[BACK]Return to authfd.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/authfd.c, Revision 1.6

1.1       deraadt     1: /*
                      2:
                      3: authfd.c
                      4:
                      5: Author: Tatu Ylonen <ylo@cs.hut.fi>
                      6:
                      7: Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      8:                    All rights reserved
                      9:
                     10: Created: Wed Mar 29 01:30:28 1995 ylo
                     11:
                     12: Functions for connecting the local authentication agent.
                     13:
                     14: */
                     15:
                     16: #include "includes.h"
1.6     ! markus     17: RCSID("$Id: authfd.c,v 1.5 1999/10/03 19:22:38 deraadt Exp $");
1.1       deraadt    18:
                     19: #include "ssh.h"
                     20: #include "rsa.h"
                     21: #include "authfd.h"
                     22: #include "buffer.h"
                     23: #include "bufaux.h"
                     24: #include "xmalloc.h"
                     25: #include "getput.h"
                     26:
1.2       provos     27: #include <ssl/rsa.h>
                     28:
1.1       deraadt    29: /* Returns the number of the authentication fd, or -1 if there is none. */
                     30:
1.2       provos     31: int
                     32: ssh_get_authentication_fd()
1.1       deraadt    33: {
                     34:   const char *authfd, *authsocket;
                     35:   int sock;
                     36:   struct sockaddr_un sunaddr;
                     37:
                     38:   authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
                     39:   if (!authsocket)
                     40:     return -1;
                     41:
                     42:   sunaddr.sun_family = AF_UNIX;
1.3       deraadt    43:   strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
1.1       deraadt    44:
                     45:   sock = socket(AF_UNIX, SOCK_STREAM, 0);
                     46:   if (sock < 0)
                     47:     return -1;
                     48:
1.4       deraadt    49:   if (connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
1.1       deraadt    50:     {
                     51:       close(sock);
                     52:       return -1;
                     53:     }
                     54:
                     55:   return sock;
                     56: }
                     57:
                     58: /* Closes the agent socket if it should be closed (depends on how it was
                     59:    obtained).  The argument must have been returned by
                     60:    ssh_get_authentication_fd(). */
                     61:
                     62: void ssh_close_authentication_socket(int sock)
                     63: {
                     64:   if (getenv(SSH_AUTHSOCKET_ENV_NAME))
                     65:     close(sock);
                     66: }
                     67:
                     68: /* Dummy alarm used to prevent waiting for connection from the
                     69:    authentication agent indefinitely. */
                     70:
1.4       deraadt    71: static void dummy_alarm_handler(int sig)
1.1       deraadt    72: {
                     73:   /* Do nothing; a cought signal will just cause accept to return. */
                     74: }
                     75:
                     76: /* Opens a socket to the authentication server.  Returns the number of
                     77:    that socket, or -1 if no connection could be made. */
                     78:
                     79: int ssh_get_authentication_connection_fd()
                     80: {
                     81:   int authfd;
                     82:   int listen_sock, sock, port, addrlen;
                     83:   int old_timeout;
1.4       deraadt    84:   void (*old_handler)();
1.1       deraadt    85:   struct sockaddr_in sin;
                     86:   char msg[3];
                     87:
                     88:   /* Get the the socket number from the environment.  This is the socket
                     89:      used to obtain the real authentication socket. */
                     90:   authfd = ssh_get_authentication_fd();
                     91:   if (authfd == -1)
                     92:     return -1;
                     93:
                     94:   /* Create a local socket for listening. */
                     95:   listen_sock = socket(AF_INET, SOCK_STREAM, 0);
                     96:   if (listen_sock == -1)
                     97:     {
                     98:       ssh_close_authentication_socket(authfd);
                     99:       return -1;
                    100:     }
                    101:
                    102:   /* Bind the socket to random unprivileged port. */
                    103:   memset(&sin, 0, sizeof(sin));
                    104:   sin.sin_family = AF_INET;
                    105:   do
                    106:     {
                    107:       port = 32768 + (rand() % 30000);
                    108:       sin.sin_port = htons(port);
                    109:     }
                    110:   while (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0 &&
                    111:         errno == EADDRINUSE);
                    112:
                    113:   /* Start listening for connections on the socket. */
                    114:   if (listen(listen_sock, 1) < 0)
                    115:     {
                    116:       error("listen: %.100s", strerror(errno));
                    117:       close(listen_sock);
                    118:       ssh_close_authentication_socket(authfd);
                    119:       return -1;
                    120:     }
                    121:
                    122:   /* Send a message to the authentication fd requesting the agent or its
                    123:      local representative to connect to the given socket.  Note that
                    124:      we use send() to get the packet sent atomically (there can be several
                    125:      clients trying to use the same authentication fd simultaneously). */
                    126:   msg[0] = (char)SSH_AUTHFD_CONNECT;
                    127:   PUT_16BIT(msg + 1, port);
                    128:   if (send(authfd, msg, 3, 0) < 0)
                    129:     {
1.5       deraadt   130:       shutdown(listen_sock, SHUT_RDWR);
1.1       deraadt   131:       close(listen_sock);
                    132:       ssh_close_authentication_socket(authfd);
                    133:       return -1;
                    134:     }
                    135:
                    136:   /* Setup a timeout so we won't wait for the connection indefinitely. */
                    137:   old_timeout = alarm(120);
                    138:   old_handler = signal(SIGALRM, dummy_alarm_handler);
                    139:
                    140:   /* Wait for the connection from the agent or its representative. */
                    141:   addrlen = sizeof(sin);
                    142:   sock = accept(listen_sock, (struct sockaddr *)&sin, &addrlen);
                    143:
                    144:   /* Remove the alarm (restore its old values). */
                    145:   alarm(old_timeout);
                    146:   signal(SIGALRM, old_handler);
                    147:
                    148:   /* Close the socket we used for listening.  It is no longer needed.
                    149:      (The authentication fd and the new connection still remain open.) */
1.5       deraadt   150:   shutdown(listen_sock, SHUT_RDWR);
1.1       deraadt   151:   close(listen_sock);
                    152:   ssh_close_authentication_socket(authfd);
                    153:
                    154:   return sock;
                    155: }
                    156:
                    157: /* Opens and connects a private socket for communication with the
                    158:    authentication agent.  Returns the file descriptor (which must be
                    159:    shut down and closed by the caller when no longer needed).
                    160:    Returns NULL if an error occurred and the connection could not be
                    161:    opened. */
                    162:
                    163: AuthenticationConnection *ssh_get_authentication_connection()
                    164: {
                    165:   AuthenticationConnection *auth;
                    166:   int sock;
                    167:
                    168:   /* Get a connection to the authentication agent. */
                    169:   sock = ssh_get_authentication_connection_fd();
                    170:
                    171:   /* Fail if we couldn't obtain a connection.  This happens if we exited
                    172:      due to a timeout. */
                    173:   if (sock < 0)
                    174:     return NULL;
                    175:
                    176:   /* Applocate the connection structure and initialize it. */
                    177:   auth = xmalloc(sizeof(*auth));
                    178:   auth->fd = sock;
                    179:   buffer_init(&auth->packet);
                    180:   buffer_init(&auth->identities);
                    181:   auth->howmany = 0;
                    182:
                    183:   return auth;
                    184: }
                    185:
                    186: /* Closes the connection to the authentication agent and frees any associated
                    187:    memory. */
                    188:
                    189: void ssh_close_authentication_connection(AuthenticationConnection *ac)
                    190: {
                    191:   buffer_free(&ac->packet);
                    192:   buffer_free(&ac->identities);
                    193:   close(ac->fd);
                    194: }
                    195:
                    196: /* Returns the first authentication identity held by the agent.
                    197:    Returns true if an identity is available, 0 otherwise.
                    198:    The caller must initialize the integers before the call, and free the
                    199:    comment after a successful call (before calling ssh_get_next_identity). */
                    200:
1.2       provos    201: int
                    202: ssh_get_first_identity(AuthenticationConnection *auth,
                    203:                       int *bitsp, BIGNUM *e, BIGNUM *n, char **comment)
1.1       deraadt   204: {
                    205:   unsigned char msg[8192];
                    206:   int len, l;
                    207:
                    208:   /* Send a message to the agent requesting for a list of the identities
                    209:      it can represent. */
                    210:   msg[0] = 0;
                    211:   msg[1] = 0;
                    212:   msg[2] = 0;
                    213:   msg[3] = 1;
                    214:   msg[4] = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
                    215:   if (write(auth->fd, msg, 5) != 5)
                    216:     {
                    217:       error("write auth->fd: %.100s", strerror(errno));
                    218:       return 0;
                    219:     }
                    220:
                    221:   /* Read the length of the response.  XXX implement timeouts here. */
                    222:   len = 4;
                    223:   while (len > 0)
                    224:     {
                    225:       l = read(auth->fd, msg + 4 - len, len);
                    226:       if (l <= 0)
                    227:        {
                    228:          error("read auth->fd: %.100s", strerror(errno));
                    229:          return 0;
                    230:        }
                    231:       len -= l;
                    232:     }
                    233:
                    234:   /* Extract the length, and check it for sanity.  (We cannot trust
                    235:      authentication agents). */
                    236:   len = GET_32BIT(msg);
                    237:   if (len < 1 || len > 256*1024)
                    238:     fatal("Authentication reply message too long: %d\n", len);
                    239:
                    240:   /* Read the packet itself. */
                    241:   buffer_clear(&auth->identities);
                    242:   while (len > 0)
                    243:     {
                    244:       l = len;
                    245:       if (l > sizeof(msg))
                    246:        l = sizeof(msg);
                    247:       l = read(auth->fd, msg, l);
                    248:       if (l <= 0)
                    249:        fatal("Incomplete authentication reply.");
                    250:       buffer_append(&auth->identities, (char *)msg, l);
                    251:       len -= l;
                    252:     }
                    253:
                    254:   /* Get message type, and verify that we got a proper answer. */
                    255:   buffer_get(&auth->identities, (char *)msg, 1);
                    256:   if (msg[0] != SSH_AGENT_RSA_IDENTITIES_ANSWER)
                    257:     fatal("Bad authentication reply message type: %d", msg[0]);
                    258:
                    259:   /* Get the number of entries in the response and check it for sanity. */
                    260:   auth->howmany = buffer_get_int(&auth->identities);
                    261:   if (auth->howmany > 1024)
                    262:     fatal("Too many identities in authentication reply: %d\n", auth->howmany);
                    263:
                    264:   /* Return the first entry (if any). */
                    265:   return ssh_get_next_identity(auth, bitsp, e, n, comment);
                    266: }
                    267:
                    268: /* Returns the next authentication identity for the agent.  Other functions
                    269:    can be called between this and ssh_get_first_identity or two calls of this
                    270:    function.  This returns 0 if there are no more identities.  The caller
                    271:    must free comment after a successful return. */
                    272:
1.2       provos    273: int
                    274: ssh_get_next_identity(AuthenticationConnection *auth,
                    275:                      int *bitsp, BIGNUM *e, BIGNUM *n, char **comment)
1.1       deraadt   276: {
                    277:   /* Return failure if no more entries. */
                    278:   if (auth->howmany <= 0)
                    279:     return 0;
                    280:
                    281:   /* Get the next entry from the packet.  These will abort with a fatal
                    282:      error if the packet is too short or contains corrupt data. */
                    283:   *bitsp = buffer_get_int(&auth->identities);
1.2       provos    284:   buffer_get_bignum(&auth->identities, e);
                    285:   buffer_get_bignum(&auth->identities, n);
1.1       deraadt   286:   *comment = buffer_get_string(&auth->identities, NULL);
                    287:
                    288:   /* Decrement the number of remaining entries. */
                    289:   auth->howmany--;
                    290:
                    291:   return 1;
                    292: }
                    293:
                    294: /* Generates a random challenge, sends it to the agent, and waits for response
                    295:    from the agent.  Returns true (non-zero) if the agent gave the correct
                    296:    answer, zero otherwise.  Response type selects the style of response
                    297:    desired, with 0 corresponding to protocol version 1.0 (no longer supported)
                    298:    and 1 corresponding to protocol version 1.1. */
                    299:
1.2       provos    300: int
                    301: ssh_decrypt_challenge(AuthenticationConnection *auth,
                    302:                      int bits, BIGNUM *e, BIGNUM *n, BIGNUM *challenge,
                    303:                      unsigned char session_id[16],
                    304:                      unsigned int response_type,
                    305:                      unsigned char response[16])
1.1       deraadt   306: {
                    307:   Buffer buffer;
                    308:   unsigned char buf[8192];
                    309:   int len, l, i;
                    310:
                    311:   /* Response type 0 is no longer supported. */
                    312:   if (response_type == 0)
                    313:     fatal("Compatibility with ssh protocol version 1.0 no longer supported.");
                    314:
                    315:   /* Format a message to the agent. */
                    316:   buf[0] = SSH_AGENTC_RSA_CHALLENGE;
                    317:   buffer_init(&buffer);
                    318:   buffer_append(&buffer, (char *)buf, 1);
                    319:   buffer_put_int(&buffer, bits);
1.2       provos    320:   buffer_put_bignum(&buffer, e);
                    321:   buffer_put_bignum(&buffer, n);
                    322:   buffer_put_bignum(&buffer, challenge);
1.1       deraadt   323:   buffer_append(&buffer, (char *)session_id, 16);
                    324:   buffer_put_int(&buffer, response_type);
                    325:
                    326:   /* Get the length of the message, and format it in the buffer. */
                    327:   len = buffer_len(&buffer);
                    328:   PUT_32BIT(buf, len);
                    329:
                    330:   /* Send the length and then the packet to the agent. */
                    331:   if (write(auth->fd, buf, 4) != 4 ||
                    332:       write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
                    333:         buffer_len(&buffer))
                    334:     {
                    335:       error("Error writing to authentication socket.");
                    336:     error_cleanup:
                    337:       buffer_free(&buffer);
                    338:       return 0;
                    339:     }
                    340:
                    341:   /* Wait for response from the agent.  First read the length of the
                    342:      response packet. */
                    343:   len = 4;
                    344:   while (len > 0)
                    345:     {
                    346:       l = read(auth->fd, buf + 4 - len, len);
                    347:       if (l <= 0)
                    348:        {
                    349:          error("Error reading response length from authentication socket.");
                    350:          goto error_cleanup;
                    351:        }
                    352:       len -= l;
                    353:     }
                    354:
                    355:   /* Extract the length, and check it for sanity. */
                    356:   len = GET_32BIT(buf);
                    357:   if (len > 256*1024)
                    358:     fatal("Authentication response too long: %d", len);
                    359:
                    360:   /* Read the rest of the response in tothe buffer. */
                    361:   buffer_clear(&buffer);
                    362:   while (len > 0)
                    363:     {
                    364:       l = len;
                    365:       if (l > sizeof(buf))
                    366:        l = sizeof(buf);
                    367:       l = read(auth->fd, buf, l);
                    368:       if (l <= 0)
                    369:        {
                    370:          error("Error reading response from authentication socket.");
                    371:          goto error_cleanup;
                    372:        }
                    373:       buffer_append(&buffer, (char *)buf, l);
                    374:       len -= l;
                    375:     }
                    376:
                    377:   /* Get the type of the packet. */
                    378:   buffer_get(&buffer, (char *)buf, 1);
                    379:
                    380:   /* Check for agent failure message. */
                    381:   if (buf[0] == SSH_AGENT_FAILURE)
                    382:     {
                    383:       log("Agent admitted failure to authenticate using the key.");
                    384:       goto error_cleanup;
                    385:     }
                    386:
                    387:   /* Now it must be an authentication response packet. */
                    388:   if (buf[0] != SSH_AGENT_RSA_RESPONSE)
                    389:     fatal("Bad authentication response: %d", buf[0]);
                    390:
                    391:   /* Get the response from the packet.  This will abort with a fatal error
                    392:      if the packet is corrupt. */
                    393:   for (i = 0; i < 16; i++)
                    394:     response[i] = buffer_get_char(&buffer);
                    395:
                    396:   /* The buffer containing the packet is no longer needed. */
                    397:   buffer_free(&buffer);
                    398:
                    399:   /* Correct answer. */
                    400:   return 1;
                    401: }
                    402:
                    403: /* Adds an identity to the authentication server.  This call is not meant to
                    404:    be used by normal applications. */
                    405:
                    406: int ssh_add_identity(AuthenticationConnection *auth,
1.2       provos    407:                     RSA *key, const char *comment)
1.1       deraadt   408: {
                    409:   Buffer buffer;
                    410:   unsigned char buf[8192];
                    411:   int len, l, type;
                    412:
                    413:   /* Format a message to the agent. */
                    414:   buffer_init(&buffer);
                    415:   buffer_put_char(&buffer, SSH_AGENTC_ADD_RSA_IDENTITY);
1.2       provos    416:   buffer_put_int(&buffer, BN_num_bits(key->n));
                    417:   buffer_put_bignum(&buffer, key->n);
                    418:   buffer_put_bignum(&buffer, key->e);
                    419:   buffer_put_bignum(&buffer, key->d);
                    420:   /* To keep within the protocol: p < q for ssh. in SSL p > q */
                    421:   buffer_put_bignum(&buffer, key->iqmp); /* ssh key->u */
                    422:   buffer_put_bignum(&buffer, key->q); /* ssh key->p, SSL key->q */
                    423:   buffer_put_bignum(&buffer, key->p); /* ssh key->q, SSL key->p */
1.1       deraadt   424:   buffer_put_string(&buffer, comment, strlen(comment));
                    425:
                    426:   /* Get the length of the message, and format it in the buffer. */
                    427:   len = buffer_len(&buffer);
                    428:   PUT_32BIT(buf, len);
                    429:
                    430:   /* Send the length and then the packet to the agent. */
                    431:   if (write(auth->fd, buf, 4) != 4 ||
                    432:       write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
                    433:         buffer_len(&buffer))
                    434:     {
                    435:       error("Error writing to authentication socket.");
                    436:     error_cleanup:
                    437:       buffer_free(&buffer);
                    438:       return 0;
                    439:     }
                    440:
                    441:   /* Wait for response from the agent.  First read the length of the
                    442:      response packet. */
                    443:   len = 4;
                    444:   while (len > 0)
                    445:     {
                    446:       l = read(auth->fd, buf + 4 - len, len);
                    447:       if (l <= 0)
                    448:        {
                    449:          error("Error reading response length from authentication socket.");
                    450:          goto error_cleanup;
                    451:        }
                    452:       len -= l;
                    453:     }
                    454:
                    455:   /* Extract the length, and check it for sanity. */
                    456:   len = GET_32BIT(buf);
                    457:   if (len > 256*1024)
                    458:     fatal("Add identity response too long: %d", len);
                    459:
                    460:   /* Read the rest of the response in tothe buffer. */
                    461:   buffer_clear(&buffer);
                    462:   while (len > 0)
                    463:     {
                    464:       l = len;
                    465:       if (l > sizeof(buf))
                    466:        l = sizeof(buf);
                    467:       l = read(auth->fd, buf, l);
                    468:       if (l <= 0)
                    469:        {
                    470:          error("Error reading response from authentication socket.");
                    471:          goto error_cleanup;
                    472:        }
                    473:       buffer_append(&buffer, (char *)buf, l);
                    474:       len -= l;
                    475:     }
                    476:
                    477:   /* Get the type of the packet. */
                    478:   type = buffer_get_char(&buffer);
                    479:   switch (type)
                    480:     {
                    481:     case SSH_AGENT_FAILURE:
                    482:       buffer_free(&buffer);
                    483:       return 0;
                    484:     case SSH_AGENT_SUCCESS:
                    485:       buffer_free(&buffer);
                    486:       return 1;
                    487:     default:
                    488:       fatal("Bad response to add identity from authentication agent: %d",
                    489:            type);
                    490:     }
                    491:   /*NOTREACHED*/
                    492:   return 0;
                    493: }
                    494:
                    495: /* Removes an identity from the authentication server.  This call is not meant
                    496:    to be used by normal applications. */
                    497:
1.2       provos    498: int ssh_remove_identity(AuthenticationConnection *auth, RSA *key)
1.1       deraadt   499: {
                    500:   Buffer buffer;
                    501:   unsigned char buf[8192];
                    502:   int len, l, type;
                    503:
                    504:   /* Format a message to the agent. */
                    505:   buffer_init(&buffer);
                    506:   buffer_put_char(&buffer, SSH_AGENTC_REMOVE_RSA_IDENTITY);
1.2       provos    507:   buffer_put_int(&buffer, BN_num_bits(key->n));
                    508:   buffer_put_bignum(&buffer, key->e);
                    509:   buffer_put_bignum(&buffer, key->n);
1.1       deraadt   510:
                    511:   /* Get the length of the message, and format it in the buffer. */
                    512:   len = buffer_len(&buffer);
                    513:   PUT_32BIT(buf, len);
                    514:
                    515:   /* Send the length and then the packet to the agent. */
                    516:   if (write(auth->fd, buf, 4) != 4 ||
                    517:       write(auth->fd, buffer_ptr(&buffer), buffer_len(&buffer)) !=
                    518:         buffer_len(&buffer))
                    519:     {
                    520:       error("Error writing to authentication socket.");
                    521:     error_cleanup:
                    522:       buffer_free(&buffer);
                    523:       return 0;
                    524:     }
                    525:
                    526:   /* Wait for response from the agent.  First read the length of the
                    527:      response packet. */
                    528:   len = 4;
                    529:   while (len > 0)
                    530:     {
                    531:       l = read(auth->fd, buf + 4 - len, len);
                    532:       if (l <= 0)
                    533:        {
                    534:          error("Error reading response length from authentication socket.");
                    535:          goto error_cleanup;
                    536:        }
                    537:       len -= l;
                    538:     }
                    539:
                    540:   /* Extract the length, and check it for sanity. */
                    541:   len = GET_32BIT(buf);
                    542:   if (len > 256*1024)
                    543:     fatal("Remove identity response too long: %d", len);
                    544:
                    545:   /* Read the rest of the response in tothe buffer. */
                    546:   buffer_clear(&buffer);
                    547:   while (len > 0)
                    548:     {
                    549:       l = len;
                    550:       if (l > sizeof(buf))
                    551:        l = sizeof(buf);
                    552:       l = read(auth->fd, buf, l);
                    553:       if (l <= 0)
                    554:        {
                    555:          error("Error reading response from authentication socket.");
                    556:          goto error_cleanup;
                    557:        }
                    558:       buffer_append(&buffer, (char *)buf, l);
                    559:       len -= l;
                    560:     }
                    561:
                    562:   /* Get the type of the packet. */
                    563:   type = buffer_get_char(&buffer);
                    564:   switch (type)
                    565:     {
                    566:     case SSH_AGENT_FAILURE:
                    567:       buffer_free(&buffer);
                    568:       return 0;
                    569:     case SSH_AGENT_SUCCESS:
                    570:       buffer_free(&buffer);
                    571:       return 1;
                    572:     default:
                    573:       fatal("Bad response to remove identity from authentication agent: %d",
                    574:            type);
                    575:     }
                    576:   /*NOTREACHED*/
                    577:   return 0;
                    578: }
                    579:
                    580: /* Removes all identities from the agent.  This call is not meant
                    581:    to be used by normal applications. */
                    582:
                    583: int ssh_remove_all_identities(AuthenticationConnection *auth)
                    584: {
                    585:   Buffer buffer;
                    586:   unsigned char buf[8192];
                    587:   int len, l, type;
                    588:
                    589:   /* Get the length of the message, and format it in the buffer. */
                    590:   PUT_32BIT(buf, 1);
                    591:   buf[4] = SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES;
                    592:
                    593:   /* Send the length and then the packet to the agent. */
                    594:   if (write(auth->fd, buf, 5) != 5)
                    595:     {
                    596:       error("Error writing to authentication socket.");
                    597:       return 0;
                    598:     }
                    599:
                    600:   /* Wait for response from the agent.  First read the length of the
                    601:      response packet. */
                    602:   len = 4;
                    603:   while (len > 0)
                    604:     {
                    605:       l = read(auth->fd, buf + 4 - len, len);
                    606:       if (l <= 0)
                    607:        {
                    608:          error("Error reading response length from authentication socket.");
                    609:          return 0;
                    610:        }
                    611:       len -= l;
                    612:     }
                    613:
                    614:   /* Extract the length, and check it for sanity. */
                    615:   len = GET_32BIT(buf);
                    616:   if (len > 256*1024)
                    617:     fatal("Remove identity response too long: %d", len);
                    618:
                    619:   /* Read the rest of the response into the buffer. */
                    620:   buffer_init(&buffer);
                    621:   while (len > 0)
                    622:     {
                    623:       l = len;
                    624:       if (l > sizeof(buf))
                    625:        l = sizeof(buf);
                    626:       l = read(auth->fd, buf, l);
                    627:       if (l <= 0)
                    628:        {
                    629:          error("Error reading response from authentication socket.");
                    630:          buffer_free(&buffer);
                    631:          return 0;
                    632:        }
                    633:       buffer_append(&buffer, (char *)buf, l);
                    634:       len -= l;
                    635:     }
                    636:
                    637:   /* Get the type of the packet. */
                    638:   type = buffer_get_char(&buffer);
                    639:   switch (type)
                    640:     {
                    641:     case SSH_AGENT_FAILURE:
                    642:       buffer_free(&buffer);
                    643:       return 0;
                    644:     case SSH_AGENT_SUCCESS:
                    645:       buffer_free(&buffer);
                    646:       return 1;
                    647:     default:
                    648:       fatal("Bad response to remove identity from authentication agent: %d",
                    649:            type);
                    650:     }
                    651:   /*NOTREACHED*/
                    652:   return 0;
                    653: }
                    654:
                    655: /* Closes the connection to the authentication agent. */
                    656:
                    657: void ssh_close_authentication(AuthenticationConnection *auth)
                    658: {
                    659:   /* Close the connection. */
1.5       deraadt   660:   shutdown(auth->fd, SHUT_RDWR);
1.1       deraadt   661:   close(auth->fd);
                    662:
                    663:   /* Free the buffers. */
                    664:   buffer_free(&auth->packet);
                    665:   buffer_free(&auth->identities);
                    666:
                    667:   /* Free the connection data structure. */
                    668:   xfree(auth);
                    669: }