[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.10

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