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

Annotation of src/usr.bin/ssh/monitor.c, Revision 1.1

1.1     ! provos      1: /*
        !             2:  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
        !             3:  * Copyright 2002 Markus Friedl <markus@openbsd.org>
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            20:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            21:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            22:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            23:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            24:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            25:  */
        !            26:
        !            27: #include "includes.h"
        !            28: RCSID("$OpenBSD$");
        !            29:
        !            30: #include <openssl/dh.h>
        !            31:
        !            32: #ifdef SKEY
        !            33: #include <skey.h>
        !            34: #endif
        !            35:
        !            36: #include "ssh.h"
        !            37: #include "auth.h"
        !            38: #include "kex.h"
        !            39: #include "dh.h"
        !            40: #include "zlib.h"
        !            41: #include "packet.h"
        !            42: #include "auth-options.h"
        !            43: #include "sshpty.h"
        !            44: #include "channels.h"
        !            45: #include "session.h"
        !            46: #include "sshlogin.h"
        !            47: #include "canohost.h"
        !            48: #include "log.h"
        !            49: #include "servconf.h"
        !            50: #include "monitor.h"
        !            51: #include "monitor_mm.h"
        !            52: #include "monitor_wrap.h"
        !            53: #include "monitor_fdpass.h"
        !            54: #include "xmalloc.h"
        !            55: #include "misc.h"
        !            56: #include "buffer.h"
        !            57: #include "bufaux.h"
        !            58: #include "compat.h"
        !            59: #include "ssh2.h"
        !            60: #include "mpaux.h"
        !            61:
        !            62: /* Imports */
        !            63: extern ServerOptions options;
        !            64: extern u_int utmp_len;
        !            65: extern Newkeys *current_keys[];
        !            66: extern z_stream incoming_stream;
        !            67: extern z_stream outgoing_stream;
        !            68: extern u_char session_id[];
        !            69: extern Buffer input, output;
        !            70: extern Buffer auth_debug;
        !            71: extern int auth_debug_init;
        !            72:
        !            73: /* State exported from the child */
        !            74:
        !            75: struct {
        !            76:        z_stream incoming;
        !            77:        z_stream outgoing;
        !            78:        u_char *keyin;
        !            79:        u_int keyinlen;
        !            80:        u_char *keyout;
        !            81:        u_int keyoutlen;
        !            82:        u_char *ivin;
        !            83:        u_int ivinlen;
        !            84:        u_char *ivout;
        !            85:        u_int ivoutlen;
        !            86:        int ssh1cipher;
        !            87:        int ssh1protoflags;
        !            88:        u_char *input;
        !            89:        u_int ilen;
        !            90:        u_char *output;
        !            91:        u_int olen;
        !            92: } child_state;
        !            93:
        !            94: /* Prototypes for request sending and receiving */
        !            95: void mm_request_send(int, enum monitor_reqtype, Buffer *);
        !            96: void mm_request_receive(int, Buffer *);
        !            97: void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *);
        !            98:
        !            99: /* Prototypes for authentication functions */
        !           100: int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
        !           101: int bsdauth_respond(void *, u_int, char **);
        !           102: int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
        !           103: int skey_respond(void *, u_int, char **);
        !           104:
        !           105: int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
        !           106: int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
        !           107: int user_key_allowed(struct passwd *, Key *);
        !           108: Key *get_hostkey_by_index(int);
        !           109: Key *get_hostkey_by_type(int);
        !           110: int get_hostkey_index(Key *);
        !           111: int ssh1_session_key(BIGNUM *);
        !           112: int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
        !           113: int auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
        !           114: BIGNUM *auth_rsa_generate_challenge(Key *);
        !           115:
        !           116: void   session_pty_cleanup2(void *);
        !           117: Session        *session_by_tty(char *);
        !           118:
        !           119: /* Functions on the montior that answer unprivileged requests */
        !           120:
        !           121: int mm_answer_moduli(int, Buffer *);
        !           122: int mm_answer_sign(int, Buffer *);
        !           123: int mm_answer_pwnamallow(int, Buffer *);
        !           124: int mm_answer_authserv(int, Buffer *);
        !           125: int mm_answer_authpassword(int, Buffer *);
        !           126: int mm_answer_bsdauthquery(int, Buffer *);
        !           127: int mm_answer_bsdauthrespond(int, Buffer *);
        !           128: int mm_answer_skeyquery(int, Buffer *);
        !           129: int mm_answer_skeyrespond(int, Buffer *);
        !           130: int mm_answer_keyallowed(int, Buffer *);
        !           131: int mm_answer_keyverify(int, Buffer *);
        !           132: int mm_answer_pty(int, Buffer *);
        !           133: int mm_answer_pty_cleanup(int, Buffer *);
        !           134: int mm_answer_term(int, Buffer *);
        !           135: int mm_answer_rsa_keyallowed(int, Buffer *);
        !           136: int mm_answer_rsa_challenge(int, Buffer *);
        !           137: int mm_answer_rsa_response(int, Buffer *);
        !           138: int mm_answer_sesskey(int, Buffer *);
        !           139: int mm_answer_sessid(int, Buffer *);
        !           140:
        !           141: static Authctxt *authctxt;
        !           142: static BIGNUM *ssh1_challenge = NULL;  /* used for ssh1 rsa auth */
        !           143:
        !           144: /* local state for key verify */
        !           145: static u_char *key_blob = NULL;
        !           146: static u_int key_bloblen = 0;
        !           147: static int key_blobtype = MM_NOKEY;
        !           148: static u_char *hostbased_cuser = NULL;
        !           149: static u_char *hostbased_chost = NULL;
        !           150: static char *auth_method = "unknown";
        !           151:
        !           152: struct mon_table {
        !           153:        enum monitor_reqtype type;
        !           154:        int flags;
        !           155:        int (*f)(int, Buffer *);
        !           156: };
        !           157:
        !           158: #define MON_ISAUTH     0x0004  /* Required for Authentication */
        !           159: #define MON_AUTHDECIDE 0x0008  /* Decides Authentication */
        !           160: #define MON_ONCE       0x0010  /* Disable after calling */
        !           161:
        !           162: #define MON_AUTH       (MON_ISAUTH|MON_AUTHDECIDE)
        !           163:
        !           164: #define MON_PERMIT     0x1000  /* Request is permitted */
        !           165:
        !           166: struct mon_table mon_dispatch_proto20[] = {
        !           167:     {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
        !           168:     {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
        !           169:     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
        !           170:     {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
        !           171:     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
        !           172: #ifdef BSD_AUTH
        !           173:     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
        !           174:     {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
        !           175: #endif
        !           176: #ifdef SKEY
        !           177:     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
        !           178:     {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
        !           179: #endif
        !           180:     {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
        !           181:     {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
        !           182:     {0, 0, NULL}
        !           183: };
        !           184:
        !           185: struct mon_table mon_dispatch_postauth20[] = {
        !           186:     {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
        !           187:     {MONITOR_REQ_SIGN, 0, mm_answer_sign},
        !           188:     {MONITOR_REQ_PTY, 0, mm_answer_pty},
        !           189:     {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
        !           190:     {MONITOR_REQ_TERM, 0, mm_answer_term},
        !           191:     {0, 0, NULL}
        !           192: };
        !           193:
        !           194: struct mon_table mon_dispatch_proto15[] = {
        !           195:     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
        !           196:     {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
        !           197:     {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
        !           198:     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
        !           199:     {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},
        !           200:     {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
        !           201:     {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
        !           202:     {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
        !           203: #ifdef BSD_AUTH
        !           204:     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
        !           205:     {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
        !           206: #endif
        !           207: #ifdef SKEY
        !           208:     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
        !           209:     {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
        !           210: #endif
        !           211:     {0, 0, NULL}
        !           212: };
        !           213:
        !           214: struct mon_table mon_dispatch_postauth15[] = {
        !           215:     {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
        !           216:     {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
        !           217:     {MONITOR_REQ_TERM, 0, mm_answer_term},
        !           218:     {0, 0, NULL}
        !           219: };
        !           220:
        !           221: struct mon_table *mon_dispatch;
        !           222:
        !           223: /* Specifies if a certain message is allowed at the moment */
        !           224:
        !           225: static void
        !           226: monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
        !           227: {
        !           228:        while (ent->f != NULL) {
        !           229:                if (ent->type == type) {
        !           230:                        ent->flags &= ~MON_PERMIT;
        !           231:                        ent->flags |= permit ? MON_PERMIT : 0;
        !           232:                        return;
        !           233:                }
        !           234:                ent++;
        !           235:        }
        !           236: }
        !           237:
        !           238: static void
        !           239: monitor_permit_authentications(int permit)
        !           240: {
        !           241:        struct mon_table *ent = mon_dispatch;
        !           242:
        !           243:        while (ent->f != NULL) {
        !           244:                if (ent->flags & MON_AUTH) {
        !           245:                        ent->flags &= ~MON_PERMIT;
        !           246:                        ent->flags |= permit ? MON_PERMIT : 0;
        !           247:                }
        !           248:                ent++;
        !           249:        }
        !           250: }
        !           251:
        !           252: Authctxt *
        !           253: monitor_child_preauth(struct monitor *monitor)
        !           254: {
        !           255:        struct mon_table *ent;
        !           256:        int authenticated = 0;
        !           257:
        !           258:        debug3("preauth child monitor started");
        !           259:
        !           260:        if (compat20) {
        !           261:                mon_dispatch = mon_dispatch_proto20;
        !           262:
        !           263:                /* Permit requests for moduli and signatures */
        !           264:                monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
        !           265:                monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
        !           266:        } else {
        !           267:                mon_dispatch = mon_dispatch_proto15;
        !           268:
        !           269:                monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
        !           270:        }
        !           271:
        !           272:        authctxt = authctxt_new();
        !           273:
        !           274:        /* The first few requests do not require asynchronous access */
        !           275:        while (!authenticated) {
        !           276:                authenticated = monitor_read(monitor, mon_dispatch, &ent);
        !           277:                if (authenticated) {
        !           278:                        if (!(ent->flags & MON_AUTHDECIDE))
        !           279:                                fatal("%s: unexpected authentication from %d",
        !           280:                                    __FUNCTION__, ent->type);
        !           281:                        if (authctxt->pw->pw_uid == 0 &&
        !           282:                            !auth_root_allowed(auth_method))
        !           283:                                authenticated = 0;
        !           284:                }
        !           285:
        !           286:                if (ent->flags & MON_AUTHDECIDE) {
        !           287:                        auth_log(authctxt, authenticated, auth_method,
        !           288:                            compat20 ? " ssh2" : "");
        !           289:                        if (!authenticated)
        !           290:                                authctxt->failures++;
        !           291:                }
        !           292:        }
        !           293:
        !           294:        if (!authctxt->valid)
        !           295:                fatal("%s: authenticated invalid user", __FUNCTION__);
        !           296:
        !           297:        debug("%s: %s has been authenticated by privileged process",
        !           298:            __FUNCTION__, authctxt->user);
        !           299:
        !           300:        mm_get_keystate(monitor);
        !           301:
        !           302:        return (authctxt);
        !           303: }
        !           304:
        !           305: void
        !           306: monitor_child_postauth(struct monitor *monitor)
        !           307: {
        !           308:        if (compat20) {
        !           309:                mon_dispatch = mon_dispatch_postauth20;
        !           310:
        !           311:                /* Permit requests for moduli and signatures */
        !           312:                monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
        !           313:                monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
        !           314:                monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
        !           315:
        !           316:        } else {
        !           317:                mon_dispatch = mon_dispatch_postauth15;
        !           318:                monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
        !           319:        }
        !           320:        if (!no_pty_flag) {
        !           321:                monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
        !           322:                monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
        !           323:        }
        !           324:
        !           325:        for (;;)
        !           326:                monitor_read(monitor, mon_dispatch, NULL);
        !           327: }
        !           328:
        !           329: void
        !           330: monitor_sync(struct monitor *monitor)
        !           331: {
        !           332:        /* The member allocation is not visible, so sync it */
        !           333:        mm_share_sync(&monitor->m_zlib, &monitor->m_zback);
        !           334: }
        !           335:
        !           336: int
        !           337: monitor_read(struct monitor *monitor, struct mon_table *ent,
        !           338:     struct mon_table **pent)
        !           339: {
        !           340:        Buffer m;
        !           341:        int ret;
        !           342:        u_char type;
        !           343:
        !           344:        buffer_init(&m);
        !           345:
        !           346:        mm_request_receive(monitor->m_sendfd, &m);
        !           347:        type = buffer_get_char(&m);
        !           348:
        !           349:        debug3("%s: checking request %d", __FUNCTION__, type);
        !           350:
        !           351:        while (ent->f != NULL) {
        !           352:                if (ent->type == type)
        !           353:                        break;
        !           354:                ent++;
        !           355:        }
        !           356:
        !           357:        if (ent->f != NULL) {
        !           358:                if (!(ent->flags & MON_PERMIT))
        !           359:                        fatal("%s: unpermitted request %d", __FUNCTION__,
        !           360:                            type);
        !           361:                ret = (*ent->f)(monitor->m_sendfd, &m);
        !           362:                buffer_free(&m);
        !           363:
        !           364:                /* The child may use this request only once, disable it */
        !           365:                if (ent->flags & MON_ONCE) {
        !           366:                        debug2("%s: %d used once, disabling now", __FUNCTION__,
        !           367:                            type);
        !           368:                        ent->flags &= ~MON_PERMIT;
        !           369:                }
        !           370:
        !           371:                if (pent != NULL)
        !           372:                        *pent = ent;
        !           373:
        !           374:                return ret;
        !           375:        }
        !           376:
        !           377:        fatal("%s: unsupported request: %d\n", __FUNCTION__, type);
        !           378:
        !           379:        /* NOTREACHED */
        !           380:        return (-1);
        !           381: }
        !           382:
        !           383: /* allowed key state */
        !           384: static int
        !           385: monitor_allowed_key(u_char *blob, u_int bloblen)
        !           386: {
        !           387:        /* make sure key is allowed */
        !           388:        if (key_blob == NULL || key_bloblen != bloblen ||
        !           389:            memcmp(key_blob, blob, key_bloblen))
        !           390:                return (0);
        !           391:        return (1);
        !           392: }
        !           393:
        !           394: static void
        !           395: monitor_reset_key_state(void)
        !           396: {
        !           397:        /* reset state */
        !           398:        if (key_blob != NULL)
        !           399:                xfree(key_blob);
        !           400:        if (hostbased_cuser != NULL)
        !           401:                xfree(hostbased_cuser);
        !           402:        if (hostbased_chost != NULL)
        !           403:                xfree(hostbased_chost);
        !           404:        key_blob = NULL;
        !           405:        key_bloblen = 0;
        !           406:        key_blobtype = MM_NOKEY;
        !           407:        hostbased_cuser = NULL;
        !           408:        hostbased_chost = NULL;
        !           409: }
        !           410:
        !           411: int
        !           412: mm_answer_moduli(int socket, Buffer *m)
        !           413: {
        !           414:        DH *dh;
        !           415:        int min, want, max;
        !           416:
        !           417:        min = buffer_get_int(m);
        !           418:        want = buffer_get_int(m);
        !           419:        max = buffer_get_int(m);
        !           420:
        !           421:        debug3("%s: got parameters: %d %d %d",
        !           422:            __FUNCTION__, min, want, max);
        !           423:        /* We need to check here, too, in case the child got corrupted */
        !           424:        if (max < min || want < min || max < want)
        !           425:                fatal("%s: bad parameters: %d %d %d",
        !           426:                    __FUNCTION__, min, want, max);
        !           427:
        !           428:        buffer_clear(m);
        !           429:
        !           430:        dh = choose_dh(min, want, max);
        !           431:        if (dh == NULL) {
        !           432:                buffer_put_char(m, 0);
        !           433:                return (0);
        !           434:        } else {
        !           435:                /* Send first bignum */
        !           436:                buffer_put_char(m, 1);
        !           437:                buffer_put_bignum2(m, dh->p);
        !           438:                buffer_put_bignum2(m, dh->g);
        !           439:
        !           440:                DH_free(dh);
        !           441:        }
        !           442:        mm_request_send(socket, MONITOR_ANS_MODULI, m);
        !           443:        return (0);
        !           444: }
        !           445:
        !           446: int
        !           447: mm_answer_sign(int socket, Buffer *m)
        !           448: {
        !           449:        Key *key;
        !           450:        u_char *p;
        !           451:        u_char *signature;
        !           452:        u_int siglen, datlen;
        !           453:        int keyid;
        !           454:
        !           455:        debug3("%s", __FUNCTION__);
        !           456:
        !           457:        keyid = buffer_get_int(m);
        !           458:        p = buffer_get_string(m, &datlen);
        !           459:
        !           460:        if (datlen != 20)
        !           461:                fatal("%s: data length incorrect: %d", __FUNCTION__, datlen);
        !           462:
        !           463:        if ((key = get_hostkey_by_index(keyid)) == NULL)
        !           464:                fatal("%s: no hostkey from index %d", __FUNCTION__, keyid);
        !           465:        if (key_sign(key, &signature, &siglen, p, datlen) < 0)
        !           466:                fatal("%s: key_sign failed", __FUNCTION__);
        !           467:
        !           468:        debug3("%s: signature %p(%d)", __FUNCTION__, signature, siglen);
        !           469:
        !           470:        buffer_clear(m);
        !           471:        buffer_put_string(m, signature, siglen);
        !           472:
        !           473:        xfree(p);
        !           474:        xfree(signature);
        !           475:
        !           476:        mm_request_send(socket, MONITOR_ANS_SIGN, m);
        !           477:
        !           478:        /* Turn on permissions for getpwnam */
        !           479:        monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
        !           480:
        !           481:        return (0);
        !           482: }
        !           483:
        !           484: /* Retrieves the password entry and also checks if the user is permitted */
        !           485:
        !           486: int
        !           487: mm_answer_pwnamallow(int socket, Buffer *m)
        !           488: {
        !           489:        char *login;
        !           490:        struct passwd *pwent;
        !           491:        int allowed = 0;
        !           492:
        !           493:        debug3("%s", __FUNCTION__);
        !           494:
        !           495:        if (authctxt->attempt++ != 0)
        !           496:                fatal("%s: multiple attempts for getpwnam", __FUNCTION__);
        !           497:
        !           498:        login = buffer_get_string(m, NULL);
        !           499:
        !           500:        pwent = getpwnamallow(login);
        !           501:
        !           502:        authctxt->user = xstrdup(login);
        !           503:        setproctitle("%s [priv]", pwent ? login : "unknown");
        !           504:        xfree(login);
        !           505:
        !           506:        buffer_clear(m);
        !           507:
        !           508:        if (pwent == NULL) {
        !           509:                buffer_put_char(m, 0);
        !           510:                goto out;
        !           511:        }
        !           512:
        !           513:        allowed = 1;
        !           514:        authctxt->pw = pwcopy(pwent);
        !           515:        authctxt->valid = 1;
        !           516:
        !           517:        buffer_put_char(m, 1);
        !           518:        buffer_put_string(m, pwent, sizeof(struct passwd));
        !           519:        buffer_put_cstring(m, pwent->pw_name);
        !           520:        buffer_put_cstring(m, "*");
        !           521:        buffer_put_cstring(m, pwent->pw_gecos);
        !           522:        buffer_put_cstring(m, pwent->pw_class);
        !           523:        buffer_put_cstring(m, pwent->pw_dir);
        !           524:        buffer_put_cstring(m, pwent->pw_shell);
        !           525:
        !           526:  out:
        !           527:        debug3("%s: sending MONITOR_ANS_PWNAM: %d", __FUNCTION__, allowed);
        !           528:        mm_request_send(socket, MONITOR_ANS_PWNAM, m);
        !           529:
        !           530:        /* For SSHv1 allow authentication now */
        !           531:        if (!compat20)
        !           532:                monitor_permit_authentications(1);
        !           533:        else
        !           534:                /* Allow service/style information on the auth context */
        !           535:                monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
        !           536:
        !           537:
        !           538:        return (0);
        !           539: }
        !           540:
        !           541: int
        !           542: mm_answer_authserv(int socket, Buffer *m)
        !           543: {
        !           544:        monitor_permit_authentications(1);
        !           545:
        !           546:        authctxt->service = buffer_get_string(m, NULL);
        !           547:        authctxt->style = buffer_get_string(m, NULL);
        !           548:        if (strlen(authctxt->style) == 0) {
        !           549:                xfree(authctxt->style);
        !           550:                authctxt->style = NULL;
        !           551:        }
        !           552:
        !           553:        debug3("%s: service=%s, style=%s",
        !           554:            __FUNCTION__, authctxt->service, authctxt->style);
        !           555:
        !           556:        return (0);
        !           557: }
        !           558:
        !           559: int
        !           560: mm_answer_authpassword(int socket, Buffer *m)
        !           561: {
        !           562:        static int call_count;
        !           563:        char *passwd;
        !           564:        int authenticated, plen;
        !           565:
        !           566:        passwd = buffer_get_string(m, &plen);
        !           567:        /* Only authenticate if the context is valid */
        !           568:        authenticated = authctxt->valid && auth_password(authctxt, passwd);
        !           569:        memset(passwd, 0, strlen(passwd));
        !           570:        xfree(passwd);
        !           571:
        !           572:        buffer_clear(m);
        !           573:        buffer_put_int(m, authenticated);
        !           574:
        !           575:        debug3("%s: sending result %d", __FUNCTION__, authenticated);
        !           576:        mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);
        !           577:
        !           578:        call_count++;
        !           579:        if (plen == 0 && call_count == 1)
        !           580:                auth_method = "none";
        !           581:        else
        !           582:                auth_method = "password";
        !           583:
        !           584:        /* Causes monitor loop to terminate if authenticated */
        !           585:        return (authenticated);
        !           586: }
        !           587:
        !           588: #ifdef BSD_AUTH
        !           589: int
        !           590: mm_answer_bsdauthquery(int socket, Buffer *m)
        !           591: {
        !           592:        char *name, *infotxt;
        !           593:        u_int numprompts;
        !           594:        u_int *echo_on;
        !           595:        char **prompts;
        !           596:        int res;
        !           597:
        !           598:        res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
        !           599:            &prompts, &echo_on);
        !           600:
        !           601:        buffer_clear(m);
        !           602:        buffer_put_int(m, res);
        !           603:        if (res != -1)
        !           604:                buffer_put_cstring(m, prompts[0]);
        !           605:
        !           606:        debug3("%s: sending challenge res: %d", __FUNCTION__, res);
        !           607:        mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);
        !           608:
        !           609:        if (res != -1) {
        !           610:                xfree(name);
        !           611:                xfree(infotxt);
        !           612:                xfree(prompts);
        !           613:                xfree(echo_on);
        !           614:        }
        !           615:
        !           616:        return (0);
        !           617: }
        !           618:
        !           619: int
        !           620: mm_answer_bsdauthrespond(int socket, Buffer *m)
        !           621: {
        !           622:        char *response;
        !           623:        int authok;
        !           624:
        !           625:        if (authctxt->as == 0)
        !           626:                fatal("%s: no bsd auth session", __FUNCTION__);
        !           627:
        !           628:        response = buffer_get_string(m, NULL);
        !           629:        authok = auth_userresponse(authctxt->as, response, 0);
        !           630:        authctxt->as = NULL;
        !           631:        debug3("%s: <%s> = <%d>", __FUNCTION__, response, authok);
        !           632:        xfree(response);
        !           633:
        !           634:        buffer_clear(m);
        !           635:        buffer_put_int(m, authok);
        !           636:
        !           637:        debug3("%s: sending authenticated: %d", __FUNCTION__, authok);
        !           638:        mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);
        !           639:
        !           640:        auth_method = "bsdauth";
        !           641:
        !           642:        return (authok != 0);
        !           643: }
        !           644: #endif
        !           645:
        !           646: #ifdef SKEY
        !           647: int
        !           648: mm_answer_skeyquery(int socket, Buffer *m)
        !           649: {
        !           650:        struct skey skey;
        !           651:        char challenge[1024];
        !           652:        int res;
        !           653:
        !           654:        res = skeychallenge(&skey, authctxt->user, challenge);
        !           655:
        !           656:        buffer_clear(m);
        !           657:        buffer_put_int(m, res);
        !           658:        if (res != -1)
        !           659:                buffer_put_cstring(m, challenge);
        !           660:
        !           661:        debug3("%s: sending challenge res: %d", __FUNCTION__, res);
        !           662:        mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);
        !           663:
        !           664:        return (0);
        !           665: }
        !           666:
        !           667: int
        !           668: mm_answer_skeyrespond(int socket, Buffer *m)
        !           669: {
        !           670:        char *response;
        !           671:        int authok;
        !           672:
        !           673:        response = buffer_get_string(m, NULL);
        !           674:
        !           675:        authok = (authctxt->valid &&
        !           676:            skey_haskey(authctxt->pw->pw_name) == 0 &&
        !           677:            skey_passcheck(authctxt->pw->pw_name, response) != -1);
        !           678:
        !           679:        xfree(response);
        !           680:
        !           681:        buffer_clear(m);
        !           682:        buffer_put_int(m, authok);
        !           683:
        !           684:        debug3("%s: sending authenticated: %d", __FUNCTION__, authok);
        !           685:        mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);
        !           686:
        !           687:        auth_method = "skey";
        !           688:
        !           689:        return (authok != 0);
        !           690: }
        !           691: #endif
        !           692:
        !           693: void
        !           694: mm_append_debug(Buffer *m)
        !           695: {
        !           696:        if (auth_debug_init && buffer_len(&auth_debug)) {
        !           697:                debug3("%s: Appending debug messages for child", __FUNCTION__);
        !           698:                buffer_append(m, buffer_ptr(&auth_debug),
        !           699:                    buffer_len(&auth_debug));
        !           700:                buffer_clear(&auth_debug);
        !           701:        }
        !           702: }
        !           703:
        !           704: int
        !           705: mm_answer_keyallowed(int socket, Buffer *m)
        !           706: {
        !           707:        Key *key;
        !           708:        u_char *cuser, *chost, *blob;
        !           709:        u_int bloblen;
        !           710:        enum mm_keytype type = 0;
        !           711:        int allowed = 0;
        !           712:
        !           713:        debug3("%s entering", __FUNCTION__);
        !           714:
        !           715:        type = buffer_get_int(m);
        !           716:        cuser = buffer_get_string(m, NULL);
        !           717:        chost = buffer_get_string(m, NULL);
        !           718:        blob = buffer_get_string(m, &bloblen);
        !           719:
        !           720:        key = key_from_blob(blob, bloblen);
        !           721:
        !           722:        if ((compat20 && type == MM_RSAHOSTKEY) ||
        !           723:            (!compat20 && type != MM_RSAHOSTKEY))
        !           724:                fatal("%s: key type and protocol mismatch", __FUNCTION__);
        !           725:
        !           726:        debug3("%s: key_from_blob: %p", __FUNCTION__, key);
        !           727:
        !           728:        if (key != NULL && authctxt->pw != NULL) {
        !           729:                switch(type) {
        !           730:                case MM_USERKEY:
        !           731:                        allowed = user_key_allowed(authctxt->pw, key);
        !           732:                        break;
        !           733:                case MM_HOSTKEY:
        !           734:                        allowed = hostbased_key_allowed(authctxt->pw,
        !           735:                            cuser, chost, key);
        !           736:                        break;
        !           737:                case MM_RSAHOSTKEY:
        !           738:                        key->type = KEY_RSA1; /* XXX */
        !           739:                        allowed = auth_rhosts_rsa_key_allowed(authctxt->pw,
        !           740:                            cuser, chost, key);
        !           741:                        break;
        !           742:                default:
        !           743:                        fatal("%s: unknown key type %d", __FUNCTION__, type);
        !           744:                        break;
        !           745:                }
        !           746:                key_free(key);
        !           747:        }
        !           748:
        !           749:        /* clear temporarily storage (used by verify) */
        !           750:        monitor_reset_key_state();
        !           751:
        !           752:        if (allowed) {
        !           753:                /* Save temporarily for comparison in verify */
        !           754:                key_blob = blob;
        !           755:                key_bloblen = bloblen;
        !           756:                key_blobtype = type;
        !           757:                hostbased_cuser = cuser;
        !           758:                hostbased_chost = chost;
        !           759:        }
        !           760:
        !           761:        debug3("%s: key %p is %s",
        !           762:            __FUNCTION__, key, allowed ? "allowed" : "disallowed");
        !           763:
        !           764:        buffer_clear(m);
        !           765:        buffer_put_int(m, allowed);
        !           766:
        !           767:        mm_append_debug(m);
        !           768:
        !           769:        mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m);
        !           770:
        !           771:        if (type == MM_RSAHOSTKEY)
        !           772:                monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
        !           773:
        !           774:        return (0);
        !           775: }
        !           776:
        !           777: static int
        !           778: monitor_valid_userblob(u_char *data, u_int datalen)
        !           779: {
        !           780:        Buffer b;
        !           781:        u_char *p;
        !           782:        u_int len;
        !           783:        int fail = 0;
        !           784:        int session_id2_len = 20 /*XXX should get from [net] */;
        !           785:
        !           786:        buffer_init(&b);
        !           787:        buffer_append(&b, data, datalen);
        !           788:
        !           789:        if (datafellows & SSH_OLD_SESSIONID) {
        !           790:                buffer_consume(&b, session_id2_len);
        !           791:        } else {
        !           792:                xfree(buffer_get_string(&b, &len));
        !           793:                if (len != session_id2_len)
        !           794:                        fail++;
        !           795:        }
        !           796:        if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
        !           797:                fail++;
        !           798:        p = buffer_get_string(&b, NULL);
        !           799:        if (strcmp(authctxt->user, p) != 0) {
        !           800:                log("wrong user name passed to monitor: expected %s != %.100s",
        !           801:                    authctxt->user, p);
        !           802:                fail++;
        !           803:        }
        !           804:        xfree(p);
        !           805:        buffer_skip_string(&b);
        !           806:        if (datafellows & SSH_BUG_PKAUTH) {
        !           807:                if (!buffer_get_char(&b))
        !           808:                        fail++;
        !           809:        } else {
        !           810:                p = buffer_get_string(&b, NULL);
        !           811:                if (strcmp("publickey", p) != 0)
        !           812:                        fail++;
        !           813:                xfree(p);
        !           814:                if (!buffer_get_char(&b))
        !           815:                        fail++;
        !           816:                buffer_skip_string(&b);
        !           817:        }
        !           818:        buffer_skip_string(&b);
        !           819:        if (buffer_len(&b) != 0)
        !           820:                fail++;
        !           821:        buffer_free(&b);
        !           822:        return (fail == 0);
        !           823: }
        !           824:
        !           825: static int
        !           826: monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser,
        !           827:     u_char *chost)
        !           828: {
        !           829:        Buffer b;
        !           830:        u_char *p;
        !           831:        u_int len;
        !           832:        int fail = 0;
        !           833:        int session_id2_len = 20 /*XXX should get from [net] */;
        !           834:
        !           835:        buffer_init(&b);
        !           836:        buffer_append(&b, data, datalen);
        !           837:
        !           838:        xfree(buffer_get_string(&b, &len));
        !           839:        if (len != session_id2_len)
        !           840:                fail++;
        !           841:        if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
        !           842:                fail++;
        !           843:        p = buffer_get_string(&b, NULL);
        !           844:        if (strcmp(authctxt->user, p) != 0) {
        !           845:                log("wrong user name passed to monitor: expected %s != %.100s",
        !           846:                    authctxt->user, p);
        !           847:                fail++;
        !           848:        }
        !           849:        xfree(p);
        !           850:        buffer_skip_string(&b); /* service */
        !           851:        p = buffer_get_string(&b, NULL);
        !           852:        if (strcmp(p, "hostbased") != 0)
        !           853:                fail++;
        !           854:        xfree(p);
        !           855:        buffer_skip_string(&b); /* pkalg */
        !           856:        buffer_skip_string(&b); /* pkblob */
        !           857:
        !           858:        /* verify client host, strip trailing dot if necessary */
        !           859:        p = buffer_get_string(&b, NULL);
        !           860:        if (((len = strlen(p)) > 0) && p[len - 1] == '.')
        !           861:                p[len - 1] = '\0';
        !           862:        if (strcmp(p, chost) != 0)
        !           863:                fail++;
        !           864:        xfree(p);
        !           865:
        !           866:        /* verify client user */
        !           867:        p = buffer_get_string(&b, NULL);
        !           868:        if (strcmp(p, cuser) != 0)
        !           869:                fail++;
        !           870:        xfree(p);
        !           871:
        !           872:        if (buffer_len(&b) != 0)
        !           873:                fail++;
        !           874:        buffer_free(&b);
        !           875:        return (fail == 0);
        !           876: }
        !           877:
        !           878: int
        !           879: mm_answer_keyverify(int socket, Buffer *m)
        !           880: {
        !           881:        Key *key;
        !           882:        u_char *signature, *data, *blob;
        !           883:        u_int signaturelen, datalen, bloblen;
        !           884:        int verified = 0;
        !           885:        int valid_data = 0;
        !           886:
        !           887:        blob = buffer_get_string(m, &bloblen);
        !           888:        signature = buffer_get_string(m, &signaturelen);
        !           889:        data = buffer_get_string(m, &datalen);
        !           890:
        !           891:        if (hostbased_cuser == NULL || hostbased_chost == NULL ||
        !           892:           monitor_allowed_key(blob, bloblen) == NULL)
        !           893:                fatal("%s: bad key, not previously allowed", __FUNCTION__);
        !           894:
        !           895:        key = key_from_blob(blob, bloblen);
        !           896:        if (key == NULL)
        !           897:                fatal("%s: bad public key blob", __FUNCTION__);
        !           898:
        !           899:        switch (key_blobtype) {
        !           900:        case MM_USERKEY:
        !           901:                valid_data = monitor_valid_userblob(data, datalen);
        !           902:                break;
        !           903:        case MM_HOSTKEY:
        !           904:                valid_data = monitor_valid_hostbasedblob(data, datalen,
        !           905:                    hostbased_cuser, hostbased_chost);
        !           906:                break;
        !           907:        default:
        !           908:                valid_data = 0;
        !           909:                break;
        !           910:        }
        !           911:        if (!valid_data)
        !           912:                fatal("%s: bad signature data blob", __FUNCTION__);
        !           913:
        !           914:        verified = key_verify(key, signature, signaturelen, data, datalen);
        !           915:        debug3("%s: key %p signature %s",
        !           916:            __FUNCTION__, key, verified ? "verified" : "unverified");
        !           917:
        !           918:        key_free(key);
        !           919:        xfree(blob);
        !           920:        xfree(signature);
        !           921:        xfree(data);
        !           922:
        !           923:        monitor_reset_key_state();
        !           924:
        !           925:        buffer_clear(m);
        !           926:        buffer_put_int(m, verified);
        !           927:        mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
        !           928:
        !           929:        auth_method = "publickey";
        !           930:
        !           931:        return (verified);
        !           932: }
        !           933:
        !           934: void
        !           935: mm_record_login(Session *s, struct passwd *pw)
        !           936: {
        !           937:        socklen_t fromlen;
        !           938:        struct sockaddr_storage from;
        !           939:
        !           940:        /*
        !           941:         * Get IP address of client. If the connection is not a socket, let
        !           942:         * the address be 0.0.0.0.
        !           943:         */
        !           944:        memset(&from, 0, sizeof(from));
        !           945:        if (packet_connection_is_on_socket()) {
        !           946:                fromlen = sizeof(from);
        !           947:                if (getpeername(packet_get_connection_in(),
        !           948:                        (struct sockaddr *) & from, &fromlen) < 0) {
        !           949:                        debug("getpeername: %.100s", strerror(errno));
        !           950:                        fatal_cleanup();
        !           951:                }
        !           952:        }
        !           953:        /* Record that there was a login on that tty from the remote host. */
        !           954:        record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
        !           955:            get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
        !           956:            (struct sockaddr *)&from);
        !           957: }
        !           958:
        !           959: static void
        !           960: mm_session_close(Session *s)
        !           961: {
        !           962:        debug3("%s: session %d pid %d", __FUNCTION__, s->self, s->pid);
        !           963:        if (s->ttyfd != -1) {
        !           964:                debug3("%s: tty %s ptyfd %d",  __FUNCTION__, s->tty, s->ptyfd);
        !           965:                fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
        !           966:                session_pty_cleanup2(s);
        !           967:        }
        !           968:        s->used = 0;
        !           969: }
        !           970:
        !           971: int
        !           972: mm_answer_pty(int socket, Buffer *m)
        !           973: {
        !           974:        extern struct monitor *monitor;
        !           975:        Session *s;
        !           976:        int res, fd0;
        !           977:
        !           978:        debug3("%s entering", __FUNCTION__);
        !           979:
        !           980:        buffer_clear(m);
        !           981:        s = session_new();
        !           982:        if (s == NULL)
        !           983:                goto error;
        !           984:        s->authctxt = authctxt;
        !           985:        s->pw = authctxt->pw;
        !           986:        s->pid = monitor->m_pid;
        !           987:        res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
        !           988:        if (res == 0)
        !           989:                goto error;
        !           990:        fatal_add_cleanup(session_pty_cleanup2, (void *)s);
        !           991:        pty_setowner(authctxt->pw, s->tty);
        !           992:
        !           993:        buffer_put_int(m, 1);
        !           994:        buffer_put_cstring(m, s->tty);
        !           995:        mm_request_send(socket, MONITOR_ANS_PTY, m);
        !           996:
        !           997:        mm_send_fd(socket, s->ptyfd);
        !           998:        mm_send_fd(socket, s->ttyfd);
        !           999:
        !          1000:        /* We need to trick ttyslot */
        !          1001:        if (dup2(s->ttyfd, 0) == -1)
        !          1002:                fatal("%s: dup2", __FUNCTION__);
        !          1003:
        !          1004:        mm_record_login(s, authctxt->pw);
        !          1005:
        !          1006:        /* Now we can close the file descriptor again */
        !          1007:        close(0);
        !          1008:
        !          1009:        /* make sure nothing uses fd 0 */
        !          1010:        if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
        !          1011:                fatal("%s: open(/dev/null): %s", __FUNCTION__, strerror(errno));
        !          1012:        if (fd0 != 0)
        !          1013:                error("%s: fd0 %d != 0", __FUNCTION__, fd0);
        !          1014:
        !          1015:        /* slave is not needed */
        !          1016:        close(s->ttyfd);
        !          1017:        s->ttyfd = s->ptyfd;
        !          1018:        /* no need to dup() because nobody closes ptyfd */
        !          1019:        s->ptymaster = s->ptyfd;
        !          1020:
        !          1021:        debug3("%s: tty %s ptyfd %d",  __FUNCTION__, s->tty, s->ttyfd);
        !          1022:
        !          1023:        return (0);
        !          1024:
        !          1025:  error:
        !          1026:        if (s != NULL)
        !          1027:                mm_session_close(s);
        !          1028:        buffer_put_int(m, 0);
        !          1029:        mm_request_send(socket, MONITOR_ANS_PTY, m);
        !          1030:        return (0);
        !          1031: }
        !          1032:
        !          1033: int
        !          1034: mm_answer_pty_cleanup(int socket, Buffer *m)
        !          1035: {
        !          1036:        Session *s;
        !          1037:        char *tty;
        !          1038:
        !          1039:        debug3("%s entering", __FUNCTION__);
        !          1040:
        !          1041:        tty = buffer_get_string(m, NULL);
        !          1042:        if ((s = session_by_tty(tty)) != NULL)
        !          1043:                mm_session_close(s);
        !          1044:        buffer_clear(m);
        !          1045:        xfree(tty);
        !          1046:        return (0);
        !          1047: }
        !          1048:
        !          1049: int
        !          1050: mm_answer_sesskey(int socket, Buffer *m)
        !          1051: {
        !          1052:        BIGNUM *p;
        !          1053:        int rsafail;
        !          1054:
        !          1055:        /* Turn off permissions */
        !          1056:        monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
        !          1057:
        !          1058:        if ((p = BN_new()) == NULL)
        !          1059:                fatal("%s: BN_new", __FUNCTION__);
        !          1060:
        !          1061:        buffer_get_bignum2(m, p);
        !          1062:
        !          1063:        rsafail = ssh1_session_key(p);
        !          1064:
        !          1065:        buffer_clear(m);
        !          1066:        buffer_put_int(m, rsafail);
        !          1067:        buffer_put_bignum2(m, p);
        !          1068:
        !          1069:        BN_clear_free(p);
        !          1070:
        !          1071:        mm_request_send(socket, MONITOR_ANS_SESSKEY, m);
        !          1072:
        !          1073:        /* Turn on permissions for sessid passing */
        !          1074:        monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);
        !          1075:
        !          1076:        return (0);
        !          1077: }
        !          1078:
        !          1079: int
        !          1080: mm_answer_sessid(int socket, Buffer *m)
        !          1081: {
        !          1082:        int i;
        !          1083:
        !          1084:        debug3("%s entering", __FUNCTION__);
        !          1085:
        !          1086:        if (buffer_len(m) != 16)
        !          1087:                fatal("%s: bad ssh1 session id", __FUNCTION__);
        !          1088:        for (i = 0; i < 16; i++)
        !          1089:                session_id[i] = buffer_get_char(m);
        !          1090:
        !          1091:        /* Turn on permissions for getpwnam */
        !          1092:        monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
        !          1093:
        !          1094:        return (0);
        !          1095: }
        !          1096:
        !          1097: int
        !          1098: mm_answer_rsa_keyallowed(int socket, Buffer *m)
        !          1099: {
        !          1100:        BIGNUM *client_n;
        !          1101:        Key *key = NULL;
        !          1102:         u_char *blob = NULL;
        !          1103:         u_int blen = 0;
        !          1104:        int allowed = 0;
        !          1105:
        !          1106:        debug3("%s entering", __FUNCTION__);
        !          1107:
        !          1108:        if (authctxt->valid) {
        !          1109:                if ((client_n = BN_new()) == NULL)
        !          1110:                        fatal("%s: BN_new", __FUNCTION__);
        !          1111:                buffer_get_bignum2(m, client_n);
        !          1112:                allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);
        !          1113:                BN_clear_free(client_n);
        !          1114:        }
        !          1115:        buffer_clear(m);
        !          1116:        buffer_put_int(m, allowed);
        !          1117:
        !          1118:        /* clear temporarily storage (used by generate challenge) */
        !          1119:        monitor_reset_key_state();
        !          1120:
        !          1121:        if (allowed && key != NULL) {
        !          1122:                key->type = KEY_RSA;    /* cheat for key_to_blob */
        !          1123:                if (key_to_blob(key, &blob, &blen) == 0)
        !          1124:                        fatal("%s: key_to_blob failed", __FUNCTION__);
        !          1125:                buffer_put_string(m, blob, blen);
        !          1126:
        !          1127:                /* Save temporarily for comparison in verify */
        !          1128:                key_blob = blob;
        !          1129:                key_bloblen = blen;
        !          1130:                key_blobtype = MM_RSAUSERKEY;
        !          1131:                key_free(key);
        !          1132:        }
        !          1133:
        !          1134:        mm_append_debug(m);
        !          1135:
        !          1136:        mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m);
        !          1137:
        !          1138:        monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
        !          1139:        monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0);
        !          1140:        return (0);
        !          1141: }
        !          1142:
        !          1143: int
        !          1144: mm_answer_rsa_challenge(int socket, Buffer *m)
        !          1145: {
        !          1146:        Key *key = NULL;
        !          1147:         u_char *blob;
        !          1148:         u_int blen;
        !          1149:
        !          1150:        debug3("%s entering", __FUNCTION__);
        !          1151:
        !          1152:        if (!authctxt->valid)
        !          1153:                fatal("%s: authctxt not valid", __FUNCTION__);
        !          1154:        blob = buffer_get_string(m, &blen);
        !          1155:        if (!monitor_allowed_key(blob, blen))
        !          1156:                fatal("%s: bad key, not previously allowed", __FUNCTION__);
        !          1157:        if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
        !          1158:                fatal("%s: key type mismatch", __FUNCTION__);
        !          1159:        if ((key = key_from_blob(blob, blen)) == NULL)
        !          1160:                fatal("%s: received bad key", __FUNCTION__);
        !          1161:
        !          1162:        if (ssh1_challenge)
        !          1163:                BN_clear_free(ssh1_challenge);
        !          1164:        ssh1_challenge = auth_rsa_generate_challenge(key);
        !          1165:
        !          1166:        buffer_clear(m);
        !          1167:        buffer_put_bignum2(m, ssh1_challenge);
        !          1168:
        !          1169:        debug3("%s sending reply", __FUNCTION__);
        !          1170:        mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);
        !          1171:
        !          1172:
        !          1173:        monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
        !          1174:        return (0);
        !          1175: }
        !          1176:
        !          1177: int
        !          1178: mm_answer_rsa_response(int socket, Buffer *m)
        !          1179: {
        !          1180:        Key *key = NULL;
        !          1181:         u_char *blob, *response;
        !          1182:         u_int blen, len;
        !          1183:         int success;
        !          1184:
        !          1185:        debug3("%s entering", __FUNCTION__);
        !          1186:
        !          1187:        if (!authctxt->valid)
        !          1188:                fatal("%s: authctxt not valid", __FUNCTION__);
        !          1189:        if (ssh1_challenge == NULL)
        !          1190:                fatal("%s: no ssh1_challenge", __FUNCTION__);
        !          1191:
        !          1192:        blob = buffer_get_string(m, &blen);
        !          1193:        if (!monitor_allowed_key(blob, blen))
        !          1194:                fatal("%s: bad key, not previously allowed", __FUNCTION__);
        !          1195:        if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
        !          1196:                fatal("%s: key type mismatch: %d", __FUNCTION__, key_blobtype);
        !          1197:        if ((key = key_from_blob(blob, blen)) == NULL)
        !          1198:                fatal("%s: received bad key", __FUNCTION__);
        !          1199:        response = buffer_get_string(m, &len);
        !          1200:        if (len != 16)
        !          1201:                fatal("%s: received bad response to challenge", __FUNCTION__);
        !          1202:        success = auth_rsa_verify_response(key, ssh1_challenge, response);
        !          1203:
        !          1204:        key_free(key);
        !          1205:        xfree(response);
        !          1206:
        !          1207:        auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";
        !          1208:
        !          1209:        /* reset state */
        !          1210:        BN_clear_free(ssh1_challenge);
        !          1211:        ssh1_challenge = NULL;
        !          1212:        monitor_reset_key_state();
        !          1213:
        !          1214:        buffer_clear(m);
        !          1215:        buffer_put_int(m, success);
        !          1216:        mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m);
        !          1217:
        !          1218:        return (success);
        !          1219: }
        !          1220:
        !          1221: int
        !          1222: mm_answer_term(int socket, Buffer *req)
        !          1223: {
        !          1224:        extern struct monitor *monitor;
        !          1225:        int res, status;
        !          1226:
        !          1227:        debug3("%s: tearing down sessions", __FUNCTION__);
        !          1228:
        !          1229:        /* The child is terminating */
        !          1230:        session_destroy_all(&mm_session_close);
        !          1231:
        !          1232:        if (waitpid(monitor->m_pid, &status, 0) == -1)
        !          1233:                exit(1);
        !          1234:
        !          1235:        res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
        !          1236:
        !          1237:        /* Terminate process */
        !          1238:        exit (res);
        !          1239: }
        !          1240:
        !          1241: void
        !          1242: monitor_apply_keystate(struct monitor *monitor)
        !          1243: {
        !          1244:        if (compat20) {
        !          1245:                set_newkeys(MODE_IN);
        !          1246:                set_newkeys(MODE_OUT);
        !          1247:        } else {
        !          1248:                u_char key[256];
        !          1249:                packet_set_protocol_flags(child_state.ssh1protoflags);
        !          1250:                packet_set_encryption_key(key, SSH_SESSION_KEY_LENGTH,
        !          1251:                    child_state.ssh1cipher);
        !          1252:        }
        !          1253:
        !          1254:        packet_set_keycontext(MODE_OUT, child_state.keyout);
        !          1255:        xfree(child_state.keyout);
        !          1256:        packet_set_keycontext(MODE_IN, child_state.keyin);
        !          1257:        xfree(child_state.keyin);
        !          1258:
        !          1259:        if (!compat20) {
        !          1260:                packet_set_iv(MODE_OUT, child_state.ivout);
        !          1261:                xfree(child_state.ivout);
        !          1262:                packet_set_iv(MODE_IN, child_state.ivin);
        !          1263:                xfree(child_state.ivin);
        !          1264:        }
        !          1265:
        !          1266:        memcpy(&incoming_stream, &child_state.incoming,
        !          1267:            sizeof(incoming_stream));
        !          1268:        memcpy(&outgoing_stream, &child_state.outgoing,
        !          1269:            sizeof(outgoing_stream));
        !          1270:
        !          1271:        /* Update with new address */
        !          1272:        mm_init_compression(monitor->m_zlib);
        !          1273:
        !          1274:        /* Network I/O buffers */
        !          1275:        /* XXX inefficient for large buffers, need: buffer_init_from_string */
        !          1276:        buffer_clear(&input);
        !          1277:        buffer_append(&input, child_state.input, child_state.ilen);
        !          1278:        memset(child_state.input, 0, child_state.ilen);
        !          1279:        xfree(child_state.input);
        !          1280:
        !          1281:        buffer_clear(&output);
        !          1282:        buffer_append(&output, child_state.output, child_state.olen);
        !          1283:        memset(child_state.output, 0, child_state.olen);
        !          1284:        xfree(child_state.output);
        !          1285: }
        !          1286:
        !          1287: Kex *
        !          1288: mm_get_kex(Buffer *m)
        !          1289: {
        !          1290:        Kex *kex;
        !          1291:        void *blob;
        !          1292:        u_int bloblen;
        !          1293:
        !          1294:        kex = xmalloc(sizeof(*kex));
        !          1295:        memset(kex, 0, sizeof(*kex));
        !          1296:        kex->session_id = buffer_get_string(m, &kex->session_id_len);
        !          1297:        kex->we_need = buffer_get_int(m);
        !          1298:        kex->server = 1;
        !          1299:        kex->hostkey_type = buffer_get_int(m);
        !          1300:        kex->kex_type = buffer_get_int(m);
        !          1301:        blob = buffer_get_string(m, &bloblen);
        !          1302:        buffer_init(&kex->my);
        !          1303:        buffer_append(&kex->my, blob, bloblen);
        !          1304:        xfree(blob);
        !          1305:        blob = buffer_get_string(m, &bloblen);
        !          1306:        buffer_init(&kex->peer);
        !          1307:        buffer_append(&kex->peer, blob, bloblen);
        !          1308:        xfree(blob);
        !          1309:        kex->done = 1;
        !          1310:        kex->flags = buffer_get_int(m);
        !          1311:        kex->client_version_string = buffer_get_string(m, NULL);
        !          1312:        kex->server_version_string = buffer_get_string(m, NULL);
        !          1313:        kex->load_host_key=&get_hostkey_by_type;
        !          1314:        kex->host_key_index=&get_hostkey_index;
        !          1315:
        !          1316:        return (kex);
        !          1317: }
        !          1318:
        !          1319: /* This function requries careful sanity checking */
        !          1320:
        !          1321: void
        !          1322: mm_get_keystate(struct monitor *monitor)
        !          1323: {
        !          1324:        Buffer m;
        !          1325:        u_char *blob, *p;
        !          1326:        u_int bloblen, plen;
        !          1327:
        !          1328:        debug3("%s: Waiting for new keys", __FUNCTION__);
        !          1329:
        !          1330:        buffer_init(&m);
        !          1331:        mm_request_receive_expect(monitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);
        !          1332:        if (!compat20) {
        !          1333:                child_state.ssh1protoflags = buffer_get_int(&m);
        !          1334:                child_state.ssh1cipher = buffer_get_int(&m);
        !          1335:                child_state.ivout = buffer_get_string(&m,
        !          1336:                    &child_state.ivoutlen);
        !          1337:                child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
        !          1338:                goto skip;
        !          1339:        } else {
        !          1340:                /* Get the Kex for rekeying */
        !          1341:                *monitor->m_pkex = mm_get_kex(&m);
        !          1342:        }
        !          1343:
        !          1344:        blob = buffer_get_string(&m, &bloblen);
        !          1345:        current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
        !          1346:        xfree(blob);
        !          1347:
        !          1348:        debug3("%s: Waiting for second key", __FUNCTION__);
        !          1349:        blob = buffer_get_string(&m, &bloblen);
        !          1350:        current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
        !          1351:        xfree(blob);
        !          1352:
        !          1353:        /* Now get sequence numbers for the packets */
        !          1354:        packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
        !          1355:        packet_set_seqnr(MODE_IN, buffer_get_int(&m));
        !          1356:
        !          1357:  skip:
        !          1358:        /* Get the key context */
        !          1359:        child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
        !          1360:        child_state.keyin  = buffer_get_string(&m, &child_state.keyinlen);
        !          1361:
        !          1362:        debug3("%s: Getting compression state", __FUNCTION__);
        !          1363:        /* Get compression state */
        !          1364:        p = buffer_get_string(&m, &plen);
        !          1365:        if (plen != sizeof(child_state.outgoing))
        !          1366:                fatal("%s: bad request size", __FUNCTION__);
        !          1367:        memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
        !          1368:        xfree(p);
        !          1369:
        !          1370:        p = buffer_get_string(&m, &plen);
        !          1371:        if (plen != sizeof(child_state.incoming))
        !          1372:                fatal("%s: bad request size", __FUNCTION__);
        !          1373:        memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
        !          1374:        xfree(p);
        !          1375:
        !          1376:        /* Network I/O buffers */
        !          1377:        debug3("%s: Getting Network I/O buffers", __FUNCTION__);
        !          1378:        child_state.input = buffer_get_string(&m, &child_state.ilen);
        !          1379:        child_state.output = buffer_get_string(&m, &child_state.olen);
        !          1380:
        !          1381:        buffer_free(&m);
        !          1382: }
        !          1383:
        !          1384:
        !          1385: /* Allocation functions for zlib */
        !          1386: void *
        !          1387: mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
        !          1388: {
        !          1389:        void *address;
        !          1390:
        !          1391:        address = mm_malloc(mm, size * ncount);
        !          1392:
        !          1393:        return (address);
        !          1394: }
        !          1395:
        !          1396: void
        !          1397: mm_zfree(struct mm_master *mm, void *address)
        !          1398: {
        !          1399:        mm_free(mm, address);
        !          1400: }
        !          1401:
        !          1402: void
        !          1403: mm_init_compression(struct mm_master *mm)
        !          1404: {
        !          1405:        outgoing_stream.zalloc = (alloc_func)mm_zalloc;
        !          1406:        outgoing_stream.zfree = (free_func)mm_zfree;
        !          1407:        outgoing_stream.opaque = mm;
        !          1408:
        !          1409:        incoming_stream.zalloc = (alloc_func)mm_zalloc;
        !          1410:        incoming_stream.zfree = (free_func)mm_zfree;
        !          1411:        incoming_stream.opaque = mm;
        !          1412: }
        !          1413:
        !          1414: /* XXX */
        !          1415:
        !          1416: #define FD_CLOSEONEXEC(x) do { \
        !          1417:        if (fcntl(x, F_SETFD, 1) == -1) \
        !          1418:                fatal("fcntl(%d, F_SETFD)", x); \
        !          1419: } while (0)
        !          1420:
        !          1421: void
        !          1422: monitor_socketpair(int *pair)
        !          1423: {
        !          1424:        if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
        !          1425:                fatal("%s: socketpair", __FUNCTION__);
        !          1426:        FD_CLOSEONEXEC(pair[0]);
        !          1427:        FD_CLOSEONEXEC(pair[1]);
        !          1428: }
        !          1429:
        !          1430: #define MM_MEMSIZE     65536
        !          1431:
        !          1432: struct monitor *
        !          1433: monitor_init(void)
        !          1434: {
        !          1435:        struct monitor *mon;
        !          1436:        int pair[2];
        !          1437:
        !          1438:        mon = xmalloc(sizeof(*mon));
        !          1439:
        !          1440:        monitor_socketpair(pair);
        !          1441:
        !          1442:        mon->m_recvfd = pair[0];
        !          1443:        mon->m_sendfd = pair[1];
        !          1444:
        !          1445:        /* Used to share zlib space across processes */
        !          1446:        mon->m_zback = mm_create(NULL, MM_MEMSIZE);
        !          1447:        mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
        !          1448:
        !          1449:        /* Compression needs to share state across borders */
        !          1450:        mm_init_compression(mon->m_zlib);
        !          1451:
        !          1452:        return mon;
        !          1453: }
        !          1454:
        !          1455: void
        !          1456: monitor_reinit(struct monitor *mon)
        !          1457: {
        !          1458:        int pair[2];
        !          1459:
        !          1460:        monitor_socketpair(pair);
        !          1461:
        !          1462:        mon->m_recvfd = pair[0];
        !          1463:        mon->m_sendfd = pair[1];
        !          1464: }