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

Annotation of src/usr.bin/ssh/auth.c, Revision 1.2

1.1       markus      1: /*
                      2:  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      3:  *                    All rights reserved
1.2     ! markus      4:  * Copyright (c) 2000 Markus Friedl. All rights reserved.
1.1       markus      5:  */
                      6:
                      7: #include "includes.h"
1.2     ! markus      8: RCSID("$OpenBSD: auth.c,v 1.1 2000/03/28 21:15:45 markus Exp $");
1.1       markus      9:
                     10: #include "xmalloc.h"
                     11: #include "rsa.h"
                     12: #include "ssh.h"
                     13: #include "pty.h"
                     14: #include "packet.h"
                     15: #include "buffer.h"
                     16: #include "cipher.h"
                     17: #include "mpaux.h"
                     18: #include "servconf.h"
1.2     ! markus     19: #include "compat.h"
1.1       markus     20: #include "channels.h"
                     21: #include "match.h"
                     22:
1.2     ! markus     23: #include "bufaux.h"
        !            24: #include "ssh2.h"
        !            25: #include "auth.h"
1.1       markus     26: #include "session.h"
                     27: #include "dispatch.h"
                     28:
1.2     ! markus     29:
1.1       markus     30: /* import */
                     31: extern ServerOptions options;
                     32: extern char *forced_command;
                     33:
                     34: /*
                     35:  * Check if the user is allowed to log in via ssh. If user is listed in
                     36:  * DenyUsers or user's primary group is listed in DenyGroups, false will
                     37:  * be returned. If AllowUsers isn't empty and user isn't listed there, or
                     38:  * if AllowGroups isn't empty and user isn't listed there, false will be
                     39:  * returned.
                     40:  * If the user's shell is not executable, false will be returned.
                     41:  * Otherwise true is returned.
                     42:  */
                     43: static int
                     44: allowed_user(struct passwd * pw)
                     45: {
                     46:        struct stat st;
                     47:        struct group *grp;
                     48:        int i;
                     49:
                     50:        /* Shouldn't be called if pw is NULL, but better safe than sorry... */
                     51:        if (!pw)
                     52:                return 0;
                     53:
                     54:        /* deny if shell does not exists or is not executable */
                     55:        if (stat(pw->pw_shell, &st) != 0)
                     56:                return 0;
                     57:        if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
                     58:                return 0;
                     59:
                     60:        /* Return false if user is listed in DenyUsers */
                     61:        if (options.num_deny_users > 0) {
                     62:                if (!pw->pw_name)
                     63:                        return 0;
                     64:                for (i = 0; i < options.num_deny_users; i++)
                     65:                        if (match_pattern(pw->pw_name, options.deny_users[i]))
                     66:                                return 0;
                     67:        }
                     68:        /* Return false if AllowUsers isn't empty and user isn't listed there */
                     69:        if (options.num_allow_users > 0) {
                     70:                if (!pw->pw_name)
                     71:                        return 0;
                     72:                for (i = 0; i < options.num_allow_users; i++)
                     73:                        if (match_pattern(pw->pw_name, options.allow_users[i]))
                     74:                                break;
                     75:                /* i < options.num_allow_users iff we break for loop */
                     76:                if (i >= options.num_allow_users)
                     77:                        return 0;
                     78:        }
                     79:        /* Get the primary group name if we need it. Return false if it fails */
                     80:        if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
                     81:                grp = getgrgid(pw->pw_gid);
                     82:                if (!grp)
                     83:                        return 0;
                     84:
                     85:                /* Return false if user's group is listed in DenyGroups */
                     86:                if (options.num_deny_groups > 0) {
                     87:                        if (!grp->gr_name)
                     88:                                return 0;
                     89:                        for (i = 0; i < options.num_deny_groups; i++)
                     90:                                if (match_pattern(grp->gr_name, options.deny_groups[i]))
                     91:                                        return 0;
                     92:                }
                     93:                /*
                     94:                 * Return false if AllowGroups isn't empty and user's group
                     95:                 * isn't listed there
                     96:                 */
                     97:                if (options.num_allow_groups > 0) {
                     98:                        if (!grp->gr_name)
                     99:                                return 0;
                    100:                        for (i = 0; i < options.num_allow_groups; i++)
                    101:                                if (match_pattern(grp->gr_name, options.allow_groups[i]))
                    102:                                        break;
                    103:                        /* i < options.num_allow_groups iff we break for
                    104:                           loop */
                    105:                        if (i >= options.num_allow_groups)
                    106:                                return 0;
                    107:                }
                    108:        }
                    109:        /* We found no reason not to let this user try to log on... */
                    110:        return 1;
                    111: }
                    112:
                    113: /*
                    114:  * convert ssh auth msg type into description
                    115:  */
                    116: char *
                    117: get_authname(int type)
                    118: {
                    119:        static char buf[1024];
                    120:        switch (type) {
                    121:        case SSH_CMSG_AUTH_PASSWORD:
                    122:                return "password";
                    123:        case SSH_CMSG_AUTH_RSA:
                    124:                return "rsa";
                    125:        case SSH_CMSG_AUTH_RHOSTS_RSA:
                    126:                return "rhosts-rsa";
                    127:        case SSH_CMSG_AUTH_RHOSTS:
                    128:                return "rhosts";
                    129: #ifdef KRB4
                    130:        case SSH_CMSG_AUTH_KERBEROS:
                    131:                return "kerberos";
                    132: #endif
                    133: #ifdef SKEY
                    134:        case SSH_CMSG_AUTH_TIS_RESPONSE:
                    135:                return "s/key";
                    136: #endif
                    137:        }
                    138:        snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
                    139:        return buf;
                    140: }
                    141:
                    142: #define AUTH_FAIL_MAX 6
                    143: #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
                    144: #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
                    145:
                    146: /*
                    147:  * The user does not exist or access is denied,
                    148:  * but fake indication that authentication is needed.
                    149:  */
                    150: void
                    151: do_fake_authloop1(char *user)
                    152: {
                    153:        int attempt = 0;
                    154:
                    155:        log("Faking authloop for illegal user %.200s from %.200s port %d",
                    156:            user,
                    157:            get_remote_ipaddr(),
                    158:            get_remote_port());
                    159:
                    160:        /* Indicate that authentication is needed. */
                    161:        packet_start(SSH_SMSG_FAILURE);
                    162:        packet_send();
                    163:        packet_write_wait();
                    164:
                    165:        /*
                    166:         * Keep reading packets, and always respond with a failure.  This is
                    167:         * to avoid disclosing whether such a user really exists.
                    168:         */
                    169:        for (attempt = 1;; attempt++) {
                    170:                /* Read a packet.  This will not return if the client disconnects. */
                    171:                int plen;
                    172:                int type = packet_read(&plen);
                    173: #ifdef SKEY
                    174:                unsigned int dlen;
                    175:                char *password, *skeyinfo;
                    176:                password = NULL;
                    177:                /* Try to send a fake s/key challenge. */
                    178:                if (options.skey_authentication == 1 &&
                    179:                    (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
                    180:                        if (type == SSH_CMSG_AUTH_TIS) {
                    181:                                packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                    182:                                packet_put_string(skeyinfo, strlen(skeyinfo));
                    183:                                packet_send();
                    184:                                packet_write_wait();
                    185:                                continue;
                    186:                        } else if (type == SSH_CMSG_AUTH_PASSWORD &&
                    187:                                   options.password_authentication &&
                    188:                                   (password = packet_get_string(&dlen)) != NULL &&
                    189:                                   dlen == 5 &&
                    190:                                   strncasecmp(password, "s/key", 5) == 0 ) {
                    191:                                packet_send_debug(skeyinfo);
                    192:                        }
                    193:                }
                    194:                if (password != NULL)
                    195:                        xfree(password);
                    196: #endif
                    197:                if (attempt > AUTH_FAIL_MAX)
                    198:                        packet_disconnect(AUTH_FAIL_MSG, user);
                    199:
                    200:                /*
                    201:                 * Send failure.  This should be indistinguishable from a
                    202:                 * failed authentication.
                    203:                 */
                    204:                packet_start(SSH_SMSG_FAILURE);
                    205:                packet_send();
                    206:                packet_write_wait();
                    207:        }
                    208:        /* NOTREACHED */
                    209:        abort();
                    210: }
                    211:
                    212: /*
                    213:  * read packets and try to authenticate local user *pw.
                    214:  * return if authentication is successfull
                    215:  */
                    216: void
                    217: do_authloop(struct passwd * pw)
                    218: {
                    219:        int attempt = 0;
                    220:        unsigned int bits;
                    221:        RSA *client_host_key;
                    222:        BIGNUM *n;
                    223:        char *client_user, *password;
                    224:        char user[1024];
                    225:        unsigned int dlen;
                    226:        int plen, nlen, elen;
                    227:        unsigned int ulen;
                    228:        int type = 0;
                    229:        void (*authlog) (const char *fmt,...) = verbose;
                    230:
                    231:        /* Indicate that authentication is needed. */
                    232:        packet_start(SSH_SMSG_FAILURE);
                    233:        packet_send();
                    234:        packet_write_wait();
                    235:
                    236:        for (attempt = 1;; attempt++) {
                    237:                int authenticated = 0;
                    238:                strlcpy(user, "", sizeof user);
                    239:
                    240:                /* Get a packet from the client. */
                    241:                type = packet_read(&plen);
                    242:
                    243:                /* Process the packet. */
                    244:                switch (type) {
                    245: #ifdef AFS
                    246:                case SSH_CMSG_HAVE_KERBEROS_TGT:
                    247:                        if (!options.kerberos_tgt_passing) {
                    248:                                /* packet_get_all(); */
                    249:                                verbose("Kerberos tgt passing disabled.");
                    250:                                break;
                    251:                        } else {
                    252:                                /* Accept Kerberos tgt. */
                    253:                                char *tgt = packet_get_string(&dlen);
                    254:                                packet_integrity_check(plen, 4 + dlen, type);
                    255:                                if (!auth_kerberos_tgt(pw, tgt))
                    256:                                        verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
                    257:                                xfree(tgt);
                    258:                        }
                    259:                        continue;
                    260:
                    261:                case SSH_CMSG_HAVE_AFS_TOKEN:
                    262:                        if (!options.afs_token_passing || !k_hasafs()) {
                    263:                                /* packet_get_all(); */
                    264:                                verbose("AFS token passing disabled.");
                    265:                                break;
                    266:                        } else {
                    267:                                /* Accept AFS token. */
                    268:                                char *token_string = packet_get_string(&dlen);
                    269:                                packet_integrity_check(plen, 4 + dlen, type);
                    270:                                if (!auth_afs_token(pw, token_string))
                    271:                                        verbose("AFS token REFUSED for %s", pw->pw_name);
                    272:                                xfree(token_string);
                    273:                        }
                    274:                        continue;
                    275: #endif /* AFS */
                    276: #ifdef KRB4
                    277:                case SSH_CMSG_AUTH_KERBEROS:
                    278:                        if (!options.kerberos_authentication) {
                    279:                                /* packet_get_all(); */
                    280:                                verbose("Kerberos authentication disabled.");
                    281:                                break;
                    282:                        } else {
                    283:                                /* Try Kerberos v4 authentication. */
                    284:                                KTEXT_ST auth;
                    285:                                char *tkt_user = NULL;
                    286:                                char *kdata = packet_get_string((unsigned int *) &auth.length);
                    287:                                packet_integrity_check(plen, 4 + auth.length, type);
                    288:
                    289:                                if (auth.length < MAX_KTXT_LEN)
                    290:                                        memcpy(auth.dat, kdata, auth.length);
                    291:                                xfree(kdata);
                    292:
                    293:                                authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
                    294:
                    295:                                if (authenticated) {
                    296:                                        snprintf(user, sizeof user, " tktuser %s", tkt_user);
                    297:                                        xfree(tkt_user);
                    298:                                }
                    299:                        }
                    300:                        break;
                    301: #endif /* KRB4 */
                    302:
                    303:                case SSH_CMSG_AUTH_RHOSTS:
                    304:                        if (!options.rhosts_authentication) {
                    305:                                verbose("Rhosts authentication disabled.");
                    306:                                break;
                    307:                        }
                    308:                        /*
                    309:                         * Get client user name.  Note that we just have to
                    310:                         * trust the client; this is one reason why rhosts
                    311:                         * authentication is insecure. (Another is
                    312:                         * IP-spoofing on a local network.)
                    313:                         */
                    314:                        client_user = packet_get_string(&ulen);
                    315:                        packet_integrity_check(plen, 4 + ulen, type);
                    316:
                    317:                        /* Try to authenticate using /etc/hosts.equiv and
                    318:                           .rhosts. */
                    319:                        authenticated = auth_rhosts(pw, client_user);
                    320:
                    321:                        snprintf(user, sizeof user, " ruser %s", client_user);
                    322:                        xfree(client_user);
                    323:                        break;
                    324:
                    325:                case SSH_CMSG_AUTH_RHOSTS_RSA:
                    326:                        if (!options.rhosts_rsa_authentication) {
                    327:                                verbose("Rhosts with RSA authentication disabled.");
                    328:                                break;
                    329:                        }
                    330:                        /*
                    331:                         * Get client user name.  Note that we just have to
                    332:                         * trust the client; root on the client machine can
                    333:                         * claim to be any user.
                    334:                         */
                    335:                        client_user = packet_get_string(&ulen);
                    336:
                    337:                        /* Get the client host key. */
                    338:                        client_host_key = RSA_new();
                    339:                        if (client_host_key == NULL)
                    340:                                fatal("RSA_new failed");
                    341:                        client_host_key->e = BN_new();
                    342:                        client_host_key->n = BN_new();
                    343:                        if (client_host_key->e == NULL || client_host_key->n == NULL)
                    344:                                fatal("BN_new failed");
                    345:                        bits = packet_get_int();
                    346:                        packet_get_bignum(client_host_key->e, &elen);
                    347:                        packet_get_bignum(client_host_key->n, &nlen);
                    348:
                    349:                        if (bits != BN_num_bits(client_host_key->n))
                    350:                                error("Warning: keysize mismatch for client_host_key: "
                    351:                                      "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
                    352:                        packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
                    353:
                    354:                        authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
                    355:                        RSA_free(client_host_key);
                    356:
                    357:                        snprintf(user, sizeof user, " ruser %s", client_user);
                    358:                        xfree(client_user);
                    359:                        break;
                    360:
                    361:                case SSH_CMSG_AUTH_RSA:
                    362:                        if (!options.rsa_authentication) {
                    363:                                verbose("RSA authentication disabled.");
                    364:                                break;
                    365:                        }
                    366:                        /* RSA authentication requested. */
                    367:                        n = BN_new();
                    368:                        packet_get_bignum(n, &nlen);
                    369:                        packet_integrity_check(plen, nlen, type);
                    370:                        authenticated = auth_rsa(pw, n);
                    371:                        BN_clear_free(n);
                    372:                        break;
                    373:
                    374:                case SSH_CMSG_AUTH_PASSWORD:
                    375:                        if (!options.password_authentication) {
                    376:                                verbose("Password authentication disabled.");
                    377:                                break;
                    378:                        }
                    379:                        /*
                    380:                         * Read user password.  It is in plain text, but was
                    381:                         * transmitted over the encrypted channel so it is
                    382:                         * not visible to an outside observer.
                    383:                         */
                    384:                        password = packet_get_string(&dlen);
                    385:                        packet_integrity_check(plen, 4 + dlen, type);
                    386:
                    387:                        /* Try authentication with the password. */
                    388:                        authenticated = auth_password(pw, password);
                    389:
                    390:                        memset(password, 0, strlen(password));
                    391:                        xfree(password);
                    392:                        break;
                    393:
                    394: #ifdef SKEY
                    395:                case SSH_CMSG_AUTH_TIS:
                    396:                        debug("rcvd SSH_CMSG_AUTH_TIS");
                    397:                        if (options.skey_authentication == 1) {
                    398:                                char *skeyinfo = skey_keyinfo(pw->pw_name);
                    399:                                if (skeyinfo == NULL) {
                    400:                                        debug("generating fake skeyinfo for %.100s.", pw->pw_name);
                    401:                                        skeyinfo = skey_fake_keyinfo(pw->pw_name);
                    402:                                }
                    403:                                if (skeyinfo != NULL) {
                    404:                                        /* we send our s/key- in tis-challenge messages */
                    405:                                        debug("sending challenge '%s'", skeyinfo);
                    406:                                        packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                    407:                                        packet_put_string(skeyinfo, strlen(skeyinfo));
                    408:                                        packet_send();
                    409:                                        packet_write_wait();
                    410:                                        continue;
                    411:                                }
                    412:                        }
                    413:                        break;
                    414:                case SSH_CMSG_AUTH_TIS_RESPONSE:
                    415:                        debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
                    416:                        if (options.skey_authentication == 1) {
                    417:                                char *response = packet_get_string(&dlen);
                    418:                                debug("skey response == '%s'", response);
                    419:                                packet_integrity_check(plen, 4 + dlen, type);
                    420:                                authenticated = (skey_haskey(pw->pw_name) == 0 &&
                    421:                                                 skey_passcheck(pw->pw_name, response) != -1);
                    422:                                xfree(response);
                    423:                        }
                    424:                        break;
                    425: #else
                    426:                case SSH_CMSG_AUTH_TIS:
                    427:                        /* TIS Authentication is unsupported */
                    428:                        log("TIS authentication unsupported.");
                    429:                        break;
                    430: #endif
                    431:
                    432:                default:
                    433:                        /*
                    434:                         * Any unknown messages will be ignored (and failure
                    435:                         * returned) during authentication.
                    436:                         */
                    437:                        log("Unknown message during authentication: type %d", type);
                    438:                        break;
                    439:                }
                    440:
                    441:                /*
                    442:                 * Check if the user is logging in as root and root logins
                    443:                 * are disallowed.
                    444:                 * Note that root login is allowed for forced commands.
                    445:                 */
                    446:                if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
                    447:                        if (forced_command) {
                    448:                                log("Root login accepted for forced command.");
                    449:                        } else {
                    450:                                authenticated = 0;
                    451:                                log("ROOT LOGIN REFUSED FROM %.200s",
                    452:                                    get_canonical_hostname());
                    453:                        }
                    454:                }
                    455:
                    456:                /* Raise logging level */
                    457:                if (authenticated ||
                    458:                    attempt == AUTH_FAIL_LOG ||
                    459:                    type == SSH_CMSG_AUTH_PASSWORD)
                    460:                        authlog = log;
                    461:
                    462:                authlog("%s %s for %.200s from %.200s port %d%s",
                    463:                        authenticated ? "Accepted" : "Failed",
                    464:                        get_authname(type),
                    465:                        pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
                    466:                        get_remote_ipaddr(),
                    467:                        get_remote_port(),
                    468:                        user);
                    469:
                    470:                if (authenticated)
                    471:                        return;
                    472:
                    473:                if (attempt > AUTH_FAIL_MAX)
                    474:                        packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
                    475:
                    476:                /* Send a message indicating that the authentication attempt failed. */
                    477:                packet_start(SSH_SMSG_FAILURE);
                    478:                packet_send();
                    479:                packet_write_wait();
                    480:        }
                    481: }
                    482:
                    483: /*
                    484:  * Performs authentication of an incoming connection.  Session key has already
                    485:  * been exchanged and encryption is enabled.
                    486:  */
                    487: void
                    488: do_authentication()
                    489: {
                    490:        struct passwd *pw, pwcopy;
                    491:        int plen;
                    492:        unsigned int ulen;
                    493:        char *user;
                    494:
                    495:        /* Get the name of the user that we wish to log in as. */
                    496:        packet_read_expect(&plen, SSH_CMSG_USER);
                    497:
                    498:        /* Get the user name. */
                    499:        user = packet_get_string(&ulen);
                    500:        packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
                    501:
                    502:        setproctitle("%s", user);
                    503:
                    504: #ifdef AFS
                    505:        /* If machine has AFS, set process authentication group. */
                    506:        if (k_hasafs()) {
                    507:                k_setpag();
                    508:                k_unlog();
                    509:        }
                    510: #endif /* AFS */
                    511:
                    512:        /* Verify that the user is a valid user. */
                    513:        pw = getpwnam(user);
                    514:        if (!pw || !allowed_user(pw))
                    515:                do_fake_authloop1(user);
                    516:        xfree(user);
                    517:
                    518:        /* Take a copy of the returned structure. */
                    519:        memset(&pwcopy, 0, sizeof(pwcopy));
                    520:        pwcopy.pw_name = xstrdup(pw->pw_name);
                    521:        pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
                    522:        pwcopy.pw_uid = pw->pw_uid;
                    523:        pwcopy.pw_gid = pw->pw_gid;
                    524:        pwcopy.pw_dir = xstrdup(pw->pw_dir);
                    525:        pwcopy.pw_shell = xstrdup(pw->pw_shell);
                    526:        pw = &pwcopy;
                    527:
                    528:        /*
                    529:         * If we are not running as root, the user must have the same uid as
                    530:         * the server.
                    531:         */
                    532:        if (getuid() != 0 && pw->pw_uid != getuid())
                    533:                packet_disconnect("Cannot change user when server not running as root.");
                    534:
                    535:        debug("Attempting authentication for %.100s.", pw->pw_name);
                    536:
                    537:        /* If the user has no password, accept authentication immediately. */
                    538:        if (options.password_authentication &&
                    539: #ifdef KRB4
                    540:            (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
                    541: #endif /* KRB4 */
                    542:            auth_password(pw, "")) {
                    543:                /* Authentication with empty password succeeded. */
                    544:                log("Login for user %s from %.100s, accepted without authentication.",
                    545:                    pw->pw_name, get_remote_ipaddr());
                    546:        } else {
                    547:                /* Loop until the user has been authenticated or the
                    548:                   connection is closed, do_authloop() returns only if
                    549:                   authentication is successfull */
                    550:                do_authloop(pw);
                    551:        }
                    552:
                    553:        /* The user has been authenticated and accepted. */
                    554:        packet_start(SSH_SMSG_SUCCESS);
                    555:        packet_send();
                    556:        packet_write_wait();
                    557:
                    558:        /* Perform session preparation. */
                    559:        do_authenticated(pw);
1.2     ! markus    560: }
        !           561:
        !           562:
        !           563: void input_service_request(int type, int plen);
        !           564: void input_userauth_request(int type, int plen);
        !           565: void ssh2_pty_cleanup(void);
        !           566:
        !           567: typedef struct Authctxt Authctxt;
        !           568: struct Authctxt {
        !           569:        char *user;
        !           570:        char *service;
        !           571:        struct passwd pw;
        !           572:        int valid;
        !           573: };
        !           574: static Authctxt        *authctxt = NULL;
        !           575: static int userauth_success = 0;
        !           576:
        !           577: struct passwd*
        !           578: auth_get_user(void)
        !           579: {
        !           580:        return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
        !           581: }
        !           582: struct passwd*
        !           583: auth_set_user(char *u, char *s)
        !           584: {
        !           585:        struct passwd *pw, *copy;
        !           586:
        !           587:        if (authctxt == NULL) {
        !           588:                authctxt = xmalloc(sizeof(*authctxt));
        !           589:                authctxt->valid = 0;
        !           590:                authctxt->user = xstrdup(u);
        !           591:                authctxt->service = xstrdup(s);
        !           592:                setproctitle("%s", u);
        !           593:                pw = getpwnam(u);
        !           594:                if (!pw || !allowed_user(pw)) {
        !           595:                        log("auth_set_user: bad user %s", u);
        !           596:                        return NULL;
        !           597:                }
        !           598:                copy = &authctxt->pw;
        !           599:                memset(copy, 0, sizeof(*copy));
        !           600:                copy->pw_name = xstrdup(pw->pw_name);
        !           601:                copy->pw_passwd = xstrdup(pw->pw_passwd);
        !           602:                copy->pw_uid = pw->pw_uid;
        !           603:                copy->pw_gid = pw->pw_gid;
        !           604:                copy->pw_dir = xstrdup(pw->pw_dir);
        !           605:                copy->pw_shell = xstrdup(pw->pw_shell);
        !           606:                authctxt->valid = 1;
        !           607:        } else {
        !           608:                if (strcmp(u, authctxt->user) != 0 ||
        !           609:                    strcmp(s, authctxt->service) != 0) {
        !           610:                        log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
        !           611:                            u, s, authctxt->user, authctxt->service);
        !           612:                        return NULL;
        !           613:                }
        !           614:        }
        !           615:        return auth_get_user();
        !           616: }
        !           617:
        !           618: static void
        !           619: protocol_error(int type, int plen)
        !           620: {
        !           621:        log("auth: protocol error: type %d plen %d", type, plen);
        !           622:        packet_start(SSH2_MSG_UNIMPLEMENTED);
        !           623:        packet_put_int(0);
        !           624:        packet_send();
        !           625:        packet_write_wait();
        !           626: }
        !           627: void
        !           628: input_service_request(int type, int plen)
        !           629: {
        !           630:        unsigned int len;
        !           631:        int accept = 0;
        !           632:        char *service = packet_get_string(&len);
        !           633:
        !           634:        if (strcmp(service, "ssh-userauth") == 0) {
        !           635:                if (!userauth_success) {
        !           636:                        accept = 1;
        !           637:                        /* now we can handle user-auth requests */
        !           638:                        dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
        !           639:                }
        !           640:        }
        !           641:        /* XXX all other service requests are denied */
        !           642:
        !           643:        if (accept) {
        !           644:                packet_start(SSH2_MSG_SERVICE_ACCEPT);
        !           645:                packet_put_cstring(service);
        !           646:                packet_send();
        !           647:                packet_write_wait();
        !           648:        } else {
        !           649:                debug("bad service request %s", service);
        !           650:                packet_disconnect("bad service request %s", service);
        !           651:        }
        !           652:        xfree(service);
        !           653: }
        !           654: void
        !           655: input_userauth_request(int type, int plen)
        !           656: {
        !           657:        static int try = 0;
        !           658:        unsigned int len;
        !           659:        int c, authenticated = 0;
        !           660:        char *user, *service, *method;
        !           661:        struct passwd *pw;
        !           662:
        !           663:        if (++try == AUTH_FAIL_MAX)
        !           664:                packet_disconnect("too many failed userauth_requests");
        !           665:
        !           666:        user = packet_get_string(&len);
        !           667:        service = packet_get_string(&len);
        !           668:        method = packet_get_string(&len);
        !           669:        debug("userauth-request for user %s service %s method %s", user, service, method);
        !           670:
        !           671:        /* XXX we only allow the ssh-connection service */
        !           672:        pw = auth_set_user(user, service);
        !           673:        if (pw && strcmp(service, "ssh-connection")==0) {
        !           674:                if (strcmp(method, "none") == 0 && try == 1) {
        !           675:                        authenticated = auth_password(pw, "");
        !           676:                } else if (strcmp(method, "password") == 0) {
        !           677:                        char *password;
        !           678:                        c = packet_get_char();
        !           679:                        if (c)
        !           680:                                debug("password change not supported");
        !           681:                        password = packet_get_string(&len);
        !           682:                        authenticated = auth_password(pw, password);
        !           683:                        memset(password, 0, len);
        !           684:                        xfree(password);
        !           685:                } else if (strcmp(method, "publickey") == 0) {
        !           686:                        /* XXX TODO */
        !           687:                        char *pkalg;
        !           688:                        char *pkblob;
        !           689:                        c = packet_get_char();
        !           690:                        pkalg = packet_get_string(&len);
        !           691:                        pkblob = packet_get_string(&len);
        !           692:                        xfree(pkalg);
        !           693:                        xfree(pkblob);
        !           694:                }
        !           695:        }
        !           696:        /* XXX check if other auth methods are needed */
        !           697:        if (authenticated) {
        !           698:                /* turn off userauth */
        !           699:                dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
        !           700:                /* success! */
        !           701:                packet_start(SSH2_MSG_USERAUTH_SUCCESS);
        !           702:                packet_send();
        !           703:                packet_write_wait();
        !           704:                log("userauth success for %s", user);
        !           705:                /* now we can break out */
        !           706:                userauth_success = 1;
        !           707:        } else {
        !           708:                packet_start(SSH2_MSG_USERAUTH_FAILURE);
        !           709:                packet_put_cstring("password");
        !           710:                packet_put_char(0);             /* partial success */
        !           711:                packet_send();
        !           712:                packet_write_wait();
        !           713:        }
        !           714:        xfree(service);
        !           715:        xfree(user);
        !           716:        xfree(method);
        !           717: }
        !           718: void
        !           719: do_authentication2()
        !           720: {
        !           721:        dispatch_init(&protocol_error);
        !           722:        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
        !           723:        dispatch_run(DISPATCH_BLOCK, &userauth_success);
        !           724:        do_authenticated2();
1.1       markus    725: }