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

Annotation of src/usr.bin/ssh/ssh-agent.c, Revision 1.9

1.1       deraadt     1: /*
                      2:
                      3: ssh-agent.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 03:46:59 1995 ylo
                     11:
                     12: The authentication agent program.
                     13:
                     14: */
                     15:
                     16: #include "includes.h"
1.9     ! markus     17: RCSID("$Id: ssh-agent.c,v 1.8 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 "packet.h"
                     26: #include "getput.h"
                     27: #include "mpaux.h"
                     28:
1.7       deraadt    29: #include <md5.h>
                     30:
1.1       deraadt    31: typedef struct
                     32: {
                     33:   int fd;
                     34:   enum { AUTH_UNUSED, AUTH_FD, AUTH_SOCKET, AUTH_SOCKET_FD,
                     35:     AUTH_CONNECTION } type;
                     36:   Buffer input;
                     37:   Buffer output;
                     38: } SocketEntry;
                     39:
                     40: unsigned int sockets_alloc = 0;
                     41: SocketEntry *sockets = NULL;
                     42:
                     43: typedef struct
                     44: {
1.2       provos     45:   RSA *key;
1.1       deraadt    46:   char *comment;
                     47: } Identity;
                     48:
                     49: unsigned int num_identities = 0;
                     50: Identity *identities = NULL;
                     51:
                     52: int max_fd = 0;
                     53:
1.2       provos     54: void
                     55: process_request_identity(SocketEntry *e)
1.1       deraadt    56: {
                     57:   Buffer msg;
                     58:   int i;
                     59:
                     60:   buffer_init(&msg);
                     61:   buffer_put_char(&msg, SSH_AGENT_RSA_IDENTITIES_ANSWER);
                     62:   buffer_put_int(&msg, num_identities);
                     63:   for (i = 0; i < num_identities; i++)
                     64:     {
1.2       provos     65:       buffer_put_int(&msg, BN_num_bits(identities[i].key->n));
                     66:       buffer_put_bignum(&msg, identities[i].key->e);
                     67:       buffer_put_bignum(&msg, identities[i].key->n);
1.1       deraadt    68:       buffer_put_string(&msg, identities[i].comment,
                     69:                        strlen(identities[i].comment));
                     70:     }
                     71:   buffer_put_int(&e->output, buffer_len(&msg));
                     72:   buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg));
                     73:   buffer_free(&msg);
                     74: }
                     75:
1.2       provos     76: void
                     77: process_authentication_challenge(SocketEntry *e)
1.1       deraadt    78: {
1.2       provos     79:   int i, pub_bits, len;
                     80:   BIGNUM *pub_e, *pub_n, *challenge;
1.1       deraadt    81:   Buffer msg;
1.7       deraadt    82:   MD5_CTX md;
1.1       deraadt    83:   unsigned char buf[32], mdbuf[16], session_id[16];
                     84:   unsigned int response_type;
                     85:
                     86:   buffer_init(&msg);
1.2       provos     87:   pub_e = BN_new();
                     88:   pub_n = BN_new();
                     89:   challenge = BN_new();
1.1       deraadt    90:   pub_bits = buffer_get_int(&e->input);
1.2       provos     91:   buffer_get_bignum(&e->input, pub_e);
                     92:   buffer_get_bignum(&e->input, pub_n);
                     93:   buffer_get_bignum(&e->input, challenge);
1.1       deraadt    94:   if (buffer_len(&e->input) == 0)
                     95:     {
                     96:       /* Compatibility code for old servers. */
                     97:       memset(session_id, 0, 16);
                     98:       response_type = 0;
                     99:     }
                    100:   else
                    101:     {
                    102:       /* New code. */
                    103:       buffer_get(&e->input, (char *)session_id, 16);
                    104:       response_type = buffer_get_int(&e->input);
                    105:     }
                    106:   for (i = 0; i < num_identities; i++)
1.2       provos    107:     if (pub_bits == BN_num_bits(identities[i].key->n) &&
                    108:        BN_cmp(pub_e, identities[i].key->e) == 0 &&
                    109:        BN_cmp(pub_n, identities[i].key->n) == 0)
1.1       deraadt   110:       {
                    111:        /* Decrypt the challenge using the private key. */
1.2       provos    112:        rsa_private_decrypt(challenge, challenge, identities[i].key);
1.1       deraadt   113:
                    114:        /* Compute the desired response. */
                    115:        switch (response_type)
                    116:          {
                    117:          case 0: /* As of protocol 1.0 */
                    118:            /* This response type is no longer supported. */
                    119:            log("Compatibility with ssh protocol 1.0 no longer supported.");
                    120:            buffer_put_char(&msg, SSH_AGENT_FAILURE);
                    121:            goto send;
                    122:
                    123:          case 1: /* As of protocol 1.1 */
                    124:            /* The response is MD5 of decrypted challenge plus session id. */
1.2       provos    125:            len = BN_num_bytes(challenge);
                    126:            assert(len <= 32 && len);
                    127:            memset(buf, 0, 32);
                    128:            BN_bn2bin(challenge, buf + 32 - len);
1.1       deraadt   129:            MD5Init(&md);
                    130:            MD5Update(&md, buf, 32);
                    131:            MD5Update(&md, session_id, 16);
                    132:            MD5Final(mdbuf, &md);
                    133:            break;
                    134:
                    135:          default:
                    136:            fatal("process_authentication_challenge: bad response_type %d",
                    137:                  response_type);
                    138:            break;
                    139:          }
                    140:
                    141:        /* Send the response. */
                    142:        buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE);
                    143:        for (i = 0; i < 16; i++)
                    144:          buffer_put_char(&msg, mdbuf[i]);
                    145:
                    146:        goto send;
                    147:       }
                    148:   /* Unknown identity.  Send failure. */
                    149:   buffer_put_char(&msg, SSH_AGENT_FAILURE);
                    150:  send:
                    151:   buffer_put_int(&e->output, buffer_len(&msg));
                    152:   buffer_append(&e->output, buffer_ptr(&msg),
                    153:                buffer_len(&msg));
                    154:   buffer_free(&msg);
1.2       provos    155:   BN_clear_free(pub_e);
                    156:   BN_clear_free(pub_n);
                    157:   BN_clear_free(challenge);
1.1       deraadt   158: }
                    159:
1.2       provos    160: void
                    161: process_remove_identity(SocketEntry *e)
1.1       deraadt   162: {
                    163:   unsigned int bits;
                    164:   unsigned int i;
1.2       provos    165:   BIGNUM *dummy, *n;
1.1       deraadt   166:
1.2       provos    167:   dummy = BN_new();
                    168:   n = BN_new();
1.1       deraadt   169:
                    170:   /* Get the key from the packet. */
                    171:   bits = buffer_get_int(&e->input);
1.2       provos    172:   buffer_get_bignum(&e->input, dummy);
                    173:   buffer_get_bignum(&e->input, n);
1.1       deraadt   174:
                    175:   /* Check if we have the key. */
                    176:   for (i = 0; i < num_identities; i++)
1.2       provos    177:     if (BN_cmp(identities[i].key->n, n) == 0)
1.1       deraadt   178:       {
                    179:        /* We have this key.  Free the old key.  Since we don\'t want to leave
                    180:           empty slots in the middle of the array, we actually free the
                    181:           key there and copy data from the last entry. */
1.2       provos    182:        RSA_free(identities[i].key);
1.1       deraadt   183:        xfree(identities[i].comment);
                    184:        if (i < num_identities - 1)
                    185:          identities[i] = identities[num_identities - 1];
                    186:        num_identities--;
1.2       provos    187:        BN_clear_free(dummy);
                    188:        BN_clear_free(n);
1.1       deraadt   189:
                    190:        /* Send success. */
                    191:        buffer_put_int(&e->output, 1);
                    192:        buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
                    193:        return;
                    194:       }
                    195:   /* We did not have the key. */
1.2       provos    196:   BN_clear(dummy);
                    197:   BN_clear(n);
1.1       deraadt   198:
                    199:   /* Send failure. */
                    200:   buffer_put_int(&e->output, 1);
                    201:   buffer_put_char(&e->output, SSH_AGENT_FAILURE);
                    202: }
                    203:
                    204: /* Removes all identities from the agent. */
                    205:
1.2       provos    206: void
                    207: process_remove_all_identities(SocketEntry *e)
1.1       deraadt   208: {
                    209:   unsigned int i;
                    210:
                    211:   /* Loop over all identities and clear the keys. */
                    212:   for (i = 0; i < num_identities; i++)
                    213:     {
1.2       provos    214:       RSA_free(identities[i].key);
1.1       deraadt   215:       xfree(identities[i].comment);
                    216:     }
                    217:
                    218:   /* Mark that there are no identities. */
                    219:   num_identities = 0;
                    220:
                    221:   /* Send success. */
                    222:   buffer_put_int(&e->output, 1);
                    223:   buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
                    224:   return;
                    225: }
                    226:
                    227: /* Adds an identity to the agent. */
                    228:
1.2       provos    229: void
                    230: process_add_identity(SocketEntry *e)
1.1       deraadt   231: {
1.2       provos    232:   RSA *k;
1.1       deraadt   233:   int i;
1.2       provos    234:   BIGNUM *aux;
                    235:   BN_CTX *ctx;
                    236:
1.1       deraadt   237:   if (num_identities == 0)
                    238:     identities = xmalloc(sizeof(Identity));
                    239:   else
                    240:     identities = xrealloc(identities, (num_identities + 1) * sizeof(Identity));
1.2       provos    241:
                    242:   identities[num_identities].key = RSA_new();
                    243:   k = identities[num_identities].key;
                    244:   buffer_get_int(&e->input); /* bits */
                    245:   k->n = BN_new();
                    246:   buffer_get_bignum(&e->input, k->n);
                    247:   k->e = BN_new();
                    248:   buffer_get_bignum(&e->input, k->e);
                    249:   k->d = BN_new();
                    250:   buffer_get_bignum(&e->input, k->d);
                    251:   k->iqmp = BN_new();
                    252:   buffer_get_bignum(&e->input, k->iqmp);
                    253:   /* SSH and SSL have p and q swapped */
                    254:   k->q = BN_new();
                    255:   buffer_get_bignum(&e->input, k->q); /* p */
                    256:   k->p = BN_new();
                    257:   buffer_get_bignum(&e->input, k->p); /* q */
                    258:
                    259:   /* Generate additional parameters */
                    260:   aux = BN_new();
                    261:   ctx = BN_CTX_new();
                    262:
                    263:   BN_sub(aux, k->q, BN_value_one());
                    264:   k->dmq1 = BN_new();
                    265:   BN_mod(k->dmq1, k->d, aux, ctx);
                    266:
                    267:   BN_sub(aux, k->p, BN_value_one());
                    268:   k->dmp1 = BN_new();
                    269:   BN_mod(k->dmp1, k->d, aux, ctx);
                    270:
                    271:   BN_clear_free(aux);
                    272:   BN_CTX_free(ctx);
                    273:
1.1       deraadt   274:   identities[num_identities].comment = buffer_get_string(&e->input, NULL);
                    275:
                    276:   /* Check if we already have the key. */
                    277:   for (i = 0; i < num_identities; i++)
1.2       provos    278:     if (BN_cmp(identities[i].key->n, k->n) == 0)
1.1       deraadt   279:       {
                    280:        /* We already have this key.  Clear and free the new data and
                    281:           return success. */
1.2       provos    282:        RSA_free(k);
1.1       deraadt   283:        xfree(identities[num_identities].comment);
                    284:
                    285:        /* Send success. */
                    286:        buffer_put_int(&e->output, 1);
                    287:        buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
                    288:        return;
                    289:       }
                    290:
                    291:   /* Increment the number of identities. */
                    292:   num_identities++;
                    293:
                    294:   /* Send a success message. */
                    295:   buffer_put_int(&e->output, 1);
                    296:   buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
                    297: }
                    298:
1.2       provos    299: void
                    300: process_message(SocketEntry *e)
1.1       deraadt   301: {
                    302:   unsigned int msg_len;
                    303:   unsigned int type;
                    304:   unsigned char *cp;
                    305:   if (buffer_len(&e->input) < 5)
                    306:     return; /* Incomplete message. */
                    307:   cp = (unsigned char *)buffer_ptr(&e->input);
                    308:   msg_len = GET_32BIT(cp);
                    309:   if (msg_len > 256 * 1024)
                    310:     {
1.8       deraadt   311:       shutdown(e->fd, SHUT_RDWR);
1.1       deraadt   312:       close(e->fd);
                    313:       e->type = AUTH_UNUSED;
                    314:       return;
                    315:     }
                    316:   if (buffer_len(&e->input) < msg_len + 4)
                    317:     return;
                    318:   buffer_consume(&e->input, 4);
                    319:   type = buffer_get_char(&e->input);
                    320:   switch (type)
                    321:     {
                    322:     case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
                    323:       process_request_identity(e);
                    324:       break;
                    325:     case SSH_AGENTC_RSA_CHALLENGE:
                    326:       process_authentication_challenge(e);
                    327:       break;
                    328:     case SSH_AGENTC_ADD_RSA_IDENTITY:
                    329:       process_add_identity(e);
                    330:       break;
                    331:     case SSH_AGENTC_REMOVE_RSA_IDENTITY:
                    332:       process_remove_identity(e);
                    333:       break;
                    334:     case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
                    335:       process_remove_all_identities(e);
                    336:       break;
                    337:     default:
                    338:       /* Unknown message.  Respond with failure. */
                    339:       error("Unknown message %d", type);
                    340:       buffer_clear(&e->input);
                    341:       buffer_put_int(&e->output, 1);
                    342:       buffer_put_char(&e->output, SSH_AGENT_FAILURE);
                    343:       break;
                    344:     }
                    345: }
                    346:
1.2       provos    347: void
                    348: new_socket(int type, int fd)
1.1       deraadt   349: {
                    350:   unsigned int i, old_alloc;
                    351:   if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
                    352:     error("fcntl O_NONBLOCK: %s", strerror(errno));
                    353:
                    354:   if (fd > max_fd)
                    355:     max_fd = fd;
                    356:
                    357:   for (i = 0; i < sockets_alloc; i++)
                    358:     if (sockets[i].type == AUTH_UNUSED)
                    359:       {
                    360:        sockets[i].fd = fd;
                    361:        sockets[i].type = type;
                    362:        buffer_init(&sockets[i].input);
                    363:        buffer_init(&sockets[i].output);
                    364:        return;
                    365:       }
                    366:   old_alloc = sockets_alloc;
                    367:   sockets_alloc += 10;
                    368:   if (sockets)
                    369:     sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0]));
                    370:   else
                    371:     sockets = xmalloc(sockets_alloc * sizeof(sockets[0]));
                    372:   for (i = old_alloc; i < sockets_alloc; i++)
                    373:     sockets[i].type = AUTH_UNUSED;
                    374:   sockets[old_alloc].type = type;
                    375:   sockets[old_alloc].fd = fd;
                    376:   buffer_init(&sockets[old_alloc].input);
                    377:   buffer_init(&sockets[old_alloc].output);
                    378: }
                    379:
1.2       provos    380: void
                    381: prepare_select(fd_set *readset, fd_set *writeset)
1.1       deraadt   382: {
                    383:   unsigned int i;
                    384:   for (i = 0; i < sockets_alloc; i++)
                    385:     switch (sockets[i].type)
                    386:       {
                    387:       case AUTH_FD:
                    388:       case AUTH_CONNECTION:
                    389:       case AUTH_SOCKET:
                    390:       case AUTH_SOCKET_FD:
                    391:        FD_SET(sockets[i].fd, readset);
                    392:        if (buffer_len(&sockets[i].output) > 0)
                    393:          FD_SET(sockets[i].fd, writeset);
                    394:        break;
                    395:       case AUTH_UNUSED:
                    396:        break;
                    397:       default:
                    398:        fatal("Unknown socket type %d", sockets[i].type);
                    399:        break;
                    400:       }
                    401: }
                    402:
                    403: void after_select(fd_set *readset, fd_set *writeset)
                    404: {
                    405:   unsigned int i;
                    406:   int len, sock, port;
                    407:   char buf[1024];
                    408:   struct sockaddr_in sin;
                    409:   struct sockaddr_un sunaddr;
                    410:
                    411:   for (i = 0; i < sockets_alloc; i++)
                    412:     switch (sockets[i].type)
                    413:       {
                    414:       case AUTH_UNUSED:
                    415:        break;
                    416:       case AUTH_FD:
                    417:        if (FD_ISSET(sockets[i].fd, readset))
                    418:          {
                    419:            len = recv(sockets[i].fd, buf, sizeof(buf), 0);
                    420:            if (len <= 0)
                    421:              { /* All instances of the other side have been closed. */
                    422:                log("Authentication agent exiting.");
                    423:                exit(0);
                    424:              }
                    425:          process_auth_fd_input:
                    426:            if (len != 3 || (unsigned char)buf[0] != SSH_AUTHFD_CONNECT)
                    427:              break; /* Incorrect message; ignore it. */
                    428:            /* It is a connection request message. */
                    429:            port = (unsigned char)buf[1] * 256 + (unsigned char)buf[2];
                    430:            memset(&sin, 0, sizeof(sin));
                    431:            sin.sin_family = AF_INET;
                    432:            sin.sin_addr.s_addr = htonl(0x7f000001); /* localhost */
                    433:            sin.sin_port = htons(port);
                    434:            sock = socket(AF_INET, SOCK_STREAM, 0);
                    435:            if (sock < 0)
                    436:              {
                    437:                perror("socket");
                    438:                break;
                    439:              }
                    440:            if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
                    441:              {
                    442:                perror("connecting to port requested in authfd message");
                    443:                close(sock);
                    444:                break;
                    445:              }
                    446:            new_socket(AUTH_CONNECTION, sock);
                    447:          }
                    448:        break;
                    449:       case AUTH_SOCKET:
                    450:        if (FD_ISSET(sockets[i].fd, readset))
                    451:          {
                    452:            len = sizeof(sunaddr);
                    453:            sock = accept(sockets[i].fd, (struct sockaddr *)&sunaddr, &len);
                    454:            if (sock < 0)
                    455:              {
                    456:                perror("accept from AUTH_SOCKET");
                    457:                break;
                    458:              }
                    459:            new_socket(AUTH_SOCKET_FD, sock);
                    460:          }
                    461:        break;
                    462:       case AUTH_SOCKET_FD:
                    463:        if (FD_ISSET(sockets[i].fd, readset))
                    464:          {
                    465:            len = recv(sockets[i].fd, buf, sizeof(buf), 0);
                    466:            if (len <= 0)
                    467:              { /* The other side has closed the socket. */
1.8       deraadt   468:                shutdown(sockets[i].fd, SHUT_RDWR);
1.1       deraadt   469:                close(sockets[i].fd);
                    470:                sockets[i].type = AUTH_UNUSED;
                    471:                break;
                    472:              }
                    473:            goto process_auth_fd_input;
                    474:          }
                    475:        break;
                    476:       case AUTH_CONNECTION:
                    477:        if (buffer_len(&sockets[i].output) > 0 &&
                    478:            FD_ISSET(sockets[i].fd, writeset))
                    479:          {
                    480:            len = write(sockets[i].fd, buffer_ptr(&sockets[i].output),
                    481:                        buffer_len(&sockets[i].output));
                    482:            if (len <= 0)
                    483:              {
1.8       deraadt   484:                shutdown(sockets[i].fd, SHUT_RDWR);
1.1       deraadt   485:                close(sockets[i].fd);
                    486:                sockets[i].type = AUTH_UNUSED;
                    487:                break;
                    488:              }
                    489:            buffer_consume(&sockets[i].output, len);
                    490:          }
                    491:        if (FD_ISSET(sockets[i].fd, readset))
                    492:          {
                    493:            len = read(sockets[i].fd, buf, sizeof(buf));
                    494:            if (len <= 0)
                    495:              {
1.8       deraadt   496:                shutdown(sockets[i].fd, SHUT_RDWR);
1.1       deraadt   497:                close(sockets[i].fd);
                    498:                sockets[i].type = AUTH_UNUSED;
                    499:                break;
                    500:              }
                    501:            buffer_append(&sockets[i].input, buf, len);
                    502:            process_message(&sockets[i]);
                    503:          }
                    504:        break;
                    505:       default:
                    506:        fatal("Unknown type %d", sockets[i].type);
                    507:       }
                    508: }
                    509:
                    510: int parent_pid = -1;
                    511: char socket_name[1024];
                    512:
1.6       deraadt   513: void
1.2       provos    514: check_parent_exists(int sig)
1.1       deraadt   515: {
                    516:   if (kill(parent_pid, 0) < 0)
                    517:     {
                    518:       remove(socket_name);
                    519:       /* printf("Parent has died - Authentication agent exiting.\n"); */
                    520:       exit(1);
                    521:     }
                    522:   signal(SIGALRM, check_parent_exists);
                    523:   alarm(10);
                    524: }
                    525:
1.2       provos    526: int
                    527: main(int ac, char **av)
1.1       deraadt   528: {
                    529:   fd_set readset, writeset;
                    530:   char buf[1024];
                    531:   int pfd;
                    532:   int sock;
                    533:   struct sockaddr_un sunaddr;
                    534:
                    535:   int sockets[2], i;
                    536:   int *dups;
1.3       deraadt   537:
                    538:   /* check if RSA support exists */
                    539:   if (rsa_alive() == 0) {
                    540:     extern char *__progname;
                    541:
                    542:     fprintf(stderr,
                    543:       "%s: no RSA support in libssl and libcrypto.  See ssl(8).\n",
                    544:       __progname);
                    545:     exit(1);
                    546:   }
1.1       deraadt   547:
                    548:   if (ac < 2)
                    549:     {
                    550:       fprintf(stderr, "ssh-agent version %s\n", SSH_VERSION);
                    551:       fprintf(stderr, "Usage: %s command\n", av[0]);
                    552:       exit(1);
                    553:     }
                    554:
1.9     ! markus    555:   /* The agent uses SSH_AUTHENTICATION_SOCKET. */
        !           556:
        !           557:   parent_pid = getpid();
        !           558:
        !           559:   snprintf(socket_name, sizeof socket_name, SSH_AGENT_SOCKET, parent_pid);
        !           560:
        !           561:   /* Fork, and have the parent execute the command.  The child continues as
        !           562:      the authentication agent. */
        !           563:   if (fork() != 0)
        !           564:     { /* Parent - execute the given command. */
        !           565:       snprintf(buf, sizeof buf, "SSH_AUTHENTICATION_SOCKET=%s", socket_name);
        !           566:       putenv(buf);
        !           567:       execvp(av[1], av + 1);
        !           568:       perror(av[1]);
        !           569:       exit(1);
        !           570:     }
        !           571:
        !           572:   sock = socket(AF_UNIX, SOCK_STREAM, 0);
        !           573:   if (sock < 0)
1.1       deraadt   574:     {
1.9     ! markus    575:       perror("socket");
        !           576:       exit(1);
        !           577:     }
        !           578:   memset(&sunaddr, 0, sizeof(sunaddr));
        !           579:   sunaddr.sun_family = AF_UNIX;
        !           580:   strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
        !           581:   if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
        !           582:     {
        !           583:       perror("bind");
        !           584:       exit(1);
        !           585:     }
        !           586:   if (chmod(socket_name, 0700) < 0)
        !           587:     {
        !           588:       perror("chmod");
        !           589:       exit(1);
        !           590:     }
        !           591:   if (listen(sock, 5) < 0)
        !           592:     {
        !           593:       perror("listen");
        !           594:       exit(1);
1.1       deraadt   595:     }
1.9     ! markus    596:   new_socket(AUTH_SOCKET, sock);
        !           597:   signal(SIGALRM, check_parent_exists);
        !           598:   alarm(10);
1.1       deraadt   599:
                    600:   signal(SIGINT, SIG_IGN);
                    601:   while (1)
                    602:     {
                    603:       FD_ZERO(&readset);
                    604:       FD_ZERO(&writeset);
                    605:       prepare_select(&readset, &writeset);
                    606:       if (select(max_fd + 1, &readset, &writeset, NULL, NULL) < 0)
                    607:        {
                    608:          if (errno == EINTR)
                    609:            continue;
                    610:          perror("select");
                    611:          exit(1);
                    612:        }
                    613:       after_select(&readset, &writeset);
                    614:     }
                    615:   /*NOTREACHED*/
                    616: }