diff options
-rw-r--r-- | ssh-agent.c | 520 |
1 files changed, 308 insertions, 212 deletions
diff --git a/ssh-agent.c b/ssh-agent.c index ae2bacca5..4925d47a3 100644 --- a/ssh-agent.c +++ b/ssh-agent.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-agent.c,v 1.193 2014/12/21 23:35:14 jmc Exp $ */ | 1 | /* $OpenBSD: ssh-agent.c,v 1.194 2015/01/14 13:09:09 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -67,16 +67,20 @@ | |||
67 | #include <string.h> | 67 | #include <string.h> |
68 | #include <unistd.h> | 68 | #include <unistd.h> |
69 | 69 | ||
70 | #include "key.h" /* XXX for typedef */ | ||
71 | #include "buffer.h" /* XXX for typedef */ | ||
72 | |||
70 | #include "xmalloc.h" | 73 | #include "xmalloc.h" |
71 | #include "ssh.h" | 74 | #include "ssh.h" |
72 | #include "rsa.h" | 75 | #include "rsa.h" |
73 | #include "buffer.h" | 76 | #include "sshbuf.h" |
74 | #include "key.h" | 77 | #include "sshkey.h" |
75 | #include "authfd.h" | 78 | #include "authfd.h" |
76 | #include "compat.h" | 79 | #include "compat.h" |
77 | #include "log.h" | 80 | #include "log.h" |
78 | #include "misc.h" | 81 | #include "misc.h" |
79 | #include "digest.h" | 82 | #include "digest.h" |
83 | #include "ssherr.h" | ||
80 | 84 | ||
81 | #ifdef ENABLE_PKCS11 | 85 | #ifdef ENABLE_PKCS11 |
82 | #include "ssh-pkcs11.h" | 86 | #include "ssh-pkcs11.h" |
@@ -95,9 +99,9 @@ typedef enum { | |||
95 | typedef struct { | 99 | typedef struct { |
96 | int fd; | 100 | int fd; |
97 | sock_type type; | 101 | sock_type type; |
98 | Buffer input; | 102 | struct sshbuf *input; |
99 | Buffer output; | 103 | struct sshbuf *output; |
100 | Buffer request; | 104 | struct sshbuf *request; |
101 | } SocketEntry; | 105 | } SocketEntry; |
102 | 106 | ||
103 | u_int sockets_alloc = 0; | 107 | u_int sockets_alloc = 0; |
@@ -105,7 +109,7 @@ SocketEntry *sockets = NULL; | |||
105 | 109 | ||
106 | typedef struct identity { | 110 | typedef struct identity { |
107 | TAILQ_ENTRY(identity) next; | 111 | TAILQ_ENTRY(identity) next; |
108 | Key *key; | 112 | struct sshkey *key; |
109 | char *comment; | 113 | char *comment; |
110 | char *provider; | 114 | char *provider; |
111 | time_t death; | 115 | time_t death; |
@@ -150,9 +154,9 @@ close_socket(SocketEntry *e) | |||
150 | close(e->fd); | 154 | close(e->fd); |
151 | e->fd = -1; | 155 | e->fd = -1; |
152 | e->type = AUTH_UNUSED; | 156 | e->type = AUTH_UNUSED; |
153 | buffer_free(&e->input); | 157 | sshbuf_free(e->input); |
154 | buffer_free(&e->output); | 158 | sshbuf_free(e->output); |
155 | buffer_free(&e->request); | 159 | sshbuf_free(e->request); |
156 | } | 160 | } |
157 | 161 | ||
158 | static void | 162 | static void |
@@ -178,7 +182,7 @@ idtab_lookup(int version) | |||
178 | static void | 182 | static void |
179 | free_identity(Identity *id) | 183 | free_identity(Identity *id) |
180 | { | 184 | { |
181 | key_free(id->key); | 185 | sshkey_free(id->key); |
182 | free(id->provider); | 186 | free(id->provider); |
183 | free(id->comment); | 187 | free(id->comment); |
184 | free(id); | 188 | free(id); |
@@ -186,13 +190,13 @@ free_identity(Identity *id) | |||
186 | 190 | ||
187 | /* return matching private key for given public key */ | 191 | /* return matching private key for given public key */ |
188 | static Identity * | 192 | static Identity * |
189 | lookup_identity(Key *key, int version) | 193 | lookup_identity(struct sshkey *key, int version) |
190 | { | 194 | { |
191 | Identity *id; | 195 | Identity *id; |
192 | 196 | ||
193 | Idtab *tab = idtab_lookup(version); | 197 | Idtab *tab = idtab_lookup(version); |
194 | TAILQ_FOREACH(id, &tab->idlist, next) { | 198 | TAILQ_FOREACH(id, &tab->idlist, next) { |
195 | if (key_equal(key, id->key)) | 199 | if (sshkey_equal(key, id->key)) |
196 | return (id); | 200 | return (id); |
197 | } | 201 | } |
198 | return (NULL); | 202 | return (NULL); |
@@ -205,7 +209,7 @@ confirm_key(Identity *id) | |||
205 | char *p; | 209 | char *p; |
206 | int ret = -1; | 210 | int ret = -1; |
207 | 211 | ||
208 | p = key_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); | 212 | p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); |
209 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", | 213 | if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", |
210 | id->comment, p)) | 214 | id->comment, p)) |
211 | ret = 0; | 215 | ret = 0; |
@@ -214,37 +218,65 @@ confirm_key(Identity *id) | |||
214 | return (ret); | 218 | return (ret); |
215 | } | 219 | } |
216 | 220 | ||
221 | static void | ||
222 | send_status(SocketEntry *e, int success) | ||
223 | { | ||
224 | int r; | ||
225 | |||
226 | if ((r = sshbuf_put_u32(e->output, 1)) != 0 || | ||
227 | (r = sshbuf_put_u8(e->output, success ? | ||
228 | SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) | ||
229 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
230 | } | ||
231 | |||
217 | /* send list of supported public keys to 'client' */ | 232 | /* send list of supported public keys to 'client' */ |
218 | static void | 233 | static void |
219 | process_request_identities(SocketEntry *e, int version) | 234 | process_request_identities(SocketEntry *e, int version) |
220 | { | 235 | { |
221 | Idtab *tab = idtab_lookup(version); | 236 | Idtab *tab = idtab_lookup(version); |
222 | Identity *id; | 237 | Identity *id; |
223 | Buffer msg; | 238 | struct sshbuf *msg; |
224 | 239 | int r; | |
225 | buffer_init(&msg); | 240 | |
226 | buffer_put_char(&msg, (version == 1) ? | 241 | if ((msg = sshbuf_new()) == NULL) |
227 | SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); | 242 | fatal("%s: sshbuf_new failed", __func__); |
228 | buffer_put_int(&msg, tab->nentries); | 243 | if ((r = sshbuf_put_u8(msg, (version == 1) ? |
244 | SSH_AGENT_RSA_IDENTITIES_ANSWER : | ||
245 | SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || | ||
246 | (r = sshbuf_put_u32(msg, tab->nentries)) != 0) | ||
247 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
229 | TAILQ_FOREACH(id, &tab->idlist, next) { | 248 | TAILQ_FOREACH(id, &tab->idlist, next) { |
230 | if (id->key->type == KEY_RSA1) { | 249 | if (id->key->type == KEY_RSA1) { |
231 | #ifdef WITH_SSH1 | 250 | #ifdef WITH_SSH1 |
232 | buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); | 251 | if ((r = sshbuf_put_u32(msg, |
233 | buffer_put_bignum(&msg, id->key->rsa->e); | 252 | BN_num_bits(id->key->rsa->n))) != 0 || |
234 | buffer_put_bignum(&msg, id->key->rsa->n); | 253 | (r = sshbuf_put_bignum1(msg, |
254 | id->key->rsa->e)) != 0 || | ||
255 | (r = sshbuf_put_bignum1(msg, | ||
256 | id->key->rsa->n)) != 0) | ||
257 | fatal("%s: buffer error: %s", | ||
258 | __func__, ssh_err(r)); | ||
235 | #endif | 259 | #endif |
236 | } else { | 260 | } else { |
237 | u_char *blob; | 261 | u_char *blob; |
238 | u_int blen; | 262 | size_t blen; |
239 | key_to_blob(id->key, &blob, &blen); | 263 | |
240 | buffer_put_string(&msg, blob, blen); | 264 | if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) { |
265 | error("%s: sshkey_to_blob: %s", __func__, | ||
266 | ssh_err(r)); | ||
267 | continue; | ||
268 | } | ||
269 | if ((r = sshbuf_put_string(msg, blob, blen)) != 0) | ||
270 | fatal("%s: buffer error: %s", | ||
271 | __func__, ssh_err(r)); | ||
241 | free(blob); | 272 | free(blob); |
242 | } | 273 | } |
243 | buffer_put_cstring(&msg, id->comment); | 274 | if ((r = sshbuf_put_cstring(msg, id->comment)) != 0) |
275 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
244 | } | 276 | } |
245 | buffer_put_int(&e->output, buffer_len(&msg)); | 277 | if ((r = sshbuf_put_stringb(e->output, msg)) != 0) |
246 | buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); | 278 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
247 | buffer_free(&msg); | 279 | sshbuf_free(msg); |
248 | } | 280 | } |
249 | 281 | ||
250 | #ifdef WITH_SSH1 | 282 | #ifdef WITH_SSH1 |
@@ -256,40 +288,48 @@ process_authentication_challenge1(SocketEntry *e) | |||
256 | u_int response_type; | 288 | u_int response_type; |
257 | BIGNUM *challenge; | 289 | BIGNUM *challenge; |
258 | Identity *id; | 290 | Identity *id; |
259 | int i, len; | 291 | int r, len; |
260 | Buffer msg; | 292 | struct sshbuf *msg; |
261 | struct ssh_digest_ctx *md; | 293 | struct ssh_digest_ctx *md; |
262 | Key *key; | 294 | struct sshkey *key; |
263 | 295 | ||
264 | buffer_init(&msg); | 296 | if ((msg = sshbuf_new()) == NULL) |
265 | key = key_new(KEY_RSA1); | 297 | fatal("%s: sshbuf_new failed", __func__); |
298 | if ((key = sshkey_new(KEY_RSA1)) == NULL) | ||
299 | fatal("%s: sshkey_new failed", __func__); | ||
266 | if ((challenge = BN_new()) == NULL) | 300 | if ((challenge = BN_new()) == NULL) |
267 | fatal("process_authentication_challenge1: BN_new failed"); | 301 | fatal("%s: BN_new failed", __func__); |
268 | 302 | ||
269 | (void) buffer_get_int(&e->request); /* ignored */ | 303 | if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ |
270 | buffer_get_bignum(&e->request, key->rsa->e); | 304 | (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || |
271 | buffer_get_bignum(&e->request, key->rsa->n); | 305 | (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || |
272 | buffer_get_bignum(&e->request, challenge); | 306 | (r = sshbuf_get_bignum1(e->request, challenge))) |
307 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
273 | 308 | ||
274 | /* Only protocol 1.1 is supported */ | 309 | /* Only protocol 1.1 is supported */ |
275 | if (buffer_len(&e->request) == 0) | 310 | if (sshbuf_len(e->request) == 0) |
276 | goto failure; | 311 | goto failure; |
277 | buffer_get(&e->request, session_id, 16); | 312 | if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 || |
278 | response_type = buffer_get_int(&e->request); | 313 | (r = sshbuf_get_u32(e->request, &response_type)) != 0) |
314 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
279 | if (response_type != 1) | 315 | if (response_type != 1) |
280 | goto failure; | 316 | goto failure; |
281 | 317 | ||
282 | id = lookup_identity(key, 1); | 318 | id = lookup_identity(key, 1); |
283 | if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { | 319 | if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { |
284 | Key *private = id->key; | 320 | struct sshkey *private = id->key; |
285 | /* Decrypt the challenge using the private key. */ | 321 | /* Decrypt the challenge using the private key. */ |
286 | if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0) | 322 | if ((r = rsa_private_decrypt(challenge, challenge, |
287 | goto failure; | 323 | private->rsa) != 0)) { |
324 | fatal("%s: rsa_public_encrypt: %s", __func__, | ||
325 | ssh_err(r)); | ||
326 | goto failure; /* XXX ? */ | ||
327 | } | ||
288 | 328 | ||
289 | /* The response is MD5 of decrypted challenge plus session id. */ | 329 | /* The response is MD5 of decrypted challenge plus session id */ |
290 | len = BN_num_bytes(challenge); | 330 | len = BN_num_bytes(challenge); |
291 | if (len <= 0 || len > 32) { | 331 | if (len <= 0 || len > 32) { |
292 | logit("process_authentication_challenge: bad challenge length %d", len); | 332 | logit("%s: bad challenge length %d", __func__, len); |
293 | goto failure; | 333 | goto failure; |
294 | } | 334 | } |
295 | memset(buf, 0, 32); | 335 | memset(buf, 0, 32); |
@@ -302,21 +342,22 @@ process_authentication_challenge1(SocketEntry *e) | |||
302 | ssh_digest_free(md); | 342 | ssh_digest_free(md); |
303 | 343 | ||
304 | /* Send the response. */ | 344 | /* Send the response. */ |
305 | buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); | 345 | if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 || |
306 | for (i = 0; i < 16; i++) | 346 | (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0) |
307 | buffer_put_char(&msg, mdbuf[i]); | 347 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
308 | goto send; | 348 | goto send; |
309 | } | 349 | } |
310 | 350 | ||
311 | failure: | 351 | failure: |
312 | /* Unknown identity or protocol error. Send failure. */ | 352 | /* Unknown identity or protocol error. Send failure. */ |
313 | buffer_put_char(&msg, SSH_AGENT_FAILURE); | 353 | if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) |
314 | send: | 354 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
315 | buffer_put_int(&e->output, buffer_len(&msg)); | 355 | send: |
316 | buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); | 356 | if ((r = sshbuf_put_stringb(e->output, msg)) != 0) |
317 | key_free(key); | 357 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
358 | sshkey_free(key); | ||
318 | BN_clear_free(challenge); | 359 | BN_clear_free(challenge); |
319 | buffer_free(&msg); | 360 | sshbuf_free(msg); |
320 | } | 361 | } |
321 | #endif | 362 | #endif |
322 | 363 | ||
@@ -325,54 +366,56 @@ static void | |||
325 | process_sign_request2(SocketEntry *e) | 366 | process_sign_request2(SocketEntry *e) |
326 | { | 367 | { |
327 | u_char *blob, *data, *signature = NULL; | 368 | u_char *blob, *data, *signature = NULL; |
328 | u_int blen, dlen, slen = 0; | 369 | size_t blen, dlen, slen = 0; |
329 | extern int datafellows; | 370 | u_int compat = 0, flags; |
330 | int odatafellows; | 371 | int r, ok = -1; |
331 | int ok = -1, flags; | 372 | struct sshbuf *msg; |
332 | Buffer msg; | 373 | struct sshkey *key; |
333 | Key *key; | 374 | |
334 | 375 | if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 || | |
335 | datafellows = 0; | 376 | (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 || |
336 | 377 | (r = sshbuf_get_u32(e->request, &flags)) != 0) | |
337 | blob = buffer_get_string(&e->request, &blen); | 378 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
338 | data = buffer_get_string(&e->request, &dlen); | ||
339 | |||
340 | flags = buffer_get_int(&e->request); | ||
341 | odatafellows = datafellows; | ||
342 | if (flags & SSH_AGENT_OLD_SIGNATURE) | 379 | if (flags & SSH_AGENT_OLD_SIGNATURE) |
343 | datafellows = SSH_BUG_SIGBLOB; | 380 | compat = SSH_BUG_SIGBLOB; |
344 | 381 | ||
345 | key = key_from_blob(blob, blen); | 382 | if ((ok = sshkey_from_blob(blob, blen, &key)) != 0) |
346 | if (key != NULL) { | 383 | error("%s: cannot parse key blob: %s", __func__, ssh_err(ok)); |
384 | else { | ||
347 | Identity *id = lookup_identity(key, 2); | 385 | Identity *id = lookup_identity(key, 2); |
348 | if (id != NULL && (!id->confirm || confirm_key(id) == 0)) | 386 | if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { |
349 | ok = key_sign(id->key, &signature, &slen, data, dlen); | 387 | if ((ok = sshkey_sign(id->key, &signature, &slen, |
350 | key_free(key); | 388 | data, dlen, compat)) != 0) |
389 | error("%s: sshkey_sign: %s", | ||
390 | __func__, ssh_err(ok)); | ||
391 | } | ||
392 | sshkey_free(key); | ||
351 | } | 393 | } |
352 | buffer_init(&msg); | 394 | if ((msg = sshbuf_new()) == NULL) |
395 | fatal("%s: sshbuf_new failed", __func__); | ||
353 | if (ok == 0) { | 396 | if (ok == 0) { |
354 | buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); | 397 | if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || |
355 | buffer_put_string(&msg, signature, slen); | 398 | (r = sshbuf_put_string(msg, signature, slen)) != 0) |
356 | } else { | 399 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
357 | buffer_put_char(&msg, SSH_AGENT_FAILURE); | 400 | } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) |
358 | } | 401 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
359 | buffer_put_int(&e->output, buffer_len(&msg)); | 402 | |
360 | buffer_append(&e->output, buffer_ptr(&msg), | 403 | if ((r = sshbuf_put_stringb(e->output, msg)) != 0) |
361 | buffer_len(&msg)); | 404 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
362 | buffer_free(&msg); | 405 | |
406 | sshbuf_free(msg); | ||
363 | free(data); | 407 | free(data); |
364 | free(blob); | 408 | free(blob); |
365 | free(signature); | 409 | free(signature); |
366 | datafellows = odatafellows; | ||
367 | } | 410 | } |
368 | 411 | ||
369 | /* shared */ | 412 | /* shared */ |
370 | static void | 413 | static void |
371 | process_remove_identity(SocketEntry *e, int version) | 414 | process_remove_identity(SocketEntry *e, int version) |
372 | { | 415 | { |
373 | u_int blen; | 416 | size_t blen; |
374 | int success = 0; | 417 | int r, success = 0; |
375 | Key *key = NULL; | 418 | struct sshkey *key = NULL; |
376 | u_char *blob; | 419 | u_char *blob; |
377 | #ifdef WITH_SSH1 | 420 | #ifdef WITH_SSH1 |
378 | u_int bits; | 421 | u_int bits; |
@@ -381,19 +424,27 @@ process_remove_identity(SocketEntry *e, int version) | |||
381 | switch (version) { | 424 | switch (version) { |
382 | #ifdef WITH_SSH1 | 425 | #ifdef WITH_SSH1 |
383 | case 1: | 426 | case 1: |
384 | key = key_new(KEY_RSA1); | 427 | if ((key = sshkey_new(KEY_RSA1)) == NULL) { |
385 | bits = buffer_get_int(&e->request); | 428 | error("%s: sshkey_new failed", __func__); |
386 | buffer_get_bignum(&e->request, key->rsa->e); | 429 | return; |
387 | buffer_get_bignum(&e->request, key->rsa->n); | 430 | } |
388 | 431 | if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || | |
389 | if (bits != key_size(key)) | 432 | (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || |
390 | logit("Warning: identity keysize mismatch: actual %u, announced %u", | 433 | (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) |
391 | key_size(key), bits); | 434 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
435 | |||
436 | if (bits != sshkey_size(key)) | ||
437 | logit("Warning: identity keysize mismatch: " | ||
438 | "actual %u, announced %u", | ||
439 | sshkey_size(key), bits); | ||
392 | break; | 440 | break; |
393 | #endif /* WITH_SSH1 */ | 441 | #endif /* WITH_SSH1 */ |
394 | case 2: | 442 | case 2: |
395 | blob = buffer_get_string(&e->request, &blen); | 443 | if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0) |
396 | key = key_from_blob(blob, blen); | 444 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
445 | if ((r = sshkey_from_blob(blob, blen, &key)) != 0) | ||
446 | error("%s: sshkey_from_blob failed: %s", | ||
447 | __func__, ssh_err(r)); | ||
397 | free(blob); | 448 | free(blob); |
398 | break; | 449 | break; |
399 | } | 450 | } |
@@ -417,11 +468,9 @@ process_remove_identity(SocketEntry *e, int version) | |||
417 | tab->nentries--; | 468 | tab->nentries--; |
418 | success = 1; | 469 | success = 1; |
419 | } | 470 | } |
420 | key_free(key); | 471 | sshkey_free(key); |
421 | } | 472 | } |
422 | buffer_put_int(&e->output, 1); | 473 | send_status(e, success); |
423 | buffer_put_char(&e->output, | ||
424 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
425 | } | 474 | } |
426 | 475 | ||
427 | static void | 476 | static void |
@@ -441,8 +490,7 @@ process_remove_all_identities(SocketEntry *e, int version) | |||
441 | tab->nentries = 0; | 490 | tab->nentries = 0; |
442 | 491 | ||
443 | /* Send success. */ | 492 | /* Send success. */ |
444 | buffer_put_int(&e->output, 1); | 493 | send_status(e, 1); |
445 | buffer_put_char(&e->output, SSH_AGENT_SUCCESS); | ||
446 | } | 494 | } |
447 | 495 | ||
448 | /* removes expired keys and returns number of seconds until the next expiry */ | 496 | /* removes expired keys and returns number of seconds until the next expiry */ |
@@ -476,71 +524,104 @@ reaper(void) | |||
476 | return (deadline - now); | 524 | return (deadline - now); |
477 | } | 525 | } |
478 | 526 | ||
527 | /* | ||
528 | * XXX this and the corresponding serialisation function probably belongs | ||
529 | * in key.c | ||
530 | */ | ||
531 | static int | ||
532 | agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp) | ||
533 | { | ||
534 | struct sshkey *k = NULL; | ||
535 | int r = SSH_ERR_INTERNAL_ERROR; | ||
536 | |||
537 | *kp = NULL; | ||
538 | if ((k = sshkey_new_private(KEY_RSA1)) == NULL) | ||
539 | return SSH_ERR_ALLOC_FAIL; | ||
540 | |||
541 | if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ | ||
542 | (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || | ||
543 | (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || | ||
544 | (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || | ||
545 | (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || | ||
546 | /* SSH1 and SSL have p and q swapped */ | ||
547 | (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ | ||
548 | (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ | ||
549 | goto out; | ||
550 | |||
551 | /* Generate additional parameters */ | ||
552 | if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) | ||
553 | goto out; | ||
554 | /* enable blinding */ | ||
555 | if (RSA_blinding_on(k->rsa, NULL) != 1) { | ||
556 | r = SSH_ERR_LIBCRYPTO_ERROR; | ||
557 | goto out; | ||
558 | } | ||
559 | |||
560 | r = 0; /* success */ | ||
561 | out: | ||
562 | if (r == 0) | ||
563 | *kp = k; | ||
564 | else | ||
565 | sshkey_free(k); | ||
566 | return r; | ||
567 | } | ||
568 | |||
479 | static void | 569 | static void |
480 | process_add_identity(SocketEntry *e, int version) | 570 | process_add_identity(SocketEntry *e, int version) |
481 | { | 571 | { |
482 | Idtab *tab = idtab_lookup(version); | 572 | Idtab *tab = idtab_lookup(version); |
483 | Identity *id; | 573 | Identity *id; |
484 | int type, success = 0, confirm = 0; | 574 | int success = 0, confirm = 0; |
485 | char *comment; | 575 | u_int seconds; |
576 | char *comment = NULL; | ||
486 | time_t death = 0; | 577 | time_t death = 0; |
487 | Key *k = NULL; | 578 | struct sshkey *k = NULL; |
579 | u_char ctype; | ||
580 | int r = SSH_ERR_INTERNAL_ERROR; | ||
488 | 581 | ||
489 | switch (version) { | 582 | switch (version) { |
490 | #ifdef WITH_SSH1 | 583 | #ifdef WITH_SSH1 |
491 | case 1: | 584 | case 1: |
492 | k = key_new_private(KEY_RSA1); | 585 | r = agent_decode_rsa1(e->request, &k); |
493 | (void) buffer_get_int(&e->request); /* ignored */ | ||
494 | buffer_get_bignum(&e->request, k->rsa->n); | ||
495 | buffer_get_bignum(&e->request, k->rsa->e); | ||
496 | buffer_get_bignum(&e->request, k->rsa->d); | ||
497 | buffer_get_bignum(&e->request, k->rsa->iqmp); | ||
498 | |||
499 | /* SSH and SSL have p and q swapped */ | ||
500 | buffer_get_bignum(&e->request, k->rsa->q); /* p */ | ||
501 | buffer_get_bignum(&e->request, k->rsa->p); /* q */ | ||
502 | |||
503 | /* Generate additional parameters */ | ||
504 | if (rsa_generate_additional_parameters(k->rsa) != 0) | ||
505 | fatal("%s: rsa_generate_additional_parameters " | ||
506 | "error", __func__); | ||
507 | |||
508 | /* enable blinding */ | ||
509 | if (RSA_blinding_on(k->rsa, NULL) != 1) { | ||
510 | error("process_add_identity: RSA_blinding_on failed"); | ||
511 | key_free(k); | ||
512 | goto send; | ||
513 | } | ||
514 | break; | 586 | break; |
515 | #endif /* WITH_SSH1 */ | 587 | #endif /* WITH_SSH1 */ |
516 | case 2: | 588 | case 2: |
517 | k = key_private_deserialize(&e->request); | 589 | r = sshkey_private_deserialize(e->request, &k); |
518 | if (k == NULL) { | ||
519 | buffer_clear(&e->request); | ||
520 | goto send; | ||
521 | } | ||
522 | break; | 590 | break; |
523 | } | 591 | } |
524 | if (k == NULL) | 592 | if (r != 0 || k == NULL || |
525 | goto send; | 593 | (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { |
526 | comment = buffer_get_string(&e->request, NULL); | 594 | error("%s: decode private key: %s", __func__, ssh_err(r)); |
595 | goto err; | ||
596 | } | ||
527 | 597 | ||
528 | while (buffer_len(&e->request)) { | 598 | while (sshbuf_len(e->request)) { |
529 | switch ((type = buffer_get_char(&e->request))) { | 599 | if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { |
600 | error("%s: buffer error: %s", __func__, ssh_err(r)); | ||
601 | goto err; | ||
602 | } | ||
603 | switch (ctype) { | ||
530 | case SSH_AGENT_CONSTRAIN_LIFETIME: | 604 | case SSH_AGENT_CONSTRAIN_LIFETIME: |
531 | death = monotime() + buffer_get_int(&e->request); | 605 | if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) { |
606 | error("%s: bad lifetime constraint: %s", | ||
607 | __func__, ssh_err(r)); | ||
608 | goto err; | ||
609 | } | ||
610 | death = monotime() + seconds; | ||
532 | break; | 611 | break; |
533 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 612 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
534 | confirm = 1; | 613 | confirm = 1; |
535 | break; | 614 | break; |
536 | default: | 615 | default: |
537 | error("process_add_identity: " | 616 | error("%s: Unknown constraint %d", __func__, ctype); |
538 | "Unknown constraint type %d", type); | 617 | err: |
618 | sshbuf_reset(e->request); | ||
539 | free(comment); | 619 | free(comment); |
540 | key_free(k); | 620 | sshkey_free(k); |
541 | goto send; | 621 | goto send; |
542 | } | 622 | } |
543 | } | 623 | } |
624 | |||
544 | success = 1; | 625 | success = 1; |
545 | if (lifetime && !death) | 626 | if (lifetime && !death) |
546 | death = monotime() + lifetime; | 627 | death = monotime() + lifetime; |
@@ -551,26 +632,25 @@ process_add_identity(SocketEntry *e, int version) | |||
551 | /* Increment the number of identities. */ | 632 | /* Increment the number of identities. */ |
552 | tab->nentries++; | 633 | tab->nentries++; |
553 | } else { | 634 | } else { |
554 | key_free(k); | 635 | sshkey_free(k); |
555 | free(id->comment); | 636 | free(id->comment); |
556 | } | 637 | } |
557 | id->comment = comment; | 638 | id->comment = comment; |
558 | id->death = death; | 639 | id->death = death; |
559 | id->confirm = confirm; | 640 | id->confirm = confirm; |
560 | send: | 641 | send: |
561 | buffer_put_int(&e->output, 1); | 642 | send_status(e, success); |
562 | buffer_put_char(&e->output, | ||
563 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
564 | } | 643 | } |
565 | 644 | ||
566 | /* XXX todo: encrypt sensitive data with passphrase */ | 645 | /* XXX todo: encrypt sensitive data with passphrase */ |
567 | static void | 646 | static void |
568 | process_lock_agent(SocketEntry *e, int lock) | 647 | process_lock_agent(SocketEntry *e, int lock) |
569 | { | 648 | { |
570 | int success = 0; | 649 | int r, success = 0; |
571 | char *passwd; | 650 | char *passwd; |
572 | 651 | ||
573 | passwd = buffer_get_string(&e->request, NULL); | 652 | if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0) |
653 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
574 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { | 654 | if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { |
575 | locked = 0; | 655 | locked = 0; |
576 | explicit_bzero(lock_passwd, strlen(lock_passwd)); | 656 | explicit_bzero(lock_passwd, strlen(lock_passwd)); |
@@ -584,25 +664,25 @@ process_lock_agent(SocketEntry *e, int lock) | |||
584 | } | 664 | } |
585 | explicit_bzero(passwd, strlen(passwd)); | 665 | explicit_bzero(passwd, strlen(passwd)); |
586 | free(passwd); | 666 | free(passwd); |
587 | 667 | send_status(e, success); | |
588 | buffer_put_int(&e->output, 1); | ||
589 | buffer_put_char(&e->output, | ||
590 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
591 | } | 668 | } |
592 | 669 | ||
593 | static void | 670 | static void |
594 | no_identities(SocketEntry *e, u_int type) | 671 | no_identities(SocketEntry *e, u_int type) |
595 | { | 672 | { |
596 | Buffer msg; | 673 | struct sshbuf *msg; |
674 | int r; | ||
597 | 675 | ||
598 | buffer_init(&msg); | 676 | if ((msg = sshbuf_new()) == NULL) |
599 | buffer_put_char(&msg, | 677 | fatal("%s: sshbuf_new failed", __func__); |
678 | if ((r = sshbuf_put_u8(msg, | ||
600 | (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? | 679 | (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? |
601 | SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); | 680 | SSH_AGENT_RSA_IDENTITIES_ANSWER : |
602 | buffer_put_int(&msg, 0); | 681 | SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || |
603 | buffer_put_int(&e->output, buffer_len(&msg)); | 682 | (r = sshbuf_put_u32(msg, 0)) != 0 || |
604 | buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); | 683 | (r = sshbuf_put_stringb(e->output, msg)) != 0) |
605 | buffer_free(&msg); | 684 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
685 | sshbuf_free(msg); | ||
606 | } | 686 | } |
607 | 687 | ||
608 | #ifdef ENABLE_PKCS11 | 688 | #ifdef ENABLE_PKCS11 |
@@ -610,19 +690,27 @@ static void | |||
610 | process_add_smartcard_key(SocketEntry *e) | 690 | process_add_smartcard_key(SocketEntry *e) |
611 | { | 691 | { |
612 | char *provider = NULL, *pin; | 692 | char *provider = NULL, *pin; |
613 | int i, type, version, count = 0, success = 0, confirm = 0; | 693 | int r, i, version, count = 0, success = 0, confirm = 0; |
694 | u_int seconds; | ||
614 | time_t death = 0; | 695 | time_t death = 0; |
615 | Key **keys = NULL, *k; | 696 | u_char type; |
697 | struct sshkey **keys = NULL, *k; | ||
616 | Identity *id; | 698 | Identity *id; |
617 | Idtab *tab; | 699 | Idtab *tab; |
618 | 700 | ||
619 | provider = buffer_get_string(&e->request, NULL); | 701 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
620 | pin = buffer_get_string(&e->request, NULL); | 702 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) |
703 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
621 | 704 | ||
622 | while (buffer_len(&e->request)) { | 705 | while (sshbuf_len(e->request)) { |
623 | switch ((type = buffer_get_char(&e->request))) { | 706 | if ((r = sshbuf_get_u8(e->request, &type)) != 0) |
707 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
708 | switch (type) { | ||
624 | case SSH_AGENT_CONSTRAIN_LIFETIME: | 709 | case SSH_AGENT_CONSTRAIN_LIFETIME: |
625 | death = monotime() + buffer_get_int(&e->request); | 710 | if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) |
711 | fatal("%s: buffer error: %s", | ||
712 | __func__, ssh_err(r)); | ||
713 | death = monotime() + seconds; | ||
626 | break; | 714 | break; |
627 | case SSH_AGENT_CONSTRAIN_CONFIRM: | 715 | case SSH_AGENT_CONSTRAIN_CONFIRM: |
628 | confirm = 1; | 716 | confirm = 1; |
@@ -652,7 +740,7 @@ process_add_smartcard_key(SocketEntry *e) | |||
652 | tab->nentries++; | 740 | tab->nentries++; |
653 | success = 1; | 741 | success = 1; |
654 | } else { | 742 | } else { |
655 | key_free(k); | 743 | sshkey_free(k); |
656 | } | 744 | } |
657 | keys[i] = NULL; | 745 | keys[i] = NULL; |
658 | } | 746 | } |
@@ -660,21 +748,20 @@ send: | |||
660 | free(pin); | 748 | free(pin); |
661 | free(provider); | 749 | free(provider); |
662 | free(keys); | 750 | free(keys); |
663 | buffer_put_int(&e->output, 1); | 751 | send_status(e, success); |
664 | buffer_put_char(&e->output, | ||
665 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
666 | } | 752 | } |
667 | 753 | ||
668 | static void | 754 | static void |
669 | process_remove_smartcard_key(SocketEntry *e) | 755 | process_remove_smartcard_key(SocketEntry *e) |
670 | { | 756 | { |
671 | char *provider = NULL, *pin = NULL; | 757 | char *provider = NULL, *pin = NULL; |
672 | int version, success = 0; | 758 | int r, version, success = 0; |
673 | Identity *id, *nxt; | 759 | Identity *id, *nxt; |
674 | Idtab *tab; | 760 | Idtab *tab; |
675 | 761 | ||
676 | provider = buffer_get_string(&e->request, NULL); | 762 | if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || |
677 | pin = buffer_get_string(&e->request, NULL); | 763 | (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) |
764 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
678 | free(pin); | 765 | free(pin); |
679 | 766 | ||
680 | for (version = 1; version < 3; version++) { | 767 | for (version = 1; version < 3; version++) { |
@@ -697,9 +784,7 @@ process_remove_smartcard_key(SocketEntry *e) | |||
697 | error("process_remove_smartcard_key:" | 784 | error("process_remove_smartcard_key:" |
698 | " pkcs11_del_provider failed"); | 785 | " pkcs11_del_provider failed"); |
699 | free(provider); | 786 | free(provider); |
700 | buffer_put_int(&e->output, 1); | 787 | send_status(e, success); |
701 | buffer_put_char(&e->output, | ||
702 | success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); | ||
703 | } | 788 | } |
704 | #endif /* ENABLE_PKCS11 */ | 789 | #endif /* ENABLE_PKCS11 */ |
705 | 790 | ||
@@ -708,30 +793,31 @@ process_remove_smartcard_key(SocketEntry *e) | |||
708 | static void | 793 | static void |
709 | process_message(SocketEntry *e) | 794 | process_message(SocketEntry *e) |
710 | { | 795 | { |
711 | u_int msg_len, type; | 796 | u_int msg_len; |
712 | u_char *cp; | 797 | u_char type; |
798 | const u_char *cp; | ||
799 | int r; | ||
713 | 800 | ||
714 | if (buffer_len(&e->input) < 5) | 801 | if (sshbuf_len(e->input) < 5) |
715 | return; /* Incomplete message. */ | 802 | return; /* Incomplete message. */ |
716 | cp = buffer_ptr(&e->input); | 803 | cp = sshbuf_ptr(e->input); |
717 | msg_len = get_u32(cp); | 804 | msg_len = PEEK_U32(cp); |
718 | if (msg_len > 256 * 1024) { | 805 | if (msg_len > 256 * 1024) { |
719 | close_socket(e); | 806 | close_socket(e); |
720 | return; | 807 | return; |
721 | } | 808 | } |
722 | if (buffer_len(&e->input) < msg_len + 4) | 809 | if (sshbuf_len(e->input) < msg_len + 4) |
723 | return; | 810 | return; |
724 | 811 | ||
725 | /* move the current input to e->request */ | 812 | /* move the current input to e->request */ |
726 | buffer_consume(&e->input, 4); | 813 | sshbuf_reset(e->request); |
727 | buffer_clear(&e->request); | 814 | if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || |
728 | buffer_append(&e->request, buffer_ptr(&e->input), msg_len); | 815 | (r = sshbuf_get_u8(e->request, &type)) != 0) |
729 | buffer_consume(&e->input, msg_len); | 816 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
730 | type = buffer_get_char(&e->request); | ||
731 | 817 | ||
732 | /* check wheter agent is locked */ | 818 | /* check wheter agent is locked */ |
733 | if (locked && type != SSH_AGENTC_UNLOCK) { | 819 | if (locked && type != SSH_AGENTC_UNLOCK) { |
734 | buffer_clear(&e->request); | 820 | sshbuf_reset(e->request); |
735 | switch (type) { | 821 | switch (type) { |
736 | case SSH_AGENTC_REQUEST_RSA_IDENTITIES: | 822 | case SSH_AGENTC_REQUEST_RSA_IDENTITIES: |
737 | case SSH2_AGENTC_REQUEST_IDENTITIES: | 823 | case SSH2_AGENTC_REQUEST_IDENTITIES: |
@@ -740,8 +826,7 @@ process_message(SocketEntry *e) | |||
740 | break; | 826 | break; |
741 | default: | 827 | default: |
742 | /* send a fail message for all other request types */ | 828 | /* send a fail message for all other request types */ |
743 | buffer_put_int(&e->output, 1); | 829 | send_status(e, 0); |
744 | buffer_put_char(&e->output, SSH_AGENT_FAILURE); | ||
745 | } | 830 | } |
746 | return; | 831 | return; |
747 | } | 832 | } |
@@ -800,9 +885,8 @@ process_message(SocketEntry *e) | |||
800 | default: | 885 | default: |
801 | /* Unknown message. Respond with failure. */ | 886 | /* Unknown message. Respond with failure. */ |
802 | error("Unknown message %d", type); | 887 | error("Unknown message %d", type); |
803 | buffer_clear(&e->request); | 888 | sshbuf_reset(e->request); |
804 | buffer_put_int(&e->output, 1); | 889 | send_status(e, 0); |
805 | buffer_put_char(&e->output, SSH_AGENT_FAILURE); | ||
806 | break; | 890 | break; |
807 | } | 891 | } |
808 | } | 892 | } |
@@ -820,9 +904,12 @@ new_socket(sock_type type, int fd) | |||
820 | for (i = 0; i < sockets_alloc; i++) | 904 | for (i = 0; i < sockets_alloc; i++) |
821 | if (sockets[i].type == AUTH_UNUSED) { | 905 | if (sockets[i].type == AUTH_UNUSED) { |
822 | sockets[i].fd = fd; | 906 | sockets[i].fd = fd; |
823 | buffer_init(&sockets[i].input); | 907 | if ((sockets[i].input = sshbuf_new()) == NULL) |
824 | buffer_init(&sockets[i].output); | 908 | fatal("%s: sshbuf_new failed", __func__); |
825 | buffer_init(&sockets[i].request); | 909 | if ((sockets[i].output = sshbuf_new()) == NULL) |
910 | fatal("%s: sshbuf_new failed", __func__); | ||
911 | if ((sockets[i].request = sshbuf_new()) == NULL) | ||
912 | fatal("%s: sshbuf_new failed", __func__); | ||
826 | sockets[i].type = type; | 913 | sockets[i].type = type; |
827 | return; | 914 | return; |
828 | } | 915 | } |
@@ -833,9 +920,12 @@ new_socket(sock_type type, int fd) | |||
833 | sockets[i].type = AUTH_UNUSED; | 920 | sockets[i].type = AUTH_UNUSED; |
834 | sockets_alloc = new_alloc; | 921 | sockets_alloc = new_alloc; |
835 | sockets[old_alloc].fd = fd; | 922 | sockets[old_alloc].fd = fd; |
836 | buffer_init(&sockets[old_alloc].input); | 923 | if ((sockets[old_alloc].input = sshbuf_new()) == NULL) |
837 | buffer_init(&sockets[old_alloc].output); | 924 | fatal("%s: sshbuf_new failed", __func__); |
838 | buffer_init(&sockets[old_alloc].request); | 925 | if ((sockets[old_alloc].output = sshbuf_new()) == NULL) |
926 | fatal("%s: sshbuf_new failed", __func__); | ||
927 | if ((sockets[old_alloc].request = sshbuf_new()) == NULL) | ||
928 | fatal("%s: sshbuf_new failed", __func__); | ||
839 | sockets[old_alloc].type = type; | 929 | sockets[old_alloc].type = type; |
840 | } | 930 | } |
841 | 931 | ||
@@ -881,7 +971,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, | |||
881 | case AUTH_SOCKET: | 971 | case AUTH_SOCKET: |
882 | case AUTH_CONNECTION: | 972 | case AUTH_CONNECTION: |
883 | FD_SET(sockets[i].fd, *fdrp); | 973 | FD_SET(sockets[i].fd, *fdrp); |
884 | if (buffer_len(&sockets[i].output) > 0) | 974 | if (sshbuf_len(sockets[i].output) > 0) |
885 | FD_SET(sockets[i].fd, *fdwp); | 975 | FD_SET(sockets[i].fd, *fdwp); |
886 | break; | 976 | break; |
887 | default: | 977 | default: |
@@ -908,7 +998,7 @@ after_select(fd_set *readset, fd_set *writeset) | |||
908 | struct sockaddr_un sunaddr; | 998 | struct sockaddr_un sunaddr; |
909 | socklen_t slen; | 999 | socklen_t slen; |
910 | char buf[1024]; | 1000 | char buf[1024]; |
911 | int len, sock; | 1001 | int len, sock, r; |
912 | u_int i, orig_alloc; | 1002 | u_int i, orig_alloc; |
913 | uid_t euid; | 1003 | uid_t euid; |
914 | gid_t egid; | 1004 | gid_t egid; |
@@ -944,11 +1034,11 @@ after_select(fd_set *readset, fd_set *writeset) | |||
944 | } | 1034 | } |
945 | break; | 1035 | break; |
946 | case AUTH_CONNECTION: | 1036 | case AUTH_CONNECTION: |
947 | if (buffer_len(&sockets[i].output) > 0 && | 1037 | if (sshbuf_len(sockets[i].output) > 0 && |
948 | FD_ISSET(sockets[i].fd, writeset)) { | 1038 | FD_ISSET(sockets[i].fd, writeset)) { |
949 | len = write(sockets[i].fd, | 1039 | len = write(sockets[i].fd, |
950 | buffer_ptr(&sockets[i].output), | 1040 | sshbuf_ptr(sockets[i].output), |
951 | buffer_len(&sockets[i].output)); | 1041 | sshbuf_len(sockets[i].output)); |
952 | if (len == -1 && (errno == EAGAIN || | 1042 | if (len == -1 && (errno == EAGAIN || |
953 | errno == EWOULDBLOCK || | 1043 | errno == EWOULDBLOCK || |
954 | errno == EINTR)) | 1044 | errno == EINTR)) |
@@ -957,7 +1047,10 @@ after_select(fd_set *readset, fd_set *writeset) | |||
957 | close_socket(&sockets[i]); | 1047 | close_socket(&sockets[i]); |
958 | break; | 1048 | break; |
959 | } | 1049 | } |
960 | buffer_consume(&sockets[i].output, len); | 1050 | if ((r = sshbuf_consume(sockets[i].output, |
1051 | len)) != 0) | ||
1052 | fatal("%s: buffer error: %s", | ||
1053 | __func__, ssh_err(r)); | ||
961 | } | 1054 | } |
962 | if (FD_ISSET(sockets[i].fd, readset)) { | 1055 | if (FD_ISSET(sockets[i].fd, readset)) { |
963 | len = read(sockets[i].fd, buf, sizeof(buf)); | 1056 | len = read(sockets[i].fd, buf, sizeof(buf)); |
@@ -969,7 +1062,10 @@ after_select(fd_set *readset, fd_set *writeset) | |||
969 | close_socket(&sockets[i]); | 1062 | close_socket(&sockets[i]); |
970 | break; | 1063 | break; |
971 | } | 1064 | } |
972 | buffer_append(&sockets[i].input, buf, len); | 1065 | if ((r = sshbuf_put(sockets[i].input, |
1066 | buf, len)) != 0) | ||
1067 | fatal("%s: buffer error: %s", | ||
1068 | __func__, ssh_err(r)); | ||
973 | explicit_bzero(buf, sizeof(buf)); | 1069 | explicit_bzero(buf, sizeof(buf)); |
974 | process_message(&sockets[i]); | 1070 | process_message(&sockets[i]); |
975 | } | 1071 | } |