Annotation of src/usr.bin/ssh/monitor_wrap.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/bn.h>
! 31: #include <openssl/dh.h>
! 32:
! 33: #include "ssh.h"
! 34: #include "dh.h"
! 35: #include "kex.h"
! 36: #include "auth.h"
! 37: #include "buffer.h"
! 38: #include "bufaux.h"
! 39: #include "packet.h"
! 40: #include "mac.h"
! 41: #include "log.h"
! 42: #include "zlib.h"
! 43: #include "monitor.h"
! 44: #include "monitor_wrap.h"
! 45: #include "xmalloc.h"
! 46: #include "atomicio.h"
! 47: #include "monitor_fdpass.h"
! 48: #include "getput.h"
! 49:
! 50: #include "auth.h"
! 51: #include "channels.h"
! 52: #include "session.h"
! 53:
! 54: /* Imports */
! 55: extern int compat20;
! 56: extern Newkeys *newkeys[];
! 57: extern z_stream incoming_stream;
! 58: extern z_stream outgoing_stream;
! 59: extern struct monitor *monitor;
! 60: extern Buffer input, output;
! 61:
! 62: void
! 63: mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
! 64: {
! 65: u_char buf[5];
! 66: u_int mlen = buffer_len(m);
! 67:
! 68: debug3("%s entering: type %d", __FUNCTION__, type);
! 69:
! 70: PUT_32BIT(buf, mlen + 1);
! 71: buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
! 72: if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
! 73: fatal("%s: write", __FUNCTION__);
! 74: if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
! 75: fatal("%s: write", __FUNCTION__);
! 76: }
! 77:
! 78: void
! 79: mm_request_receive(int socket, Buffer *m)
! 80: {
! 81: u_char buf[4];
! 82: ssize_t res;
! 83: u_int msg_len;
! 84:
! 85: debug3("%s entering", __FUNCTION__);
! 86:
! 87: res = atomicio(read, socket, buf, sizeof(buf));
! 88: if (res != sizeof(buf)) {
! 89: if (res == 0)
! 90: fatal_cleanup();
! 91: fatal("%s: read: %d", __FUNCTION__, res);
! 92: }
! 93: msg_len = GET_32BIT(buf);
! 94: if (msg_len > 256 * 1024)
! 95: fatal("%s: read: bad msg_len %d", __FUNCTION__, msg_len);
! 96: buffer_clear(m);
! 97: buffer_append_space(m, msg_len);
! 98: res = atomicio(read, socket, buffer_ptr(m), msg_len);
! 99: if (res != msg_len)
! 100: fatal("%s: read: %d != msg_len", __FUNCTION__, res);
! 101: }
! 102:
! 103: void
! 104: mm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m)
! 105: {
! 106: u_char rtype;
! 107:
! 108: debug3("%s entering: type %d", __FUNCTION__, type);
! 109:
! 110: mm_request_receive(socket, m);
! 111: rtype = buffer_get_char(m);
! 112: if (rtype != type)
! 113: fatal("%s: read: rtype %d != type %d", __FUNCTION__,
! 114: rtype, type);
! 115: }
! 116:
! 117: DH *
! 118: mm_choose_dh(int min, int nbits, int max)
! 119: {
! 120: BIGNUM *p, *g;
! 121: int success = 0;
! 122: Buffer m;
! 123:
! 124: buffer_init(&m);
! 125: buffer_put_int(&m, min);
! 126: buffer_put_int(&m, nbits);
! 127: buffer_put_int(&m, max);
! 128:
! 129: mm_request_send(monitor->m_recvfd, MONITOR_REQ_MODULI, &m);
! 130:
! 131: debug3("%s: waiting for MONITOR_ANS_MODULI", __FUNCTION__);
! 132: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_MODULI, &m);
! 133:
! 134: success = buffer_get_char(&m);
! 135: if (success == 0)
! 136: fatal("%s: MONITOR_ANS_MODULI failed", __FUNCTION__);
! 137:
! 138: if ((p = BN_new()) == NULL)
! 139: fatal("%s: BN_new failed", __FUNCTION__);
! 140: if ((g = BN_new()) == NULL)
! 141: fatal("%s: BN_new failed", __FUNCTION__);
! 142: buffer_get_bignum2(&m, p);
! 143: buffer_get_bignum2(&m, g);
! 144:
! 145: debug3("%s: remaining %d", __FUNCTION__, buffer_len(&m));
! 146: buffer_free(&m);
! 147:
! 148: return (dh_new_group(g, p));
! 149: }
! 150:
! 151: int
! 152: mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
! 153: {
! 154: Kex *kex = *monitor->m_pkex;
! 155: Buffer m;
! 156:
! 157: debug3("%s entering", __FUNCTION__);
! 158:
! 159: buffer_init(&m);
! 160: buffer_put_int(&m, kex->host_key_index(key));
! 161: buffer_put_string(&m, data, datalen);
! 162:
! 163: mm_request_send(monitor->m_recvfd, MONITOR_REQ_SIGN, &m);
! 164:
! 165: debug3("%s: waiting for MONITOR_ANS_SIGN", __FUNCTION__);
! 166: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_SIGN, &m);
! 167: *sigp = buffer_get_string(&m, lenp);
! 168: buffer_free(&m);
! 169:
! 170: return (0);
! 171: }
! 172:
! 173: struct passwd *
! 174: mm_getpwnamallow(const char *login)
! 175: {
! 176: Buffer m;
! 177: struct passwd *pw;
! 178: u_int pwlen;
! 179:
! 180: debug3("%s entering", __FUNCTION__);
! 181:
! 182: buffer_init(&m);
! 183: buffer_put_cstring(&m, login);
! 184:
! 185: mm_request_send(monitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
! 186:
! 187: debug3("%s: waiting for MONITOR_ANS_PWNAM", __FUNCTION__);
! 188: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
! 189:
! 190: if (buffer_get_char(&m) == 0) {
! 191: buffer_free(&m);
! 192: return (NULL);
! 193: }
! 194: pw = buffer_get_string(&m, &pwlen);
! 195: if (pwlen != sizeof(struct passwd))
! 196: fatal("%s: struct passwd size mismatch", __FUNCTION__);
! 197: pw->pw_name = buffer_get_string(&m, NULL);
! 198: pw->pw_passwd = buffer_get_string(&m, NULL);
! 199: pw->pw_gecos = buffer_get_string(&m, NULL);
! 200: pw->pw_class = buffer_get_string(&m, NULL);
! 201: pw->pw_dir = buffer_get_string(&m, NULL);
! 202: pw->pw_shell = buffer_get_string(&m, NULL);
! 203: buffer_free(&m);
! 204:
! 205: return (pw);
! 206: }
! 207:
! 208: void
! 209: pwfree(struct passwd *pw)
! 210: {
! 211: xfree(pw->pw_name);
! 212: xfree(pw->pw_passwd);
! 213: xfree(pw->pw_gecos);
! 214: xfree(pw->pw_class);
! 215: xfree(pw->pw_dir);
! 216: xfree(pw->pw_shell);
! 217: xfree(pw);
! 218: }
! 219:
! 220: /* Inform the privileged process about service and style */
! 221:
! 222: void
! 223: mm_inform_authserv(char *service, char *style)
! 224: {
! 225: Buffer m;
! 226:
! 227: debug3("%s entering", __FUNCTION__);
! 228:
! 229: buffer_init(&m);
! 230: buffer_put_cstring(&m, service);
! 231: buffer_put_cstring(&m, style ? style : "");
! 232:
! 233: mm_request_send(monitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
! 234:
! 235: buffer_free(&m);
! 236: }
! 237:
! 238: /* Do the password authentication */
! 239: int
! 240: mm_auth_password(Authctxt *authctxt, char *password)
! 241: {
! 242: Buffer m;
! 243: int authenticated = 0;
! 244:
! 245: debug3("%s entering", __FUNCTION__);
! 246:
! 247: buffer_init(&m);
! 248: buffer_put_cstring(&m, password);
! 249: mm_request_send(monitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
! 250:
! 251: debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __FUNCTION__);
! 252: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
! 253:
! 254: authenticated = buffer_get_int(&m);
! 255:
! 256: buffer_free(&m);
! 257:
! 258: debug3("%s: user %sauthenticated",
! 259: __FUNCTION__, authenticated ? "" : "not ");
! 260: return (authenticated);
! 261: }
! 262:
! 263: int
! 264: mm_user_key_allowed(struct passwd *pw, Key *key)
! 265: {
! 266: return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
! 267: }
! 268:
! 269: int
! 270: mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
! 271: Key *key)
! 272: {
! 273: return (mm_key_allowed(MM_HOSTKEY, user, host, key));
! 274: }
! 275:
! 276: int
! 277: mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
! 278: char *host, Key *key)
! 279: {
! 280: int ret;
! 281:
! 282: key->type = KEY_RSA; /* XXX hack for key_to_blob */
! 283: ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
! 284: key->type = KEY_RSA1;
! 285: return (ret);
! 286: }
! 287:
! 288: void
! 289: mm_send_debug(Buffer *m)
! 290: {
! 291: char *msg;
! 292:
! 293: while (buffer_len(m)) {
! 294: msg = buffer_get_string(m, NULL);
! 295: debug3("%s: Sending debug: %s", __FUNCTION__, msg);
! 296: packet_send_debug("%s", msg);
! 297: xfree(msg);
! 298: }
! 299: }
! 300:
! 301: int
! 302: mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
! 303: {
! 304: Buffer m;
! 305: u_char *blob;
! 306: u_int len;
! 307: int allowed = 0;
! 308:
! 309: debug3("%s entering", __FUNCTION__);
! 310:
! 311: /* Convert the key to a blob and the pass it over */
! 312: if (!key_to_blob(key, &blob, &len))
! 313: return (0);
! 314:
! 315: buffer_init(&m);
! 316: buffer_put_int(&m, type);
! 317: buffer_put_cstring(&m, user ? user : "");
! 318: buffer_put_cstring(&m, host ? host : "");
! 319: buffer_put_string(&m, blob, len);
! 320: xfree(blob);
! 321:
! 322: mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
! 323:
! 324: debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __FUNCTION__);
! 325: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
! 326:
! 327: allowed = buffer_get_int(&m);
! 328:
! 329: /* Send potential debug messages */
! 330: mm_send_debug(&m);
! 331:
! 332: buffer_free(&m);
! 333:
! 334: return (allowed);
! 335: }
! 336:
! 337: /*
! 338: * This key verify needs to send the key type along, because the
! 339: * privileged parent makes the decision if the key is allowed
! 340: * for authentication.
! 341: */
! 342:
! 343: int
! 344: mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
! 345: {
! 346: Buffer m;
! 347: u_char *blob;
! 348: u_int len;
! 349: int verified = 0;
! 350:
! 351: debug3("%s entering", __FUNCTION__);
! 352:
! 353: /* Convert the key to a blob and the pass it over */
! 354: if (!key_to_blob(key, &blob, &len))
! 355: return (0);
! 356:
! 357: buffer_init(&m);
! 358: buffer_put_string(&m, blob, len);
! 359: buffer_put_string(&m, sig, siglen);
! 360: buffer_put_string(&m, data, datalen);
! 361: xfree(blob);
! 362:
! 363: mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
! 364:
! 365: debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __FUNCTION__);
! 366: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
! 367:
! 368: verified = buffer_get_int(&m);
! 369:
! 370: buffer_free(&m);
! 371:
! 372: return (verified);
! 373: }
! 374:
! 375: /* Export key state after authentication */
! 376: Newkeys *
! 377: mm_newkeys_from_blob(u_char *blob, int blen)
! 378: {
! 379: Buffer b;
! 380: u_int len;
! 381: Newkeys *newkey = NULL;
! 382: Enc *enc;
! 383: Mac *mac;
! 384: Comp *comp;
! 385:
! 386: debug3("%s: %p(%d)", __FUNCTION__, blob, blen);
! 387: #ifdef DEBUG_PK
! 388: dump_base64(stderr, blob, blen);
! 389: #endif
! 390: buffer_init(&b);
! 391: buffer_append(&b, blob, blen);
! 392:
! 393: newkey = xmalloc(sizeof(*newkey));
! 394: enc = &newkey->enc;
! 395: mac = &newkey->mac;
! 396: comp = &newkey->comp;
! 397:
! 398: /* Enc structure */
! 399: enc->name = buffer_get_string(&b, NULL);
! 400: buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
! 401: enc->enabled = buffer_get_int(&b);
! 402: enc->block_size = buffer_get_int(&b);
! 403: enc->key = buffer_get_string(&b, &enc->key_len);
! 404: enc->iv = buffer_get_string(&b, &len);
! 405: if (len != enc->block_size)
! 406: fatal("%s: bad ivlen: expected %d != %d", __FUNCTION__,
! 407: enc->block_size, len);
! 408:
! 409: if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
! 410: fatal("%s: bad cipher name %s or pointer %p", __FUNCTION__,
! 411: enc->name, enc->cipher);
! 412:
! 413: /* Mac structure */
! 414: mac->name = buffer_get_string(&b, NULL);
! 415: if (mac->name == NULL || mac_init(mac, mac->name) == -1)
! 416: fatal("%s: can not init mac %s", __FUNCTION__, mac->name);
! 417: mac->enabled = buffer_get_int(&b);
! 418: mac->key = buffer_get_string(&b, &len);
! 419: if (len > mac->key_len)
! 420: fatal("%s: bad mac key lenght: %d > %d", __FUNCTION__, len,
! 421: mac->key_len);
! 422: mac->key_len = len;
! 423:
! 424: /* Comp structure */
! 425: comp->type = buffer_get_int(&b);
! 426: comp->enabled = buffer_get_int(&b);
! 427: comp->name = buffer_get_string(&b, NULL);
! 428:
! 429: len = buffer_len(&b);
! 430: if (len != 0)
! 431: error("newkeys_from_blob: remaining bytes in blob %d", len);
! 432: buffer_free(&b);
! 433: return (newkey);
! 434: }
! 435:
! 436: int
! 437: mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
! 438: {
! 439: Buffer b;
! 440: int len;
! 441: u_char *buf;
! 442: Enc *enc;
! 443: Mac *mac;
! 444: Comp *comp;
! 445: Newkeys *newkey = newkeys[mode];
! 446:
! 447: debug3("%s: converting %p", __FUNCTION__, newkey);
! 448:
! 449: if (newkey == NULL) {
! 450: error("%s: newkey == NULL", __FUNCTION__);
! 451: return 0;
! 452: }
! 453: enc = &newkey->enc;
! 454: mac = &newkey->mac;
! 455: comp = &newkey->comp;
! 456:
! 457: buffer_init(&b);
! 458: /* Enc structure */
! 459: buffer_put_cstring(&b, enc->name);
! 460: /* The cipher struct is constant and shared, you export pointer */
! 461: buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
! 462: buffer_put_int(&b, enc->enabled);
! 463: buffer_put_int(&b, enc->block_size);
! 464: buffer_put_string(&b, enc->key, enc->key_len);
! 465: packet_get_keyiv(mode, enc->iv, enc->block_size);
! 466: buffer_put_string(&b, enc->iv, enc->block_size);
! 467:
! 468: /* Mac structure */
! 469: buffer_put_cstring(&b, mac->name);
! 470: buffer_put_int(&b, mac->enabled);
! 471: buffer_put_string(&b, mac->key, mac->key_len);
! 472:
! 473: /* Comp structure */
! 474: buffer_put_int(&b, comp->type);
! 475: buffer_put_int(&b, comp->enabled);
! 476: buffer_put_cstring(&b, comp->name);
! 477:
! 478: len = buffer_len(&b);
! 479: buf = xmalloc(len);
! 480: memcpy(buf, buffer_ptr(&b), len);
! 481: memset(buffer_ptr(&b), 0, len);
! 482: buffer_free(&b);
! 483: if (lenp != NULL)
! 484: *lenp = len;
! 485: if (blobp != NULL)
! 486: *blobp = buf;
! 487: return len;
! 488: }
! 489:
! 490: void
! 491: mm_send_kex(Buffer *m, Kex *kex)
! 492: {
! 493: buffer_put_string(m, kex->session_id, kex->session_id_len);
! 494: buffer_put_int(m, kex->we_need);
! 495: buffer_put_int(m, kex->hostkey_type);
! 496: buffer_put_int(m, kex->kex_type);
! 497: buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
! 498: buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
! 499: buffer_put_int(m, kex->flags);
! 500: buffer_put_cstring(m, kex->client_version_string);
! 501: buffer_put_cstring(m, kex->server_version_string);
! 502: }
! 503:
! 504: void
! 505: mm_send_keystate(struct monitor *monitor)
! 506: {
! 507: Buffer m;
! 508: u_char *blob, *p;
! 509: u_int bloblen, plen;
! 510:
! 511: buffer_init(&m);
! 512:
! 513: if (!compat20) {
! 514: u_char iv[24];
! 515: int ivlen;
! 516:
! 517: buffer_put_int(&m, packet_get_protocol_flags());
! 518:
! 519: buffer_put_int(&m, packet_get_ssh1_cipher());
! 520:
! 521: debug3("%s: Sending ssh1 IV", __FUNCTION__);
! 522: ivlen = packet_get_keyiv_len(MODE_OUT);
! 523: packet_get_keyiv(MODE_OUT, iv, ivlen);
! 524: buffer_put_string(&m, iv, ivlen);
! 525: ivlen = packet_get_keyiv_len(MODE_OUT);
! 526: packet_get_keyiv(MODE_IN, iv, ivlen);
! 527: buffer_put_string(&m, iv, ivlen);
! 528: goto skip;
! 529: } else {
! 530: /* Kex for rekeying */
! 531: mm_send_kex(&m, *monitor->m_pkex);
! 532: }
! 533:
! 534: debug3("%s: Sending new keys: %p %p",
! 535: __FUNCTION__, newkeys[MODE_OUT], newkeys[MODE_IN]);
! 536:
! 537: /* Keys from Kex */
! 538: if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
! 539: fatal("%s: conversion of newkeys failed", __FUNCTION__);
! 540:
! 541: buffer_put_string(&m, blob, bloblen);
! 542: xfree(blob);
! 543:
! 544: if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
! 545: fatal("%s: conversion of newkeys failed", __FUNCTION__);
! 546:
! 547: buffer_put_string(&m, blob, bloblen);
! 548: xfree(blob);
! 549:
! 550: buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
! 551: buffer_put_int(&m, packet_get_seqnr(MODE_IN));
! 552:
! 553: debug3("%s: New keys have been sent", __FUNCTION__);
! 554: skip:
! 555: /* More key context */
! 556: plen = packet_get_keycontext(MODE_OUT, NULL);
! 557: p = xmalloc(plen+1);
! 558: packet_get_keycontext(MODE_OUT, p);
! 559: buffer_put_string(&m, p, plen);
! 560: xfree(p);
! 561:
! 562: plen = packet_get_keycontext(MODE_IN, NULL);
! 563: p = xmalloc(plen+1);
! 564: packet_get_keycontext(MODE_IN, p);
! 565: buffer_put_string(&m, p, plen);
! 566: xfree(p);
! 567:
! 568: /* Compression state */
! 569: debug3("%s: Sending compression state", __FUNCTION__);
! 570: buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
! 571: buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
! 572:
! 573: /* Network I/O buffers */
! 574: buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
! 575: buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
! 576:
! 577: mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
! 578: debug3("%s: Finished sending state", __FUNCTION__);
! 579:
! 580: buffer_free(&m);
! 581: }
! 582:
! 583: int
! 584: mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
! 585: {
! 586: Buffer m;
! 587: u_char *p;
! 588: int success = 0;
! 589:
! 590: buffer_init(&m);
! 591: mm_request_send(monitor->m_recvfd, MONITOR_REQ_PTY, &m);
! 592:
! 593: debug3("%s: waiting for MONITOR_ANS_PTY", __FUNCTION__);
! 594: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_PTY, &m);
! 595:
! 596: success = buffer_get_int(&m);
! 597: if (success == 0) {
! 598: debug3("%s: pty alloc failed", __FUNCTION__);
! 599: buffer_free(&m);
! 600: return (0);
! 601: }
! 602: p = buffer_get_string(&m, NULL);
! 603: buffer_free(&m);
! 604:
! 605: strlcpy(namebuf, p, namebuflen); /* Possible truncation */
! 606: xfree(p);
! 607:
! 608: *ptyfd = mm_receive_fd(monitor->m_recvfd);
! 609: *ttyfd = mm_receive_fd(monitor->m_recvfd);
! 610:
! 611: /* Success */
! 612: return (1);
! 613: }
! 614:
! 615: void
! 616: mm_session_pty_cleanup2(void *session)
! 617: {
! 618: Session *s = session;
! 619: Buffer m;
! 620:
! 621: if (s->ttyfd == -1)
! 622: return;
! 623: buffer_init(&m);
! 624: buffer_put_cstring(&m, s->tty);
! 625: mm_request_send(monitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
! 626: buffer_free(&m);
! 627:
! 628: /* closed dup'ed master */
! 629: if (close(s->ptymaster) < 0)
! 630: error("close(s->ptymaster): %s", strerror(errno));
! 631:
! 632: /* unlink pty from session */
! 633: s->ttyfd = -1;
! 634: }
! 635:
! 636: /* Request process termination */
! 637:
! 638: void
! 639: mm_terminate(void)
! 640: {
! 641: Buffer m;
! 642:
! 643: buffer_init(&m);
! 644: mm_request_send(monitor->m_recvfd, MONITOR_REQ_TERM, &m);
! 645: buffer_free(&m);
! 646: }
! 647:
! 648: int
! 649: mm_ssh1_session_key(BIGNUM *num)
! 650: {
! 651: int rsafail;
! 652: Buffer m;
! 653:
! 654: buffer_init(&m);
! 655: buffer_put_bignum2(&m, num);
! 656: mm_request_send(monitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
! 657:
! 658: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
! 659:
! 660: rsafail = buffer_get_int(&m);
! 661: buffer_get_bignum2(&m, num);
! 662:
! 663: buffer_free(&m);
! 664:
! 665: return (rsafail);
! 666: }
! 667:
! 668: void
! 669: mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
! 670: char ***prompts, u_int **echo_on)
! 671: {
! 672: *name = xstrdup("");
! 673: *infotxt = xstrdup("");
! 674: *numprompts = 1;
! 675: *prompts = xmalloc(*numprompts * sizeof(char*));
! 676: *echo_on = xmalloc(*numprompts * sizeof(u_int));
! 677: (*echo_on)[0] = 0;
! 678: }
! 679:
! 680: int
! 681: mm_bsdauth_query(void *ctx, char **name, char **infotxt,
! 682: u_int *numprompts, char ***prompts, u_int **echo_on)
! 683: {
! 684: Buffer m;
! 685: int res;
! 686: char *challenge;
! 687:
! 688: debug3("%s: entering", __FUNCTION__);
! 689:
! 690: buffer_init(&m);
! 691: mm_request_send(monitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
! 692:
! 693: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
! 694: &m);
! 695: res = buffer_get_int(&m);
! 696: if (res == -1) {
! 697: debug3("%s: no challenge", __FUNCTION__);
! 698: buffer_free(&m);
! 699: return (-1);
! 700: }
! 701:
! 702: /* Get the challenge, and format the response */
! 703: challenge = buffer_get_string(&m, NULL);
! 704: buffer_free(&m);
! 705:
! 706: mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
! 707: (*prompts)[0] = challenge;
! 708:
! 709: debug3("%s: received challenge: %s", __FUNCTION__, challenge);
! 710:
! 711: return (0);
! 712: }
! 713:
! 714: int
! 715: mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
! 716: {
! 717: Buffer m;
! 718: int authok;
! 719:
! 720: debug3("%s: entering", __FUNCTION__);
! 721: if (numresponses != 1)
! 722: return (-1);
! 723:
! 724: buffer_init(&m);
! 725: buffer_put_cstring(&m, responses[0]);
! 726: mm_request_send(monitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
! 727:
! 728: mm_request_receive_expect(monitor->m_recvfd,
! 729: MONITOR_ANS_BSDAUTHRESPOND, &m);
! 730:
! 731: authok = buffer_get_int(&m);
! 732: buffer_free(&m);
! 733:
! 734: return ((authok == 0) ? -1 : 0);
! 735: }
! 736:
! 737: int
! 738: mm_skey_query(void *ctx, char **name, char **infotxt,
! 739: u_int *numprompts, char ***prompts, u_int **echo_on)
! 740: {
! 741: Buffer m;
! 742: int len, res;
! 743: char *p, *challenge;
! 744:
! 745: debug3("%s: entering", __FUNCTION__);
! 746:
! 747: buffer_init(&m);
! 748: mm_request_send(monitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
! 749:
! 750: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
! 751: &m);
! 752: res = buffer_get_int(&m);
! 753: if (res == -1) {
! 754: debug3("%s: no challenge", __FUNCTION__);
! 755: buffer_free(&m);
! 756: return (-1);
! 757: }
! 758:
! 759: /* Get the challenge, and format the response */
! 760: challenge = buffer_get_string(&m, NULL);
! 761: buffer_free(&m);
! 762:
! 763: debug3("%s: received challenge: %s", __FUNCTION__, challenge);
! 764:
! 765: mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
! 766:
! 767: len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
! 768: p = xmalloc(len);
! 769: strlcpy(p, challenge, len);
! 770: strlcat(p, SKEY_PROMPT, len);
! 771: (*prompts)[0] = p;
! 772: xfree(challenge);
! 773:
! 774: return (0);
! 775: }
! 776:
! 777: int
! 778: mm_skey_respond(void *ctx, u_int numresponses, char **responses)
! 779: {
! 780: Buffer m;
! 781: int authok;
! 782:
! 783: debug3("%s: entering", __FUNCTION__);
! 784: if (numresponses != 1)
! 785: return (-1);
! 786:
! 787: buffer_init(&m);
! 788: buffer_put_cstring(&m, responses[0]);
! 789: mm_request_send(monitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
! 790:
! 791: mm_request_receive_expect(monitor->m_recvfd,
! 792: MONITOR_ANS_SKEYRESPOND, &m);
! 793:
! 794: authok = buffer_get_int(&m);
! 795: buffer_free(&m);
! 796:
! 797: return ((authok == 0) ? -1 : 0);
! 798: }
! 799:
! 800: void
! 801: mm_ssh1_session_id(u_char session_id[16])
! 802: {
! 803: Buffer m;
! 804: int i;
! 805:
! 806: debug3("%s entering", __FUNCTION__);
! 807:
! 808: buffer_init(&m);
! 809: for (i = 0; i < 16; i++)
! 810: buffer_put_char(&m, session_id[i]);
! 811:
! 812: mm_request_send(monitor->m_recvfd, MONITOR_REQ_SESSID, &m);
! 813: buffer_free(&m);
! 814: }
! 815:
! 816: int
! 817: mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
! 818: {
! 819: Buffer m;
! 820: Key *key;
! 821: u_char *blob;
! 822: u_int blen;
! 823: int allowed = 0;
! 824:
! 825: debug3("%s entering", __FUNCTION__);
! 826:
! 827: buffer_init(&m);
! 828: buffer_put_bignum2(&m, client_n);
! 829:
! 830: mm_request_send(monitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
! 831: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
! 832:
! 833: allowed = buffer_get_int(&m);
! 834:
! 835: if (allowed && rkey != NULL) {
! 836: blob = buffer_get_string(&m, &blen);
! 837: if ((key = key_from_blob(blob, blen)) == NULL)
! 838: fatal("%s: key_from_blob failed", __FUNCTION__);
! 839: *rkey = key;
! 840: xfree(blob);
! 841: }
! 842: mm_send_debug(&m);
! 843: buffer_free(&m);
! 844:
! 845: return (allowed);
! 846: }
! 847:
! 848: BIGNUM *
! 849: mm_auth_rsa_generate_challenge(Key *key)
! 850: {
! 851: Buffer m;
! 852: BIGNUM *challenge;
! 853: u_char *blob;
! 854: u_int blen;
! 855:
! 856: debug3("%s entering", __FUNCTION__);
! 857:
! 858: if ((challenge = BN_new()) == NULL)
! 859: fatal("%s: BN_new failed", __FUNCTION__);
! 860:
! 861: key->type = KEY_RSA; /* XXX cheat for key_to_blob */
! 862: if (key_to_blob(key, &blob, &blen) == 0)
! 863: fatal("%s: key_to_blob failed", __FUNCTION__);
! 864: key->type = KEY_RSA1;
! 865:
! 866: buffer_init(&m);
! 867: buffer_put_string(&m, blob, blen);
! 868: xfree(blob);
! 869:
! 870: mm_request_send(monitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
! 871: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
! 872:
! 873: buffer_get_bignum2(&m, challenge);
! 874: buffer_free(&m);
! 875:
! 876: return (challenge);
! 877: }
! 878:
! 879: int
! 880: mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
! 881: {
! 882: Buffer m;
! 883: u_char *blob;
! 884: u_int blen;
! 885: int success = 0;
! 886:
! 887: debug3("%s entering", __FUNCTION__);
! 888:
! 889: key->type = KEY_RSA; /* XXX cheat for key_to_blob */
! 890: if (key_to_blob(key, &blob, &blen) == 0)
! 891: fatal("%s: key_to_blob failed", __FUNCTION__);
! 892: key->type = KEY_RSA1;
! 893:
! 894: buffer_init(&m);
! 895: buffer_put_string(&m, blob, blen);
! 896: buffer_put_string(&m, response, 16);
! 897: xfree(blob);
! 898:
! 899: mm_request_send(monitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
! 900: mm_request_receive_expect(monitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
! 901:
! 902: success = buffer_get_int(&m);
! 903: buffer_free(&m);
! 904:
! 905: return (success);
! 906: }