summaryrefslogtreecommitdiff
path: root/authfd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /authfd.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'authfd.c')
-rw-r--r--authfd.c921
1 files changed, 444 insertions, 477 deletions
diff --git a/authfd.c b/authfd.c
index 33d09908e..17b0668be 100644
--- a/authfd.c
+++ b/authfd.c
@@ -1,20 +1,20 @@
1/* 1/*
2 2 *
3authfd.c 3 * authfd.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Wed Mar 29 01:30:28 1995 ylo 10 * Created: Wed Mar 29 01:30:28 1995 ylo
11 11 *
12Functions for connecting the local authentication agent. 12 * Functions for connecting the local authentication agent.
13 13 *
14*/ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: authfd.c,v 1.6 1999/11/18 21:25:48 damien Exp $"); 17RCSID("$Id: authfd.c,v 1.7 1999/11/24 13:26:21 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "rsa.h" 20#include "rsa.h"
@@ -36,45 +36,42 @@ RCSID("$Id: authfd.c,v 1.6 1999/11/18 21:25:48 damien Exp $");
36int 36int
37ssh_get_authentication_socket() 37ssh_get_authentication_socket()
38{ 38{
39 const char *authsocket; 39 const char *authsocket;
40 int sock; 40 int sock;
41 struct sockaddr_un sunaddr; 41 struct sockaddr_un sunaddr;
42 42
43 authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); 43 authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
44 if (!authsocket) 44 if (!authsocket)
45 return -1; 45 return -1;
46 46
47 sunaddr.sun_family = AF_UNIX; 47 sunaddr.sun_family = AF_UNIX;
48 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); 48 strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
49 49
50 sock = socket(AF_UNIX, SOCK_STREAM, 0); 50 sock = socket(AF_UNIX, SOCK_STREAM, 0);
51 if (sock < 0) 51 if (sock < 0)
52 return -1; 52 return -1;
53 53
54 /* close on exec */ 54 /* close on exec */
55 if (fcntl(sock, F_SETFD, 1) == -1) 55 if (fcntl(sock, F_SETFD, 1) == -1) {
56 { 56 close(sock);
57 close(sock); 57 return -1;
58 return -1; 58 }
59 } 59 if (connect(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
60 60 close(sock);
61 if (connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) 61 return -1;
62 { 62 }
63 close(sock); 63 return sock;
64 return -1;
65 }
66
67 return sock;
68} 64}
69 65
70/* Closes the agent socket if it should be closed (depends on how it was 66/* Closes the agent socket if it should be closed (depends on how it was
71 obtained). The argument must have been returned by 67 obtained). The argument must have been returned by
72 ssh_get_authentication_socket(). */ 68 ssh_get_authentication_socket(). */
73 69
74void ssh_close_authentication_socket(int sock) 70void
71ssh_close_authentication_socket(int sock)
75{ 72{
76 if (getenv(SSH_AUTHSOCKET_ENV_NAME)) 73 if (getenv(SSH_AUTHSOCKET_ENV_NAME))
77 close(sock); 74 close(sock);
78} 75}
79 76
80/* Opens and connects a private socket for communication with the 77/* Opens and connects a private socket for communication with the
@@ -83,38 +80,39 @@ void ssh_close_authentication_socket(int sock)
83 Returns NULL if an error occurred and the connection could not be 80 Returns NULL if an error occurred and the connection could not be
84 opened. */ 81 opened. */
85 82
86AuthenticationConnection *ssh_get_authentication_connection() 83AuthenticationConnection *
84ssh_get_authentication_connection()
87{ 85{
88 AuthenticationConnection *auth; 86 AuthenticationConnection *auth;
89 int sock; 87 int sock;
90 88
91 sock = ssh_get_authentication_socket(); 89 sock = ssh_get_authentication_socket();
92 90
93 /* Fail if we couldn't obtain a connection. This happens if we exited 91 /* Fail if we couldn't obtain a connection. This happens if we
94 due to a timeout. */ 92 exited due to a timeout. */
95 if (sock < 0) 93 if (sock < 0)
96 return NULL; 94 return NULL;
97 95
98 /* Applocate the connection structure and initialize it. */ 96 /* Applocate the connection structure and initialize it. */
99 auth = xmalloc(sizeof(*auth)); 97 auth = xmalloc(sizeof(*auth));
100 auth->fd = sock; 98 auth->fd = sock;
101 buffer_init(&auth->packet); 99 buffer_init(&auth->packet);
102 buffer_init(&auth->identities); 100 buffer_init(&auth->identities);
103 auth->howmany = 0; 101 auth->howmany = 0;
104 102
105 return auth; 103 return auth;
106} 104}
107 105
108/* Closes the connection to the authentication agent and frees any associated 106/* Closes the connection to the authentication agent and frees any associated
109 memory. */ 107 memory. */
110 108
111void ssh_close_authentication_connection(AuthenticationConnection *ac) 109void
110ssh_close_authentication_connection(AuthenticationConnection *ac)
112{ 111{
113 buffer_free(&ac->packet); 112 buffer_free(&ac->packet);
114 buffer_free(&ac->identities); 113 buffer_free(&ac->identities);
115 close(ac->fd); 114 close(ac->fd);
116 /* Free the connection data structure. */ 115 xfree(ac);
117 xfree(ac);
118} 116}
119 117
120/* Returns the first authentication identity held by the agent. 118/* Returns the first authentication identity held by the agent.
@@ -126,67 +124,62 @@ int
126ssh_get_first_identity(AuthenticationConnection *auth, 124ssh_get_first_identity(AuthenticationConnection *auth,
127 BIGNUM *e, BIGNUM *n, char **comment) 125 BIGNUM *e, BIGNUM *n, char **comment)
128{ 126{
129 unsigned char msg[8192]; 127 unsigned char msg[8192];
130 int len, l; 128 int len, l;
131 129
132 /* Send a message to the agent requesting for a list of the identities 130 /* Send a message to the agent requesting for a list of the
133 it can represent. */ 131 identities it can represent. */
134 msg[0] = 0; 132 msg[0] = 0;
135 msg[1] = 0; 133 msg[1] = 0;
136 msg[2] = 0; 134 msg[2] = 0;
137 msg[3] = 1; 135 msg[3] = 1;
138 msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES; 136 msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
139 if (write(auth->fd, msg, 5) != 5) 137 if (write(auth->fd, msg, 5) != 5) {
140 { 138 error("write auth->fd: %.100s", strerror(errno));
141 error("write auth->fd: %.100s", strerror(errno)); 139 return 0;
142 return 0; 140 }
143 } 141 /* Read the length of the response. XXX implement timeouts here. */
144 142 len = 4;
145 /* Read the length of the response. XXX implement timeouts here. */ 143 while (len > 0) {
146 len = 4; 144 l = read(auth->fd, msg + 4 - len, len);
147 while (len > 0) 145 if (l <= 0) {
148 { 146 error("read auth->fd: %.100s", strerror(errno));
149 l = read(auth->fd, msg + 4 - len, len); 147 return 0;
150 if (l <= 0) 148 }
151 { 149 len -= l;
152 error("read auth->fd: %.100s", strerror(errno)); 150 }
153 return 0; 151
152 /* Extract the length, and check it for sanity. (We cannot trust
153 authentication agents). */
154 len = GET_32BIT(msg);
155 if (len < 1 || len > 256 * 1024)
156 fatal("Authentication reply message too long: %d\n", len);
157
158 /* Read the packet itself. */
159 buffer_clear(&auth->identities);
160 while (len > 0) {
161 l = len;
162 if (l > sizeof(msg))
163 l = sizeof(msg);
164 l = read(auth->fd, msg, l);
165 if (l <= 0)
166 fatal("Incomplete authentication reply.");
167 buffer_append(&auth->identities, (char *) msg, l);
168 len -= l;
154 } 169 }
155 len -= l; 170
156 } 171 /* Get message type, and verify that we got a proper answer. */
157 172 buffer_get(&auth->identities, (char *) msg, 1);
158 /* Extract the length, and check it for sanity. (We cannot trust 173 if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER)
159 authentication agents). */ 174 fatal("Bad authentication reply message type: %d", msg[0]);
160 len = GET_32BIT(msg); 175
161 if (len < 1 || len > 256*1024) 176 /* Get the number of entries in the response and check it for sanity. */
162 fatal("Authentication reply message too long: %d\n", len); 177 auth->howmany = buffer_get_int(&auth->identities);
163 178 if (auth->howmany > 1024)
164 /* Read the packet itself. */ 179 fatal("Too many identities in authentication reply: %d\n", auth->howmany);
165 buffer_clear(&auth->identities); 180
166 while (len > 0) 181 /* Return the first entry (if any). */
167 { 182 return ssh_get_next_identity(auth, e, n, comment);
168 l = len;
169 if (l > sizeof(msg))
170 l = sizeof(msg);
171 l = read(auth->fd, msg, l);
172 if (l <= 0)
173 fatal("Incomplete authentication reply.");
174 buffer_append(&auth->identities, (char *)msg, l);
175 len -= l;
176 }
177
178 /* Get message type, and verify that we got a proper answer. */
179 buffer_get(&auth->identities, (char *)msg, 1);
180 if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER)
181 fatal("Bad authentication reply message type: %d", msg[0]);
182
183 /* Get the number of entries in the response and check it for sanity. */
184 auth->howmany = buffer_get_int(&auth->identities);
185 if (auth->howmany > 1024)
186 fatal("Too many identities in authentication reply: %d\n", auth->howmany);
187
188 /* Return the first entry (if any). */
189 return ssh_get_next_identity(auth, e, n, comment);
190} 183}
191 184
192/* Returns the next authentication identity for the agent. Other functions 185/* Returns the next authentication identity for the agent. Other functions
@@ -198,27 +191,27 @@ int
198ssh_get_next_identity(AuthenticationConnection *auth, 191ssh_get_next_identity(AuthenticationConnection *auth,
199 BIGNUM *e, BIGNUM *n, char **comment) 192 BIGNUM *e, BIGNUM *n, char **comment)
200{ 193{
201 unsigned int bits; 194 unsigned int bits;
202 195
203 /* Return failure if no more entries. */ 196 /* Return failure if no more entries. */
204 if (auth->howmany <= 0) 197 if (auth->howmany <= 0)
205 return 0; 198 return 0;
206 199
207 /* Get the next entry from the packet. These will abort with a fatal 200 /* Get the next entry from the packet. These will abort with a
208 error if the packet is too short or contains corrupt data. */ 201 fatal error if the packet is too short or contains corrupt data. */
209 bits = buffer_get_int(&auth->identities); 202 bits = buffer_get_int(&auth->identities);
210 buffer_get_bignum(&auth->identities, e); 203 buffer_get_bignum(&auth->identities, e);
211 buffer_get_bignum(&auth->identities, n); 204 buffer_get_bignum(&auth->identities, n);
212 *comment = buffer_get_string(&auth->identities, NULL); 205 *comment = buffer_get_string(&auth->identities, NULL);
213 206
214 if (bits != BN_num_bits(n)) 207 if (bits != BN_num_bits(n))
215 error("Warning: keysize mismatch: actual %d, announced %u", 208 error("Warning: keysize mismatch: actual %d, announced %u",
216 BN_num_bits(n), bits); 209 BN_num_bits(n), bits);
217 210
218 /* Decrement the number of remaining entries. */ 211 /* Decrement the number of remaining entries. */
219 auth->howmany--; 212 auth->howmany--;
220 213
221 return 1; 214 return 1;
222} 215}
223 216
224/* Generates a random challenge, sends it to the agent, and waits for response 217/* Generates a random challenge, sends it to the agent, and waits for response
@@ -229,355 +222,329 @@ ssh_get_next_identity(AuthenticationConnection *auth,
229 222
230int 223int
231ssh_decrypt_challenge(AuthenticationConnection *auth, 224ssh_decrypt_challenge(AuthenticationConnection *auth,
232 BIGNUM *e, BIGNUM *n, BIGNUM *challenge, 225 BIGNUM* e, BIGNUM *n, BIGNUM *challenge,
233 unsigned char session_id[16], 226 unsigned char session_id[16],
234 unsigned int response_type, 227 unsigned int response_type,
235 unsigned char response[16]) 228 unsigned char response[16])
236{ 229{
237 Buffer buffer; 230 Buffer buffer;
238 unsigned char buf[8192]; 231 unsigned char buf[8192];
239 int len, l, i; 232 int len, l, i;
240 233
241 /* Response type 0 is no longer supported. */ 234 /* Response type 0 is no longer supported. */
242 if (response_type == 0) 235 if (response_type == 0)
243 fatal("Compatibility with ssh protocol version 1.0 no longer supported."); 236 fatal("Compatibility with ssh protocol version 1.0 no longer supported.");
244 237
245 /* Format a message to the agent. */ 238 /* Format a message to the agent. */
246 buf[0] = SSH_AGENTC_RSA_CHALLENGE; 239 buf[0] = SSH_AGENTC_RSA_CHALLENGE;
247 buffer_init(&buffer); 240 buffer_init(&buffer);
248 buffer_append(&buffer, (char *)buf, 1); 241 buffer_append(&buffer, (char *) buf, 1);
249 buffer_put_int(&buffer, BN_num_bits(n)); 242 buffer_put_int(&buffer, BN_num_bits(n));
250 buffer_put_bignum(&buffer, e); 243 buffer_put_bignum(&buffer, e);
251 buffer_put_bignum(&buffer, n); 244 buffer_put_bignum(&buffer, n);
252 buffer_put_bignum(&buffer, challenge); 245 buffer_put_bignum(&buffer, challenge);
253 buffer_append(&buffer, (char *)session_id, 16); 246 buffer_append(&buffer, (char *) session_id, 16);
254 buffer_put_int(&buffer, response_type); 247 buffer_put_int(&buffer, response_type);
255 248
256 /* Get the length of the message, and format it in the buffer. */ 249 /* Get the length of the message, and format it in the buffer. */
257 len = buffer_len(&buffer); 250 len = buffer_len(&buffer);
258 PUT_32BIT(buf, len); 251 PUT_32BIT(buf, len);
259 252
260 /* Send the length and then the packet to the agent. */ 253 /* Send the length and then the packet to the agent. */
261 if (write(auth->fd, buf, 4) != 4 || 254 if (write(auth->fd, buf, 4) != 4 ||
262 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) != 255 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
263 buffer_len(&buffer)) 256 buffer_len(&buffer)) {
264 { 257 error("Error writing to authentication socket.");
265 error("Error writing to authentication socket."); 258error_cleanup:
266 error_cleanup: 259 buffer_free(&buffer);
267 buffer_free(&buffer); 260 return 0;
268 return 0; 261 }
269 } 262 /* Wait for response from the agent. First read the length of the
270 263 response packet. */
271 /* Wait for response from the agent. First read the length of the 264 len = 4;
272 response packet. */ 265 while (len > 0) {
273 len = 4; 266 l = read(auth->fd, buf + 4 - len, len);
274 while (len > 0) 267 if (l <= 0) {
275 { 268 error("Error reading response length from authentication socket.");
276 l = read(auth->fd, buf + 4 - len, len); 269 goto error_cleanup;
277 if (l <= 0) 270 }
278 { 271 len -= l;
279 error("Error reading response length from authentication socket."); 272 }
280 goto error_cleanup; 273
274 /* Extract the length, and check it for sanity. */
275 len = GET_32BIT(buf);
276 if (len > 256 * 1024)
277 fatal("Authentication response too long: %d", len);
278
279 /* Read the rest of the response in tothe buffer. */
280 buffer_clear(&buffer);
281 while (len > 0) {
282 l = len;
283 if (l > sizeof(buf))
284 l = sizeof(buf);
285 l = read(auth->fd, buf, l);
286 if (l <= 0) {
287 error("Error reading response from authentication socket.");
288 goto error_cleanup;
289 }
290 buffer_append(&buffer, (char *) buf, l);
291 len -= l;
281 } 292 }
282 len -= l; 293
283 } 294 /* Get the type of the packet. */
284 295 buffer_get(&buffer, (char *) buf, 1);
285 /* Extract the length, and check it for sanity. */ 296
286 len = GET_32BIT(buf); 297 /* Check for agent failure message. */
287 if (len > 256*1024) 298 if (buf[0] == SSH_AGENT_FAILURE) {
288 fatal("Authentication response too long: %d", len); 299 log("Agent admitted failure to authenticate using the key.");
289 300 goto error_cleanup;
290 /* Read the rest of the response in tothe buffer. */
291 buffer_clear(&buffer);
292 while (len > 0)
293 {
294 l = len;
295 if (l > sizeof(buf))
296 l = sizeof(buf);
297 l = read(auth->fd, buf, l);
298 if (l <= 0)
299 {
300 error("Error reading response from authentication socket.");
301 goto error_cleanup;
302 } 301 }
303 buffer_append(&buffer, (char *)buf, l); 302 /* Now it must be an authentication response packet. */
304 len -= l; 303 if (buf[0] != SSH_AGENT_RSA_RESPONSE)
305 } 304 fatal("Bad authentication response: %d", buf[0]);
306 305
307 /* Get the type of the packet. */ 306 /* Get the response from the packet. This will abort with a fatal
308 buffer_get(&buffer, (char *)buf, 1); 307 error if the packet is corrupt. */
309 308 for (i = 0; i < 16; i++)
310 /* Check for agent failure message. */ 309 response[i] = buffer_get_char(&buffer);
311 if (buf[0] == SSH_AGENT_FAILURE) 310
312 { 311 /* The buffer containing the packet is no longer needed. */
313 log("Agent admitted failure to authenticate using the key."); 312 buffer_free(&buffer);
314 goto error_cleanup; 313
315 } 314 /* Correct answer. */
316 315 return 1;
317 /* Now it must be an authentication response packet. */ 316}
318 if (buf[0] != SSH_AGENT_RSA_RESPONSE)
319 fatal("Bad authentication response: %d", buf[0]);
320
321 /* Get the response from the packet. This will abort with a fatal error
322 if the packet is corrupt. */
323 for (i = 0; i < 16; i++)
324 response[i] = buffer_get_char(&buffer);
325
326 /* The buffer containing the packet is no longer needed. */
327 buffer_free(&buffer);
328
329 /* Correct answer. */
330 return 1;
331}
332 317
333/* Adds an identity to the authentication server. This call is not meant to 318/* Adds an identity to the authentication server. This call is not meant to
334 be used by normal applications. */ 319 be used by normal applications. */
335 320
336int ssh_add_identity(AuthenticationConnection *auth, 321int
337 RSA *key, const char *comment) 322ssh_add_identity(AuthenticationConnection *auth,
323 RSA * key, const char *comment)
338{ 324{
339 Buffer buffer; 325 Buffer buffer;
340 unsigned char buf[8192]; 326 unsigned char buf[8192];
341 int len, l, type; 327 int len, l, type;
342 328
343 /* Format a message to the agent. */ 329 /* Format a message to the agent. */
344 buffer_init(&buffer); 330 buffer_init(&buffer);
345 buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY); 331 buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY);
346 buffer_put_int(&buffer, BN_num_bits(key->n)); 332 buffer_put_int(&buffer, BN_num_bits(key->n));
347 buffer_put_bignum(&buffer, key->n); 333 buffer_put_bignum(&buffer, key->n);
348 buffer_put_bignum(&buffer, key->e); 334 buffer_put_bignum(&buffer, key->e);
349 buffer_put_bignum(&buffer, key->d); 335 buffer_put_bignum(&buffer, key->d);
350 /* To keep within the protocol: p < q for ssh. in SSL p > q */ 336 /* To keep within the protocol: p < q for ssh. in SSL p > q */
351 buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */ 337 buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */
352 buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */ 338 buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */
353 buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */ 339 buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */
354 buffer_put_string(&buffer, comment, strlen(comment)); 340 buffer_put_string(&buffer, comment, strlen(comment));
355 341
356 /* Get the length of the message, and format it in the buffer. */ 342 /* Get the length of the message, and format it in the buffer. */
357 len = buffer_len(&buffer); 343 len = buffer_len(&buffer);
358 PUT_32BIT(buf, len); 344 PUT_32BIT(buf, len);
359 345
360 /* Send the length and then the packet to the agent. */ 346 /* Send the length and then the packet to the agent. */
361 if (write(auth->fd, buf, 4) != 4 || 347 if (write(auth->fd, buf, 4) != 4 ||
362 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) != 348 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
363 buffer_len(&buffer)) 349 buffer_len(&buffer)) {
364 { 350 error("Error writing to authentication socket.");
365 error("Error writing to authentication socket."); 351error_cleanup:
366 error_cleanup: 352 buffer_free(&buffer);
367 buffer_free(&buffer); 353 return 0;
368 return 0; 354 }
369 } 355 /* Wait for response from the agent. First read the length of the
370 356 response packet. */
371 /* Wait for response from the agent. First read the length of the 357 len = 4;
372 response packet. */ 358 while (len > 0) {
373 len = 4; 359 l = read(auth->fd, buf + 4 - len, len);
374 while (len > 0) 360 if (l <= 0) {
375 { 361 error("Error reading response length from authentication socket.");
376 l = read(auth->fd, buf + 4 - len, len); 362 goto error_cleanup;
377 if (l <= 0) 363 }
378 { 364 len -= l;
379 error("Error reading response length from authentication socket."); 365 }
380 goto error_cleanup; 366
367 /* Extract the length, and check it for sanity. */
368 len = GET_32BIT(buf);
369 if (len > 256 * 1024)
370 fatal("Add identity response too long: %d", len);
371
372 /* Read the rest of the response in tothe buffer. */
373 buffer_clear(&buffer);
374 while (len > 0) {
375 l = len;
376 if (l > sizeof(buf))
377 l = sizeof(buf);
378 l = read(auth->fd, buf, l);
379 if (l <= 0) {
380 error("Error reading response from authentication socket.");
381 goto error_cleanup;
382 }
383 buffer_append(&buffer, (char *) buf, l);
384 len -= l;
381 } 385 }
382 len -= l; 386
383 } 387 /* Get the type of the packet. */
384 388 type = buffer_get_char(&buffer);
385 /* Extract the length, and check it for sanity. */ 389 switch (type) {
386 len = GET_32BIT(buf); 390 case SSH_AGENT_FAILURE:
387 if (len > 256*1024) 391 buffer_free(&buffer);
388 fatal("Add identity response too long: %d", len); 392 return 0;
389 393 case SSH_AGENT_SUCCESS:
390 /* Read the rest of the response in tothe buffer. */ 394 buffer_free(&buffer);
391 buffer_clear(&buffer); 395 return 1;
392 while (len > 0) 396 default:
393 { 397 fatal("Bad response to add identity from authentication agent: %d",
394 l = len; 398 type);
395 if (l > sizeof(buf))
396 l = sizeof(buf);
397 l = read(auth->fd, buf, l);
398 if (l <= 0)
399 {
400 error("Error reading response from authentication socket.");
401 goto error_cleanup;
402 } 399 }
403 buffer_append(&buffer, (char *)buf, l); 400 /* NOTREACHED */
404 len -= l; 401 return 0;
405 } 402}
406 403
407 /* Get the type of the packet. */ 404/* Removes an identity from the authentication server. This call is not meant
408 type = buffer_get_char(&buffer);
409 switch (type)
410 {
411 case SSH_AGENT_FAILURE:
412 buffer_free(&buffer);
413 return 0;
414 case SSH_AGENT_SUCCESS:
415 buffer_free(&buffer);
416 return 1;
417 default:
418 fatal("Bad response to add identity from authentication agent: %d",
419 type);
420 }
421 /*NOTREACHED*/
422 return 0;
423}
424
425/* Removes an identity from the authentication server. This call is not meant
426 to be used by normal applications. */ 405 to be used by normal applications. */
427 406
428int ssh_remove_identity(AuthenticationConnection *auth, RSA *key) 407int
408ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
429{ 409{
430 Buffer buffer; 410 Buffer buffer;
431 unsigned char buf[8192]; 411 unsigned char buf[8192];
432 int len, l, type; 412 int len, l, type;
433 413
434 /* Format a message to the agent. */ 414 /* Format a message to the agent. */
435 buffer_init(&buffer); 415 buffer_init(&buffer);
436 buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY); 416 buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY);
437 buffer_put_int(&buffer, BN_num_bits(key->n)); 417 buffer_put_int(&buffer, BN_num_bits(key->n));
438 buffer_put_bignum(&buffer, key->e); 418 buffer_put_bignum(&buffer, key->e);
439 buffer_put_bignum(&buffer, key->n); 419 buffer_put_bignum(&buffer, key->n);
440 420
441 /* Get the length of the message, and format it in the buffer. */ 421 /* Get the length of the message, and format it in the buffer. */
442 len = buffer_len(&buffer); 422 len = buffer_len(&buffer);
443 PUT_32BIT(buf, len); 423 PUT_32BIT(buf, len);
444 424
445 /* Send the length and then the packet to the agent. */ 425 /* Send the length and then the packet to the agent. */
446 if (write(auth->fd, buf, 4) != 4 || 426 if (write(auth->fd, buf, 4) != 4 ||
447 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) != 427 write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
448 buffer_len(&buffer)) 428 buffer_len(&buffer)) {
449 { 429 error("Error writing to authentication socket.");
450 error("Error writing to authentication socket."); 430error_cleanup:
451 error_cleanup: 431 buffer_free(&buffer);
452 buffer_free(&buffer); 432 return 0;
453 return 0; 433 }
454 } 434 /* Wait for response from the agent. First read the length of the
455 435 response packet. */
456 /* Wait for response from the agent. First read the length of the 436 len = 4;
457 response packet. */ 437 while (len > 0) {
458 len = 4; 438 l = read(auth->fd, buf + 4 - len, len);
459 while (len > 0) 439 if (l <= 0) {
460 { 440 error("Error reading response length from authentication socket.");
461 l = read(auth->fd, buf + 4 - len, len); 441 goto error_cleanup;
462 if (l <= 0) 442 }
463 { 443 len -= l;
464 error("Error reading response length from authentication socket."); 444 }
465 goto error_cleanup; 445
446 /* Extract the length, and check it for sanity. */
447 len = GET_32BIT(buf);
448 if (len > 256 * 1024)
449 fatal("Remove identity response too long: %d", len);
450
451 /* Read the rest of the response in tothe buffer. */
452 buffer_clear(&buffer);
453 while (len > 0) {
454 l = len;
455 if (l > sizeof(buf))
456 l = sizeof(buf);
457 l = read(auth->fd, buf, l);
458 if (l <= 0) {
459 error("Error reading response from authentication socket.");
460 goto error_cleanup;
461 }
462 buffer_append(&buffer, (char *) buf, l);
463 len -= l;
466 } 464 }
467 len -= l; 465
468 } 466 /* Get the type of the packet. */
469 467 type = buffer_get_char(&buffer);
470 /* Extract the length, and check it for sanity. */ 468 switch (type) {
471 len = GET_32BIT(buf); 469 case SSH_AGENT_FAILURE:
472 if (len > 256*1024) 470 buffer_free(&buffer);
473 fatal("Remove identity response too long: %d", len); 471 return 0;
474 472 case SSH_AGENT_SUCCESS:
475 /* Read the rest of the response in tothe buffer. */ 473 buffer_free(&buffer);
476 buffer_clear(&buffer); 474 return 1;
477 while (len > 0) 475 default:
478 { 476 fatal("Bad response to remove identity from authentication agent: %d",
479 l = len; 477 type);
480 if (l > sizeof(buf))
481 l = sizeof(buf);
482 l = read(auth->fd, buf, l);
483 if (l <= 0)
484 {
485 error("Error reading response from authentication socket.");
486 goto error_cleanup;
487 } 478 }
488 buffer_append(&buffer, (char *)buf, l); 479 /* NOTREACHED */
489 len -= l; 480 return 0;
490 } 481}
491 482
492 /* Get the type of the packet. */ 483/* Removes all identities from the agent. This call is not meant
493 type = buffer_get_char(&buffer);
494 switch (type)
495 {
496 case SSH_AGENT_FAILURE:
497 buffer_free(&buffer);
498 return 0;
499 case SSH_AGENT_SUCCESS:
500 buffer_free(&buffer);
501 return 1;
502 default:
503 fatal("Bad response to remove identity from authentication agent: %d",
504 type);
505 }
506 /*NOTREACHED*/
507 return 0;
508}
509
510/* Removes all identities from the agent. This call is not meant
511 to be used by normal applications. */ 484 to be used by normal applications. */
512 485
513int ssh_remove_all_identities(AuthenticationConnection *auth) 486int
487ssh_remove_all_identities(AuthenticationConnection *auth)
514{ 488{
515 Buffer buffer; 489 Buffer buffer;
516 unsigned char buf[8192]; 490 unsigned char buf[8192];
517 int len, l, type; 491 int len, l, type;
518 492
519 /* Get the length of the message, and format it in the buffer. */ 493 /* Get the length of the message, and format it in the buffer. */
520 PUT_32BIT(buf, 1); 494 PUT_32BIT(buf, 1);
521 buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES; 495 buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
522 496
523 /* Send the length and then the packet to the agent. */ 497 /* Send the length and then the packet to the agent. */
524 if (write(auth->fd, buf, 5) != 5) 498 if (write(auth->fd, buf, 5) != 5) {
525 { 499 error("Error writing to authentication socket.");
526 error("Error writing to authentication socket."); 500 return 0;
527 return 0; 501 }
528 } 502 /* Wait for response from the agent. First read the length of the
529 503 response packet. */
530 /* Wait for response from the agent. First read the length of the 504 len = 4;
531 response packet. */ 505 while (len > 0) {
532 len = 4; 506 l = read(auth->fd, buf + 4 - len, len);
533 while (len > 0) 507 if (l <= 0) {
534 { 508 error("Error reading response length from authentication socket.");
535 l = read(auth->fd, buf + 4 - len, len); 509 return 0;
536 if (l <= 0) 510 }
537 { 511 len -= l;
538 error("Error reading response length from authentication socket."); 512 }
539 return 0; 513
514 /* Extract the length, and check it for sanity. */
515 len = GET_32BIT(buf);
516 if (len > 256 * 1024)
517 fatal("Remove identity response too long: %d", len);
518
519 /* Read the rest of the response into the buffer. */
520 buffer_init(&buffer);
521 while (len > 0) {
522 l = len;
523 if (l > sizeof(buf))
524 l = sizeof(buf);
525 l = read(auth->fd, buf, l);
526 if (l <= 0) {
527 error("Error reading response from authentication socket.");
528 buffer_free(&buffer);
529 return 0;
530 }
531 buffer_append(&buffer, (char *) buf, l);
532 len -= l;
540 } 533 }
541 len -= l; 534
542 } 535 /* Get the type of the packet. */
543 536 type = buffer_get_char(&buffer);
544 /* Extract the length, and check it for sanity. */ 537 switch (type) {
545 len = GET_32BIT(buf); 538 case SSH_AGENT_FAILURE:
546 if (len > 256*1024) 539 buffer_free(&buffer);
547 fatal("Remove identity response too long: %d", len); 540 return 0;
548 541 case SSH_AGENT_SUCCESS:
549 /* Read the rest of the response into the buffer. */ 542 buffer_free(&buffer);
550 buffer_init(&buffer); 543 return 1;
551 while (len > 0) 544 default:
552 { 545 fatal("Bad response to remove identity from authentication agent: %d",
553 l = len; 546 type);
554 if (l > sizeof(buf))
555 l = sizeof(buf);
556 l = read(auth->fd, buf, l);
557 if (l <= 0)
558 {
559 error("Error reading response from authentication socket.");
560 buffer_free(&buffer);
561 return 0;
562 } 547 }
563 buffer_append(&buffer, (char *)buf, l); 548 /* NOTREACHED */
564 len -= l; 549 return 0;
565 } 550}
566
567 /* Get the type of the packet. */
568 type = buffer_get_char(&buffer);
569 switch (type)
570 {
571 case SSH_AGENT_FAILURE:
572 buffer_free(&buffer);
573 return 0;
574 case SSH_AGENT_SUCCESS:
575 buffer_free(&buffer);
576 return 1;
577 default:
578 fatal("Bad response to remove identity from authentication agent: %d",
579 type);
580 }
581 /*NOTREACHED*/
582 return 0;
583}