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

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.5     ! markus      8: RCSID("$OpenBSD: auth.c,v 1.4 2000/04/14 10:30:29 markus Exp $");
        !             9:
        !            10: #include <openssl/dsa.h>
        !            11: #include <openssl/rsa.h>
        !            12: #include <openssl/evp.h>
1.1       markus     13:
                     14: #include "xmalloc.h"
                     15: #include "rsa.h"
                     16: #include "ssh.h"
                     17: #include "pty.h"
                     18: #include "packet.h"
                     19: #include "buffer.h"
                     20: #include "cipher.h"
                     21: #include "mpaux.h"
                     22: #include "servconf.h"
1.2       markus     23: #include "compat.h"
1.1       markus     24: #include "channels.h"
                     25: #include "match.h"
1.2       markus     26: #include "bufaux.h"
                     27: #include "ssh2.h"
                     28: #include "auth.h"
1.1       markus     29: #include "session.h"
                     30: #include "dispatch.h"
                     31:
1.5     ! markus     32: #include "key.h"
        !            33: #include "kex.h"
        !            34: #include "dsa.h"
        !            35: #include "uidswap.h"
        !            36: #include "channels.h"
1.2       markus     37:
1.1       markus     38: /* import */
                     39: extern ServerOptions options;
                     40: extern char *forced_command;
                     41:
                     42: /*
                     43:  * Check if the user is allowed to log in via ssh. If user is listed in
                     44:  * DenyUsers or user's primary group is listed in DenyGroups, false will
                     45:  * be returned. If AllowUsers isn't empty and user isn't listed there, or
                     46:  * if AllowGroups isn't empty and user isn't listed there, false will be
1.4       markus     47:  * returned.
1.1       markus     48:  * If the user's shell is not executable, false will be returned.
1.4       markus     49:  * Otherwise true is returned.
1.1       markus     50:  */
1.5     ! markus     51: int
1.1       markus     52: allowed_user(struct passwd * pw)
                     53: {
                     54:        struct stat st;
                     55:        struct group *grp;
                     56:        int i;
                     57:
                     58:        /* Shouldn't be called if pw is NULL, but better safe than sorry... */
                     59:        if (!pw)
                     60:                return 0;
                     61:
                     62:        /* deny if shell does not exists or is not executable */
                     63:        if (stat(pw->pw_shell, &st) != 0)
                     64:                return 0;
                     65:        if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
                     66:                return 0;
                     67:
                     68:        /* Return false if user is listed in DenyUsers */
                     69:        if (options.num_deny_users > 0) {
                     70:                if (!pw->pw_name)
                     71:                        return 0;
                     72:                for (i = 0; i < options.num_deny_users; i++)
                     73:                        if (match_pattern(pw->pw_name, options.deny_users[i]))
                     74:                                return 0;
                     75:        }
                     76:        /* Return false if AllowUsers isn't empty and user isn't listed there */
                     77:        if (options.num_allow_users > 0) {
                     78:                if (!pw->pw_name)
                     79:                        return 0;
                     80:                for (i = 0; i < options.num_allow_users; i++)
                     81:                        if (match_pattern(pw->pw_name, options.allow_users[i]))
                     82:                                break;
                     83:                /* i < options.num_allow_users iff we break for loop */
                     84:                if (i >= options.num_allow_users)
                     85:                        return 0;
                     86:        }
                     87:        /* Get the primary group name if we need it. Return false if it fails */
                     88:        if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
                     89:                grp = getgrgid(pw->pw_gid);
                     90:                if (!grp)
                     91:                        return 0;
                     92:
                     93:                /* Return false if user's group is listed in DenyGroups */
                     94:                if (options.num_deny_groups > 0) {
                     95:                        if (!grp->gr_name)
                     96:                                return 0;
                     97:                        for (i = 0; i < options.num_deny_groups; i++)
                     98:                                if (match_pattern(grp->gr_name, options.deny_groups[i]))
                     99:                                        return 0;
                    100:                }
                    101:                /*
                    102:                 * Return false if AllowGroups isn't empty and user's group
                    103:                 * isn't listed there
                    104:                 */
                    105:                if (options.num_allow_groups > 0) {
                    106:                        if (!grp->gr_name)
                    107:                                return 0;
                    108:                        for (i = 0; i < options.num_allow_groups; i++)
                    109:                                if (match_pattern(grp->gr_name, options.allow_groups[i]))
                    110:                                        break;
                    111:                        /* i < options.num_allow_groups iff we break for
                    112:                           loop */
                    113:                        if (i >= options.num_allow_groups)
                    114:                                return 0;
                    115:                }
                    116:        }
                    117:        /* We found no reason not to let this user try to log on... */
                    118:        return 1;
                    119: }
                    120:
1.5     ! markus    121: /* import */
        !           122: extern ServerOptions options;
        !           123: extern char *forced_command;
        !           124:
1.1       markus    125: /*
                    126:  * convert ssh auth msg type into description
                    127:  */
                    128: char *
                    129: get_authname(int type)
                    130: {
                    131:        static char buf[1024];
                    132:        switch (type) {
                    133:        case SSH_CMSG_AUTH_PASSWORD:
                    134:                return "password";
                    135:        case SSH_CMSG_AUTH_RSA:
                    136:                return "rsa";
                    137:        case SSH_CMSG_AUTH_RHOSTS_RSA:
                    138:                return "rhosts-rsa";
                    139:        case SSH_CMSG_AUTH_RHOSTS:
                    140:                return "rhosts";
                    141: #ifdef KRB4
                    142:        case SSH_CMSG_AUTH_KERBEROS:
                    143:                return "kerberos";
                    144: #endif
                    145: #ifdef SKEY
                    146:        case SSH_CMSG_AUTH_TIS_RESPONSE:
                    147:                return "s/key";
                    148: #endif
                    149:        }
                    150:        snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
                    151:        return buf;
                    152: }
                    153:
                    154: #define AUTH_FAIL_MAX 6
                    155: #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
                    156: #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
                    157:
                    158: /*
                    159:  * The user does not exist or access is denied,
                    160:  * but fake indication that authentication is needed.
                    161:  */
                    162: void
                    163: do_fake_authloop1(char *user)
                    164: {
                    165:        int attempt = 0;
                    166:
                    167:        log("Faking authloop for illegal user %.200s from %.200s port %d",
                    168:            user,
                    169:            get_remote_ipaddr(),
                    170:            get_remote_port());
                    171:
                    172:        /* Indicate that authentication is needed. */
                    173:        packet_start(SSH_SMSG_FAILURE);
                    174:        packet_send();
                    175:        packet_write_wait();
                    176:
                    177:        /*
                    178:         * Keep reading packets, and always respond with a failure.  This is
                    179:         * to avoid disclosing whether such a user really exists.
                    180:         */
                    181:        for (attempt = 1;; attempt++) {
                    182:                /* Read a packet.  This will not return if the client disconnects. */
                    183:                int plen;
                    184:                int type = packet_read(&plen);
                    185: #ifdef SKEY
                    186:                unsigned int dlen;
                    187:                char *password, *skeyinfo;
                    188:                password = NULL;
                    189:                /* Try to send a fake s/key challenge. */
                    190:                if (options.skey_authentication == 1 &&
                    191:                    (skeyinfo = skey_fake_keyinfo(user)) != NULL) {
                    192:                        if (type == SSH_CMSG_AUTH_TIS) {
                    193:                                packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                    194:                                packet_put_string(skeyinfo, strlen(skeyinfo));
                    195:                                packet_send();
                    196:                                packet_write_wait();
                    197:                                continue;
                    198:                        } else if (type == SSH_CMSG_AUTH_PASSWORD &&
1.4       markus    199:                                   options.password_authentication &&
                    200:                                   (password = packet_get_string(&dlen)) != NULL &&
                    201:                                   dlen == 5 &&
                    202:                                   strncasecmp(password, "s/key", 5) == 0 ) {
1.1       markus    203:                                packet_send_debug(skeyinfo);
                    204:                        }
                    205:                }
                    206:                if (password != NULL)
                    207:                        xfree(password);
                    208: #endif
                    209:                if (attempt > AUTH_FAIL_MAX)
                    210:                        packet_disconnect(AUTH_FAIL_MSG, user);
                    211:
                    212:                /*
                    213:                 * Send failure.  This should be indistinguishable from a
                    214:                 * failed authentication.
                    215:                 */
                    216:                packet_start(SSH_SMSG_FAILURE);
                    217:                packet_send();
                    218:                packet_write_wait();
                    219:        }
                    220:        /* NOTREACHED */
                    221:        abort();
                    222: }
                    223:
                    224: /*
                    225:  * read packets and try to authenticate local user *pw.
                    226:  * return if authentication is successfull
                    227:  */
                    228: void
                    229: do_authloop(struct passwd * pw)
                    230: {
                    231:        int attempt = 0;
                    232:        unsigned int bits;
                    233:        RSA *client_host_key;
                    234:        BIGNUM *n;
                    235:        char *client_user, *password;
                    236:        char user[1024];
                    237:        unsigned int dlen;
                    238:        int plen, nlen, elen;
                    239:        unsigned int ulen;
                    240:        int type = 0;
                    241:        void (*authlog) (const char *fmt,...) = verbose;
                    242:
                    243:        /* Indicate that authentication is needed. */
                    244:        packet_start(SSH_SMSG_FAILURE);
                    245:        packet_send();
                    246:        packet_write_wait();
                    247:
                    248:        for (attempt = 1;; attempt++) {
                    249:                int authenticated = 0;
                    250:                strlcpy(user, "", sizeof user);
                    251:
                    252:                /* Get a packet from the client. */
                    253:                type = packet_read(&plen);
                    254:
                    255:                /* Process the packet. */
                    256:                switch (type) {
                    257: #ifdef AFS
                    258:                case SSH_CMSG_HAVE_KERBEROS_TGT:
                    259:                        if (!options.kerberos_tgt_passing) {
                    260:                                /* packet_get_all(); */
                    261:                                verbose("Kerberos tgt passing disabled.");
                    262:                                break;
                    263:                        } else {
                    264:                                /* Accept Kerberos tgt. */
                    265:                                char *tgt = packet_get_string(&dlen);
                    266:                                packet_integrity_check(plen, 4 + dlen, type);
                    267:                                if (!auth_kerberos_tgt(pw, tgt))
                    268:                                        verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
                    269:                                xfree(tgt);
                    270:                        }
                    271:                        continue;
                    272:
                    273:                case SSH_CMSG_HAVE_AFS_TOKEN:
                    274:                        if (!options.afs_token_passing || !k_hasafs()) {
                    275:                                /* packet_get_all(); */
                    276:                                verbose("AFS token passing disabled.");
                    277:                                break;
                    278:                        } else {
                    279:                                /* Accept AFS token. */
                    280:                                char *token_string = packet_get_string(&dlen);
                    281:                                packet_integrity_check(plen, 4 + dlen, type);
                    282:                                if (!auth_afs_token(pw, token_string))
                    283:                                        verbose("AFS token REFUSED for %s", pw->pw_name);
                    284:                                xfree(token_string);
                    285:                        }
                    286:                        continue;
                    287: #endif /* AFS */
                    288: #ifdef KRB4
                    289:                case SSH_CMSG_AUTH_KERBEROS:
                    290:                        if (!options.kerberos_authentication) {
                    291:                                /* packet_get_all(); */
                    292:                                verbose("Kerberos authentication disabled.");
                    293:                                break;
                    294:                        } else {
                    295:                                /* Try Kerberos v4 authentication. */
                    296:                                KTEXT_ST auth;
                    297:                                char *tkt_user = NULL;
                    298:                                char *kdata = packet_get_string((unsigned int *) &auth.length);
                    299:                                packet_integrity_check(plen, 4 + auth.length, type);
                    300:
                    301:                                if (auth.length < MAX_KTXT_LEN)
                    302:                                        memcpy(auth.dat, kdata, auth.length);
                    303:                                xfree(kdata);
                    304:
                    305:                                authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
                    306:
                    307:                                if (authenticated) {
                    308:                                        snprintf(user, sizeof user, " tktuser %s", tkt_user);
                    309:                                        xfree(tkt_user);
                    310:                                }
                    311:                        }
                    312:                        break;
                    313: #endif /* KRB4 */
                    314:
                    315:                case SSH_CMSG_AUTH_RHOSTS:
                    316:                        if (!options.rhosts_authentication) {
                    317:                                verbose("Rhosts authentication disabled.");
                    318:                                break;
                    319:                        }
                    320:                        /*
                    321:                         * Get client user name.  Note that we just have to
                    322:                         * trust the client; this is one reason why rhosts
                    323:                         * authentication is insecure. (Another is
                    324:                         * IP-spoofing on a local network.)
                    325:                         */
                    326:                        client_user = packet_get_string(&ulen);
                    327:                        packet_integrity_check(plen, 4 + ulen, type);
                    328:
                    329:                        /* Try to authenticate using /etc/hosts.equiv and
                    330:                           .rhosts. */
                    331:                        authenticated = auth_rhosts(pw, client_user);
                    332:
                    333:                        snprintf(user, sizeof user, " ruser %s", client_user);
                    334:                        xfree(client_user);
                    335:                        break;
                    336:
                    337:                case SSH_CMSG_AUTH_RHOSTS_RSA:
                    338:                        if (!options.rhosts_rsa_authentication) {
                    339:                                verbose("Rhosts with RSA authentication disabled.");
                    340:                                break;
                    341:                        }
                    342:                        /*
                    343:                         * Get client user name.  Note that we just have to
                    344:                         * trust the client; root on the client machine can
                    345:                         * claim to be any user.
                    346:                         */
                    347:                        client_user = packet_get_string(&ulen);
                    348:
                    349:                        /* Get the client host key. */
                    350:                        client_host_key = RSA_new();
                    351:                        if (client_host_key == NULL)
                    352:                                fatal("RSA_new failed");
                    353:                        client_host_key->e = BN_new();
                    354:                        client_host_key->n = BN_new();
                    355:                        if (client_host_key->e == NULL || client_host_key->n == NULL)
                    356:                                fatal("BN_new failed");
                    357:                        bits = packet_get_int();
                    358:                        packet_get_bignum(client_host_key->e, &elen);
                    359:                        packet_get_bignum(client_host_key->n, &nlen);
                    360:
                    361:                        if (bits != BN_num_bits(client_host_key->n))
                    362:                                error("Warning: keysize mismatch for client_host_key: "
                    363:                                      "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
                    364:                        packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
                    365:
                    366:                        authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
                    367:                        RSA_free(client_host_key);
                    368:
                    369:                        snprintf(user, sizeof user, " ruser %s", client_user);
                    370:                        xfree(client_user);
                    371:                        break;
                    372:
                    373:                case SSH_CMSG_AUTH_RSA:
                    374:                        if (!options.rsa_authentication) {
                    375:                                verbose("RSA authentication disabled.");
                    376:                                break;
                    377:                        }
                    378:                        /* RSA authentication requested. */
                    379:                        n = BN_new();
                    380:                        packet_get_bignum(n, &nlen);
                    381:                        packet_integrity_check(plen, nlen, type);
                    382:                        authenticated = auth_rsa(pw, n);
                    383:                        BN_clear_free(n);
                    384:                        break;
                    385:
                    386:                case SSH_CMSG_AUTH_PASSWORD:
                    387:                        if (!options.password_authentication) {
                    388:                                verbose("Password authentication disabled.");
                    389:                                break;
                    390:                        }
                    391:                        /*
                    392:                         * Read user password.  It is in plain text, but was
                    393:                         * transmitted over the encrypted channel so it is
                    394:                         * not visible to an outside observer.
                    395:                         */
                    396:                        password = packet_get_string(&dlen);
                    397:                        packet_integrity_check(plen, 4 + dlen, type);
                    398:
                    399:                        /* Try authentication with the password. */
                    400:                        authenticated = auth_password(pw, password);
                    401:
                    402:                        memset(password, 0, strlen(password));
                    403:                        xfree(password);
                    404:                        break;
                    405:
                    406: #ifdef SKEY
                    407:                case SSH_CMSG_AUTH_TIS:
                    408:                        debug("rcvd SSH_CMSG_AUTH_TIS");
                    409:                        if (options.skey_authentication == 1) {
                    410:                                char *skeyinfo = skey_keyinfo(pw->pw_name);
                    411:                                if (skeyinfo == NULL) {
                    412:                                        debug("generating fake skeyinfo for %.100s.", pw->pw_name);
                    413:                                        skeyinfo = skey_fake_keyinfo(pw->pw_name);
                    414:                                }
                    415:                                if (skeyinfo != NULL) {
                    416:                                        /* we send our s/key- in tis-challenge messages */
                    417:                                        debug("sending challenge '%s'", skeyinfo);
                    418:                                        packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
                    419:                                        packet_put_string(skeyinfo, strlen(skeyinfo));
                    420:                                        packet_send();
                    421:                                        packet_write_wait();
                    422:                                        continue;
                    423:                                }
                    424:                        }
                    425:                        break;
                    426:                case SSH_CMSG_AUTH_TIS_RESPONSE:
                    427:                        debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
                    428:                        if (options.skey_authentication == 1) {
                    429:                                char *response = packet_get_string(&dlen);
                    430:                                debug("skey response == '%s'", response);
                    431:                                packet_integrity_check(plen, 4 + dlen, type);
                    432:                                authenticated = (skey_haskey(pw->pw_name) == 0 &&
                    433:                                                 skey_passcheck(pw->pw_name, response) != -1);
                    434:                                xfree(response);
                    435:                        }
                    436:                        break;
                    437: #else
                    438:                case SSH_CMSG_AUTH_TIS:
                    439:                        /* TIS Authentication is unsupported */
                    440:                        log("TIS authentication unsupported.");
                    441:                        break;
                    442: #endif
                    443:
                    444:                default:
                    445:                        /*
                    446:                         * Any unknown messages will be ignored (and failure
                    447:                         * returned) during authentication.
                    448:                         */
                    449:                        log("Unknown message during authentication: type %d", type);
                    450:                        break;
                    451:                }
1.4       markus    452:
                    453:                /*
                    454:                 * Check if the user is logging in as root and root logins
                    455:                 * are disallowed.
                    456:                 * Note that root login is allowed for forced commands.
                    457:                 */
                    458:                if (authenticated && pw->pw_uid == 0 && !options.permit_root_login) {
                    459:                        if (forced_command) {
                    460:                                log("Root login accepted for forced command.");
                    461:                        } else {
                    462:                                authenticated = 0;
                    463:                                log("ROOT LOGIN REFUSED FROM %.200s",
                    464:                                    get_canonical_hostname());
                    465:                        }
                    466:                }
1.1       markus    467:
                    468:                /* Raise logging level */
                    469:                if (authenticated ||
                    470:                    attempt == AUTH_FAIL_LOG ||
                    471:                    type == SSH_CMSG_AUTH_PASSWORD)
                    472:                        authlog = log;
                    473:
                    474:                authlog("%s %s for %.200s from %.200s port %d%s",
                    475:                        authenticated ? "Accepted" : "Failed",
                    476:                        get_authname(type),
                    477:                        pw->pw_uid == 0 ? "ROOT" : pw->pw_name,
                    478:                        get_remote_ipaddr(),
                    479:                        get_remote_port(),
                    480:                        user);
                    481:
                    482:                if (authenticated)
                    483:                        return;
                    484:
                    485:                if (attempt > AUTH_FAIL_MAX)
                    486:                        packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
                    487:
                    488:                /* Send a message indicating that the authentication attempt failed. */
                    489:                packet_start(SSH_SMSG_FAILURE);
                    490:                packet_send();
                    491:                packet_write_wait();
                    492:        }
                    493: }
                    494:
                    495: /*
                    496:  * Performs authentication of an incoming connection.  Session key has already
                    497:  * been exchanged and encryption is enabled.
                    498:  */
                    499: void
                    500: do_authentication()
                    501: {
                    502:        struct passwd *pw, pwcopy;
                    503:        int plen;
                    504:        unsigned int ulen;
                    505:        char *user;
                    506:
                    507:        /* Get the name of the user that we wish to log in as. */
                    508:        packet_read_expect(&plen, SSH_CMSG_USER);
                    509:
                    510:        /* Get the user name. */
                    511:        user = packet_get_string(&ulen);
                    512:        packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
                    513:
                    514:        setproctitle("%s", user);
                    515:
                    516: #ifdef AFS
                    517:        /* If machine has AFS, set process authentication group. */
                    518:        if (k_hasafs()) {
                    519:                k_setpag();
                    520:                k_unlog();
                    521:        }
                    522: #endif /* AFS */
                    523:
                    524:        /* Verify that the user is a valid user. */
                    525:        pw = getpwnam(user);
                    526:        if (!pw || !allowed_user(pw))
                    527:                do_fake_authloop1(user);
                    528:        xfree(user);
                    529:
                    530:        /* Take a copy of the returned structure. */
                    531:        memset(&pwcopy, 0, sizeof(pwcopy));
                    532:        pwcopy.pw_name = xstrdup(pw->pw_name);
                    533:        pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
                    534:        pwcopy.pw_uid = pw->pw_uid;
                    535:        pwcopy.pw_gid = pw->pw_gid;
                    536:        pwcopy.pw_dir = xstrdup(pw->pw_dir);
                    537:        pwcopy.pw_shell = xstrdup(pw->pw_shell);
                    538:        pw = &pwcopy;
                    539:
                    540:        /*
                    541:         * If we are not running as root, the user must have the same uid as
                    542:         * the server.
                    543:         */
                    544:        if (getuid() != 0 && pw->pw_uid != getuid())
                    545:                packet_disconnect("Cannot change user when server not running as root.");
                    546:
                    547:        debug("Attempting authentication for %.100s.", pw->pw_name);
                    548:
                    549:        /* If the user has no password, accept authentication immediately. */
                    550:        if (options.password_authentication &&
                    551: #ifdef KRB4
                    552:            (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
                    553: #endif /* KRB4 */
                    554:            auth_password(pw, "")) {
                    555:                /* Authentication with empty password succeeded. */
                    556:                log("Login for user %s from %.100s, accepted without authentication.",
                    557:                    pw->pw_name, get_remote_ipaddr());
                    558:        } else {
                    559:                /* Loop until the user has been authenticated or the
                    560:                   connection is closed, do_authloop() returns only if
                    561:                   authentication is successfull */
                    562:                do_authloop(pw);
                    563:        }
                    564:
                    565:        /* The user has been authenticated and accepted. */
                    566:        packet_start(SSH_SMSG_SUCCESS);
                    567:        packet_send();
                    568:        packet_write_wait();
                    569:
                    570:        /* Perform session preparation. */
                    571:        do_authenticated(pw);
1.2       markus    572: }
                    573:
1.5     ! markus    574: /* import */
        !           575: extern ServerOptions options;
        !           576: extern unsigned char *session_id2;
        !           577: extern int session_id2_len;
        !           578:
        !           579: /* protocol */
1.2       markus    580:
1.5     ! markus    581: void   input_service_request(int type, int plen);
        !           582: void   input_userauth_request(int type, int plen);
        !           583: void   protocol_error(int type, int plen);
        !           584:
        !           585: /* auth */
        !           586: int    ssh2_auth_none(struct passwd *pw);
        !           587: int    ssh2_auth_password(struct passwd *pw);
        !           588: int    ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen);
        !           589:
        !           590: /* helper */
        !           591: struct passwd*  auth_set_user(char *u, char *s);
        !           592: int    user_dsa_key_allowed(struct passwd *pw, Key *key);
1.2       markus    593:
                    594: typedef struct Authctxt Authctxt;
                    595: struct Authctxt {
                    596:        char *user;
                    597:        char *service;
                    598:        struct passwd pw;
                    599:        int valid;
                    600: };
                    601: static Authctxt        *authctxt = NULL;
                    602: static int userauth_success = 0;
                    603:
1.5     ! markus    604: /* set and get current user */
        !           605:
1.2       markus    606: struct passwd*
                    607: auth_get_user(void)
                    608: {
                    609:        return (authctxt != NULL && authctxt->valid) ? &authctxt->pw : NULL;
                    610: }
1.5     ! markus    611:
1.2       markus    612: struct passwd*
                    613: auth_set_user(char *u, char *s)
                    614: {
                    615:        struct passwd *pw, *copy;
                    616:
                    617:        if (authctxt == NULL) {
                    618:                authctxt = xmalloc(sizeof(*authctxt));
                    619:                authctxt->valid = 0;
                    620:                authctxt->user = xstrdup(u);
                    621:                authctxt->service = xstrdup(s);
                    622:                setproctitle("%s", u);
                    623:                pw = getpwnam(u);
                    624:                if (!pw || !allowed_user(pw)) {
                    625:                        log("auth_set_user: bad user %s", u);
                    626:                        return NULL;
                    627:                }
                    628:                copy = &authctxt->pw;
                    629:                memset(copy, 0, sizeof(*copy));
                    630:                copy->pw_name = xstrdup(pw->pw_name);
                    631:                copy->pw_passwd = xstrdup(pw->pw_passwd);
                    632:                copy->pw_uid = pw->pw_uid;
                    633:                copy->pw_gid = pw->pw_gid;
                    634:                copy->pw_dir = xstrdup(pw->pw_dir);
                    635:                copy->pw_shell = xstrdup(pw->pw_shell);
                    636:                authctxt->valid = 1;
                    637:        } else {
                    638:                if (strcmp(u, authctxt->user) != 0 ||
                    639:                    strcmp(s, authctxt->service) != 0) {
                    640:                        log("auth_set_user: missmatch: (%s,%s)!=(%s,%s)",
                    641:                            u, s, authctxt->user, authctxt->service);
                    642:                        return NULL;
                    643:                }
                    644:        }
                    645:        return auth_get_user();
                    646: }
                    647:
1.5     ! markus    648: /*
        !           649:  * loop until userauth_success == TRUE
        !           650:  */
        !           651:
        !           652: void
        !           653: do_authentication2()
        !           654: {
        !           655:        dispatch_init(&protocol_error);
        !           656:        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
        !           657:        dispatch_run(DISPATCH_BLOCK, &userauth_success);
        !           658:        do_authenticated2();
        !           659: }
        !           660:
        !           661: void
1.2       markus    662: protocol_error(int type, int plen)
                    663: {
                    664:        log("auth: protocol error: type %d plen %d", type, plen);
                    665:        packet_start(SSH2_MSG_UNIMPLEMENTED);
                    666:        packet_put_int(0);
                    667:        packet_send();
                    668:        packet_write_wait();
                    669: }
1.5     ! markus    670:
1.2       markus    671: void
                    672: input_service_request(int type, int plen)
                    673: {
                    674:        unsigned int len;
                    675:        int accept = 0;
                    676:        char *service = packet_get_string(&len);
1.3       markus    677:        packet_done();
1.2       markus    678:
                    679:        if (strcmp(service, "ssh-userauth") == 0) {
                    680:                if (!userauth_success) {
                    681:                        accept = 1;
                    682:                        /* now we can handle user-auth requests */
                    683:                        dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
                    684:                }
                    685:        }
                    686:        /* XXX all other service requests are denied */
                    687:
                    688:        if (accept) {
                    689:                packet_start(SSH2_MSG_SERVICE_ACCEPT);
                    690:                packet_put_cstring(service);
                    691:                packet_send();
                    692:                packet_write_wait();
                    693:        } else {
                    694:                debug("bad service request %s", service);
                    695:                packet_disconnect("bad service request %s", service);
                    696:        }
                    697:        xfree(service);
                    698: }
1.5     ! markus    699:
1.2       markus    700: void
                    701: input_userauth_request(int type, int plen)
                    702: {
                    703:        static int try = 0;
1.5     ! markus    704:        unsigned int len, rlen;
        !           705:        int authenticated = 0;
        !           706:        char *raw, *user, *service, *method;
1.2       markus    707:        struct passwd *pw;
                    708:
                    709:        if (++try == AUTH_FAIL_MAX)
                    710:                packet_disconnect("too many failed userauth_requests");
                    711:
1.5     ! markus    712:        raw = packet_get_raw(&rlen);
        !           713:        if (plen != rlen)
        !           714:                fatal("plen != rlen");
1.2       markus    715:        user = packet_get_string(&len);
                    716:        service = packet_get_string(&len);
                    717:        method = packet_get_string(&len);
                    718:        debug("userauth-request for user %s service %s method %s", user, service, method);
                    719:
                    720:        /* XXX we only allow the ssh-connection service */
                    721:        pw = auth_set_user(user, service);
                    722:        if (pw && strcmp(service, "ssh-connection")==0) {
1.5     ! markus    723:                if (strcmp(method, "none") == 0) {
        !           724:                        authenticated = ssh2_auth_none(pw);
1.2       markus    725:                } else if (strcmp(method, "password") == 0) {
1.5     ! markus    726:                        authenticated = ssh2_auth_password(pw);
1.2       markus    727:                } else if (strcmp(method, "publickey") == 0) {
1.5     ! markus    728:                        authenticated = ssh2_auth_pubkey(pw, raw, rlen);
1.2       markus    729:                }
                    730:        }
                    731:        /* XXX check if other auth methods are needed */
1.5     ! markus    732:        if (authenticated == 1) {
        !           733:                log("userauth success for %s method %s", user, method);
1.2       markus    734:                /* turn off userauth */
                    735:                dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
                    736:                packet_start(SSH2_MSG_USERAUTH_SUCCESS);
                    737:                packet_send();
                    738:                packet_write_wait();
                    739:                /* now we can break out */
                    740:                userauth_success = 1;
1.5     ! markus    741:        } else if (authenticated == 0) {
        !           742:                log("userauth failure for %s method %s", user, method);
1.2       markus    743:                packet_start(SSH2_MSG_USERAUTH_FAILURE);
1.5     ! markus    744:                packet_put_cstring("publickey,password");       /* XXX dynamic */
        !           745:                packet_put_char(0);                             /* XXX partial success, unused */
1.2       markus    746:                packet_send();
                    747:                packet_write_wait();
1.5     ! markus    748:        } else {
        !           749:                log("userauth postponed for %s method %s", user, method);
1.2       markus    750:        }
                    751:        xfree(service);
                    752:        xfree(user);
                    753:        xfree(method);
                    754: }
1.5     ! markus    755:
        !           756: int
        !           757: ssh2_auth_none(struct passwd *pw)
        !           758: {
        !           759:        packet_done();
        !           760:        return auth_password(pw, "");
        !           761: }
        !           762: int
        !           763: ssh2_auth_password(struct passwd *pw)
        !           764: {
        !           765:        char *password;
        !           766:        int authenticated = 0;
        !           767:        int change;
        !           768:        unsigned int len;
        !           769:        change = packet_get_char();
        !           770:        if (change)
        !           771:                log("password change not supported");
        !           772:        password = packet_get_string(&len);
        !           773:        packet_done();
        !           774:        if (auth_password(pw, password))
        !           775:                authenticated = 1;
        !           776:        memset(password, 0, len);
        !           777:        xfree(password);
        !           778:        return authenticated;
        !           779: }
        !           780:
        !           781: int
        !           782: ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen)
1.2       markus    783: {
1.5     ! markus    784:        Buffer b;
        !           785:        Key *key;
        !           786:        char *pkalg, *pkblob, *sig;
        !           787:        unsigned int alen, blen, slen;
        !           788:        int have_sig;
        !           789:        int authenticated = 0;
        !           790:
        !           791:        have_sig = packet_get_char();
        !           792:        pkalg = packet_get_string(&alen);
        !           793:        if (strcmp(pkalg, KEX_DSS) != 0) {
        !           794:                xfree(pkalg);
        !           795:                log("bad pkalg %s", pkalg);     /*XXX*/
        !           796:                return 0;
        !           797:        }
        !           798:        pkblob = packet_get_string(&blen);
        !           799:        key = dsa_key_from_blob(pkblob, blen);
        !           800:
        !           801:        if (have_sig && key != NULL) {
        !           802:                sig = packet_get_string(&slen);
        !           803:                packet_done();
        !           804:                buffer_init(&b);
        !           805:                buffer_append(&b, session_id2, session_id2_len);
        !           806:                buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
        !           807:                if (slen + 4 > rlen)
        !           808:                        fatal("bad rlen/slen");
        !           809:                buffer_append(&b, raw, rlen - slen - 4);
        !           810: #ifdef DEBUG_DSS
        !           811:                buffer_dump(&b);
        !           812: #endif
        !           813:                /* test for correct signature */
        !           814:                if (user_dsa_key_allowed(pw, key) &&
        !           815:                    dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
        !           816:                        authenticated = 1;
        !           817:                buffer_clear(&b);
        !           818:                xfree(sig);
        !           819:        } else if (!have_sig && key != NULL) {
        !           820:                packet_done();
        !           821:                debug("test key...");
        !           822:                /* test whether pkalg/pkblob are acceptable */
        !           823:                /* XXX fake reply and always send PK_OK ? */
        !           824:                if (user_dsa_key_allowed(pw, key)) {
        !           825:                        packet_start(SSH2_MSG_USERAUTH_PK_OK);
        !           826:                        packet_put_string(pkalg, alen);
        !           827:                        packet_put_string(pkblob, blen);
        !           828:                        packet_send();
        !           829:                        packet_write_wait();
        !           830:                        authenticated = -1;
        !           831:                }
        !           832:        }
        !           833:        xfree(pkalg);
        !           834:        xfree(pkblob);
        !           835:        return authenticated;
        !           836: }
        !           837:
        !           838: /* return 1 if user allows given key */
        !           839: int
        !           840: user_dsa_key_allowed(struct passwd *pw, Key *key)
        !           841: {
        !           842:        char line[8192], file[1024];
        !           843:        int found_key = 0;
        !           844:        unsigned int bits = -1;
        !           845:        FILE *f;
        !           846:        unsigned long linenum = 0;
        !           847:        struct stat st;
        !           848:        Key *found;
        !           849:
        !           850:        /* Temporarily use the user's uid. */
        !           851:        temporarily_use_uid(pw->pw_uid);
        !           852:
        !           853:        /* The authorized keys. */
        !           854:        snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
        !           855:            SSH_USER_PERMITTED_KEYS2);
        !           856:
        !           857:        /* Fail quietly if file does not exist */
        !           858:        if (stat(file, &st) < 0) {
        !           859:                /* Restore the privileged uid. */
        !           860:                restore_uid();
        !           861:                return 0;
        !           862:        }
        !           863:        /* Open the file containing the authorized keys. */
        !           864:        f = fopen(file, "r");
        !           865:        if (!f) {
        !           866:                /* Restore the privileged uid. */
        !           867:                restore_uid();
        !           868:                packet_send_debug("Could not open %.900s for reading.", file);
        !           869:                packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
        !           870:                return 0;
        !           871:        }
        !           872:        if (options.strict_modes) {
        !           873:                int fail = 0;
        !           874:                char buf[1024];
        !           875:                /* Check open file in order to avoid open/stat races */
        !           876:                if (fstat(fileno(f), &st) < 0 ||
        !           877:                    (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
        !           878:                    (st.st_mode & 022) != 0) {
        !           879:                        snprintf(buf, sizeof buf, "DSA authentication refused for %.100s: "
        !           880:                            "bad ownership or modes for '%s'.", pw->pw_name, file);
        !           881:                        fail = 1;
        !           882:                } else {
        !           883:                        /* Check path to SSH_USER_PERMITTED_KEYS */
        !           884:                        int i;
        !           885:                        static const char *check[] = {
        !           886:                                "", SSH_USER_DIR, NULL
        !           887:                        };
        !           888:                        for (i = 0; check[i]; i++) {
        !           889:                                snprintf(line, sizeof line, "%.500s/%.100s",
        !           890:                                    pw->pw_dir, check[i]);
        !           891:                                if (stat(line, &st) < 0 ||
        !           892:                                    (st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
        !           893:                                    (st.st_mode & 022) != 0) {
        !           894:                                        snprintf(buf, sizeof buf,
        !           895:                                            "DSA authentication refused for %.100s: "
        !           896:                                            "bad ownership or modes for '%s'.",
        !           897:                                            pw->pw_name, line);
        !           898:                                        fail = 1;
        !           899:                                        break;
        !           900:                                }
        !           901:                        }
        !           902:                }
        !           903:                if (fail) {
        !           904:                        log(buf);
        !           905:                        fclose(f);
        !           906:                        restore_uid();
        !           907:                        return 0;
        !           908:                }
        !           909:        }
        !           910:        found_key = 0;
        !           911:        found = key_new(KEY_DSA);
        !           912:
        !           913:        while (fgets(line, sizeof(line), f)) {
        !           914:                char *cp;
        !           915:                linenum++;
        !           916:                /* Skip leading whitespace, empty and comment lines. */
        !           917:                for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
        !           918:                        ;
        !           919:                if (!*cp || *cp == '\n' || *cp == '#')
        !           920:                        continue;
        !           921:                bits = key_read(found, &cp);
        !           922:                if (bits == 0)
        !           923:                        continue;
        !           924:                if (key_equal(found, key)) {
        !           925:                        found_key = 1;
        !           926:                        debug("matching key found: file %s, line %ld",
        !           927:                            file, linenum);
        !           928:                        break;
        !           929:                }
        !           930:        }
        !           931:        restore_uid();
        !           932:        fclose(f);
        !           933:        key_free(found);
        !           934:        return found_key;
1.1       markus    935: }