11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: sshconnect2.c,v 1.188 2011/05/24 07:15:47 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000 Markus Friedl. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2008 Damien Miller. All rights reserved. 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/wait.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/stat.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h> 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netdb.h> 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h> 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <vis.h> 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h" 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h" 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h" 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "myproposal.h" 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshconnect.h" 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfile.h" 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dh.h" 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "authfd.h" 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "readconf.h" 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h" 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dispatch.h" 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "canohost.h" 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "msg.h" 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "pathnames.h" 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "uidswap.h" 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "hostfile.h" 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "schnorr.h" 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "jpake.h" 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-gss.h" 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* import */ 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *client_version_string; 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *server_version_string; 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Options options; 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH2 key exchange 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_char *session_id2 = NULL; 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int session_id2_len = 0; 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *xxx_host; 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct sockaddr *xxx_hostaddr; 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodKex *xxx_kex = NULL; 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodverify_host_key_callback(Key *hostkey) 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Host key verification failed."); 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodorder_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *oavail, *avail, *first, *last, *alg, *hostname, *ret; 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t maxlen; 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct hostkeys *hostkeys; 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ktype; 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Find all hostkeys for this hostname */ 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostkeys = init_hostkeys(); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.num_user_hostfiles; i++) 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.num_system_hostfiles; i++) 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood maxlen = strlen(avail) + 1; 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood first = xmalloc(maxlen); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood last = xmalloc(maxlen); 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *first = *last = '\0'; 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define ALG_APPEND(to, from) \ 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do { \ 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*to != '\0') \ 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(to, ",", maxlen); \ 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(to, from, maxlen); \ 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } while (0) 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((alg = strsep(&avail, ",")) && *alg != '\0') { 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ktype = key_type_from_name(alg)) == KEY_UNSPEC) 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: unknown alg %s", __func__, alg); 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (lookup_key_in_hostkeys_by_type(hostkeys, 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_type_plain(ktype), NULL)) 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ALG_APPEND(first, alg); 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ALG_APPEND(last, alg); 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#undef ALG_APPEND 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xasprintf(&ret, "%s%s%s", first, *first == '\0' ? "" : ",", last); 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*first != '\0') 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: prefer hostkeyalgs: %s", __func__, first); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(first); 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(last); 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(hostname); 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(oavail); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_hostkeys(hostkeys); 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Kex *kex; 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xxx_host = host; 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xxx_hostaddr = hostaddr; 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.ciphers == (char *)-1) { 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("No valid ciphers for protocol version 2 given, using defaults."); 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.ciphers = NULL; 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.ciphers != NULL) { 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_ENC_ALGS_CTOS] = 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_ENC_ALGS_CTOS] = 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_ENC_ALGS_STOC] = 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.compression) { 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_COMP_ALGS_CTOS] = 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_COMP_ALGS_CTOS] = 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib"; 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.macs != NULL) { 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_MAC_ALGS_CTOS] = 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.hostkeyalgorithms != NULL) 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.hostkeyalgorithms; 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Prefer algorithms that we already have keys for */ 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood order_hostkeyalgs(host, hostaddr, port); 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.kex_algorithms != NULL) 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.rekey_limit) 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_set_rekey_limit((u_int32_t)options.rekey_limit); 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* start key exchange */ 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex = kex_setup(myproposal); 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->kex[KEX_ECDH_SHA2] = kexecdh_client; 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->client_version_string=client_version_string; 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->server_version_string=server_version_string; 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->verify_host_key=&verify_host_key_callback; 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xxx_kex = kex; 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_run(DISPATCH_BLOCK, &kex->done, kex); 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_roaming && !kex->roaming) { 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Roaming not allowed by server"); 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.use_roaming = 0; 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_id2 = kex->session_id; 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_id2_len = kex->session_id_len; 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send 1st encrypted/maced/compressed message */ 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_IGNORE); 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("markus"); 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Authenticate user 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct Authctxt Authctxt; 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct Authmethod Authmethod; 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct identity Identity; 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtypedef struct idlist Idlist; 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct identity { 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_ENTRY(identity) next; 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AuthenticationConnection *ac; /* set if agent supports key */ 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; /* public/private key */ 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *filename; /* comment for agent-only keys */ 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int tried; 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int isprivate; /* key points to the private key */ 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodTAILQ_HEAD(idlist, identity); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct Authctxt { 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *server_user; 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *local_user; 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *host; 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *service; 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authmethod *method; 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sig_atomic_t success; 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *authlist; 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* pubkey */ 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idlist keys; 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AuthenticationConnection *agent; 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* hostbased */ 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Sensitive *sensitive; 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* kbd-interactive */ 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int info_req_seen; 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* generic */ 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood void *methoddata; 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct Authmethod { 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name; /* string to compare against server's list */ 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int (*userauth)(Authctxt *authctxt); 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood void (*cleanup)(Authctxt *authctxt); 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int *enabled; /* flag in option struct that enables method */ 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int *batch_flag; /* flag in option struct that disables method */ 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_success(int, u_int32_t, void *); 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_success_unexpected(int, u_int32_t, void *); 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_failure(int, u_int32_t, void *); 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_banner(int, u_int32_t, void *); 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_error(int, u_int32_t, void *); 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_info_req(int, u_int32_t, void *); 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_pk_ok(int, u_int32_t, void *); 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_passwd_changereq(int, u_int32_t, void *); 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_jpake_server_step1(int, u_int32_t, void *); 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_jpake_server_step2(int, u_int32_t, void *); 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_userauth_jpake_server_confirm(int, u_int32_t, void *); 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_none(Authctxt *); 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_pubkey(Authctxt *); 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_passwd(Authctxt *); 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_kbdint(Authctxt *); 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_hostbased(Authctxt *); 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_jpake(Authctxt *); 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid userauth_jpake_cleanup(Authctxt *); 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint userauth_gssapi(Authctxt *authctxt); 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_gssapi_response(int type, u_int32_t, void *); 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_gssapi_token(int type, u_int32_t, void *); 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_gssapi_hash(int type, u_int32_t, void *); 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_gssapi_error(int, u_int32_t, void *); 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid input_gssapi_errtok(int, u_int32_t, void *); 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid userauth(Authctxt *, char *); 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int sign_and_send_pubkey(Authctxt *, Identity *); 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void pubkey_prepare(Authctxt *); 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void pubkey_cleanup(Authctxt *); 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Key *load_identity_file(char *); 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Authmethod *authmethod_get(char *authlist); 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Authmethod *authmethod_lookup(const char *name); 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *authmethods_get(void); 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodAuthmethod authmethods[] = { 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"gssapi-with-mic", 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_gssapi, 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.gss_authentication, 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL}, 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"hostbased", 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_hostbased, 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.hostbased_authentication, 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL}, 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"publickey", 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_pubkey, 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.pubkey_authentication, 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL}, 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef JPAKE 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"jpake-01@openssh.com", 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_jpake, 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_jpake_cleanup, 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.zero_knowledge_password_authentication, 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.batch_mode}, 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"keyboard-interactive", 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_kbdint, 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.kbd_interactive_authentication, 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.batch_mode}, 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"password", 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_passwd, 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.password_authentication, 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &options.batch_mode}, 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {"none", 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_none, 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL, 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood NULL}, 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood {NULL, NULL, NULL, NULL, NULL} 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_userauth2(const char *local_user, const char *server_user, char *host, 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Sensitive *sensitive) 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt authctxt; 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int type; 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.challenge_response_authentication) 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.kbd_interactive_authentication = 1; 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_SERVICE_REQUEST); 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring("ssh-userauth"); 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("SSH2_MSG_SERVICE_REQUEST sent"); 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = packet_read(); 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (type != SSH2_MSG_SERVICE_ACCEPT) 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Server denied authentication request: %d", type); 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_remaining() > 0) { 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *reply = packet_get_string(NULL); 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("service_accept: %s", reply); 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(reply); 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("buggy server: service_accept w/o service"); 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("SSH2_MSG_SERVICE_ACCEPT received"); 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.preferred_authentications == NULL) 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.preferred_authentications = authmethods_get(); 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* setup authentication context */ 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&authctxt, 0, sizeof(authctxt)); 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pubkey_prepare(&authctxt); 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.server_user = server_user; 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.local_user = local_user; 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.host = host; 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.service = "ssh-connection"; /* service name */ 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.success = 0; 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.method = authmethod_lookup("none"); 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.authlist = NULL; 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.methoddata = NULL; 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.sensitive = sensitive; 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt.info_req_seen = 0; 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt.method == NULL) 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ssh_userauth2: internal error: cannot send userauth none request"); 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* initial userauth request */ 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_none(&authctxt); 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_init(&input_userauth_error); 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pubkey_cleanup(&authctxt); 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Authentication succeeded (%s).", authctxt.method->name); 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth(Authctxt *authctxt, char *authlist) 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->method != NULL && authctxt->method->cleanup != NULL) 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->method->cleanup(authctxt); 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->methoddata) { 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(authctxt->methoddata); 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->methoddata = NULL; 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authlist == NULL) { 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authlist = authctxt->authlist; 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->authlist) 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(authctxt->authlist); 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->authlist = authlist; 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (;;) { 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authmethod *method = authmethod_get(authlist); 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (method == NULL) 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Permission denied (%s).", authlist); 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->method = method; 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* reset the per method handler */ 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* and try new method */ 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (method->userauth(authctxt) != 0) { 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("we sent a %s packet, wait for reply", method->name); 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("we did not send a packet, disable method"); 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood method->enabled = NULL; 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_error(int type, u_int32_t seq, void *ctxt) 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_error: bad message during authentication: " 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "type %d", type); 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_banner(int type, u_int32_t seq, void *ctxt) 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *msg, *raw, *lang; 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("input_userauth_banner"); 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood raw = packet_get_string(&len); 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lang = packet_get_string(NULL); 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len > 65536) 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 65536; 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "%s", msg); 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(msg); 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(raw); 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(lang); 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_success(int type, u_int32_t seq, void *ctxt) 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_success: no authentication context"); 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->authlist) { 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(authctxt->authlist); 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->authlist = NULL; 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->method != NULL && authctxt->method->cleanup != NULL) 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->method->cleanup(authctxt); 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->methoddata) { 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(authctxt->methoddata); 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->methoddata = NULL; 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->success = 1; /* break out */ 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: no authentication context", __func__); 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unexpected authentication success during %s.", 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->method->name); 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_failure(int type, u_int32_t seq, void *ctxt) 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *authlist = NULL; 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int partial; 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_failure: no authentication context"); 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authlist = packet_get_string(NULL); 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood partial = packet_get_char(); 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (partial != 0) 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Authenticated with partial success."); 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Authentications that can continue: %s", authlist); 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth(authctxt, authlist); 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key = NULL; 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id = NULL; 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int pktype, sent = 0; 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int alen, blen; 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *pkalg, *fp; 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *pkblob; 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_pk_ok: no authentication context"); 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_BUG_PKOK) { 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* this is similar to SSH_BUG_PKAUTH */ 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkblob = packet_get_string(&blen); 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, pkblob, blen); 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkalg = buffer_get_string(&b, &alen); 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkalg = packet_get_string(&alen); 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkblob = packet_get_string(&blen); 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Server accepts key: pkalg %s blen %u", pkalg, blen); 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("unknown pkalg %s", pkalg); 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto done; 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((key = key_from_blob(pkblob, blen)) == NULL) { 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("no key from blob. pkalg %s", pkalg); 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto done; 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key->type != pktype) { 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("input_userauth_pk_ok: type mismatch " 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "for decoded key (received %d, expected %d)", 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key->type, pktype); 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto done; 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("input_userauth_pk_ok: fp %s", fp); 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(fp); 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * search keys in the reverse order, because last candidate has been 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * moved to the end of the queue. this also avoids confusion by 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * duplicate keys 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal(key, id->key)) { 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sent = sign_and_send_pubkey(authctxt, id); 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddone: 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key != NULL) 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pkalg); 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pkblob); 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* try another method if we did not send a packet */ 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sent == 0) 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth(authctxt, NULL); 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_gssapi(Authctxt *authctxt) 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Gssctxt *gssctxt = NULL; 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static gss_OID_set gss_supported = NULL; 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static u_int mech = 0; 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OM_uint32 min; 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ok = 0; 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Try one GSSAPI method at a time, rather than sending them all at 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * once. */ 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (gss_supported == NULL) 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_indicate_mechs(&min, &gss_supported); 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Check to see if the mechanism is usable before we offer it */ 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (mech < gss_supported->count && !ok) { 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* My DER encoding requires length<128 */ 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (gss_supported->elements[mech].length < 128 && 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_gssapi_check_mechanism(&gssctxt, 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &gss_supported->elements[mech], authctxt->host)) { 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ok = 1; /* Mechanism works */ 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mech++; 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!ok) 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->methoddata=(void *)gssctxt; 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(1); 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int((gss_supported->elements[mech].length) + 2); 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(SSH_GSS_OIDTYPE); 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(gss_supported->elements[mech].length); 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_raw(gss_supported->elements[mech].elements, 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_supported->elements[mech].length); 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mech++; /* Move along to next candidate */ 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic OM_uint32 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodprocess_gssapi_token(void *ctxt, gss_buffer_t recv_tok) 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Gssctxt *gssctxt = authctxt->methoddata; 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc gssbuf; 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OM_uint32 status, ms, flags; 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood recv_tok, &send_tok, &flags); 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (send_tok.length > 0) { 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (GSS_ERROR(status)) 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(send_tok.value, send_tok.length); 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_release_buffer(&ms, &send_tok); 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (status == GSS_S_COMPLETE) { 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send either complete or MIC, depending on mechanism */ 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(flags & GSS_C_INTEG_FLAG)) { 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_gssapi_buildmic(&b, authctxt->server_user, 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->service, "gssapi-with-mic"); 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gssbuf.value = buffer_ptr(&b); 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gssbuf.length = buffer_len(&b); 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!GSS_ERROR(status)) { 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(mic.value, mic.length); 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_release_buffer(&ms, &mic); 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return status; 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_gssapi_response(int type, u_int32_t plen, void *ctxt) 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Gssctxt *gssctxt; 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int oidlen; 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *oidv; 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_gssapi_response: no authentication context"); 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gssctxt = authctxt->methoddata; 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Setup our OID */ 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood oidv = packet_get_string(&oidlen); 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (oidlen <= 2 || 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood oidv[0] != SSH_GSS_OIDTYPE || 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood oidv[1] != oidlen - 2) { 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(oidv); 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Badly encoded mechanism OID received"); 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth(authctxt, NULL); 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Server returned different OID than expected"); 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(oidv); 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Start again with next method on list */ 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Trying to start again"); 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth(authctxt, NULL); 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_gssapi_token(int type, u_int32_t plen, void *ctxt) 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc recv_tok; 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OM_uint32 status; 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int slen; 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_gssapi_response: no authentication context"); 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood recv_tok.value = packet_get_string(&slen); 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood recv_tok.length = slen; /* safe typecast */ 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood status = process_gssapi_token(ctxt, &recv_tok); 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(recv_tok.value); 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (GSS_ERROR(status)) { 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Start again with the next method in the list */ 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth(authctxt, NULL); 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Gssctxt *gssctxt; 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_buffer_desc recv_tok; 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OM_uint32 status, ms; 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_gssapi_response: no authentication context"); 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gssctxt = authctxt->methoddata; 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood recv_tok.value = packet_get_string(&len); 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood recv_tok.length = len; 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Stick it into GSSAPI and see what it says */ 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &recv_tok, &send_tok, NULL); 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(recv_tok.value); 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gss_release_buffer(&ms, &send_tok); 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Server will be returning a failed packet after this one */ 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_gssapi_error(int type, u_int32_t plen, void *ctxt) 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood OM_uint32 maj, min; 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *msg; 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *lang; 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood maj=packet_get_int(); 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood min=packet_get_int(); 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood msg=packet_get_string(NULL); 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lang=packet_get_string(NULL); 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Server GSSAPI Error:\n%s", msg); 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(msg); 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(lang); 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* GSSAPI */ 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_none(Authctxt *authctxt) 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* initial userauth request */ 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_passwd(Authctxt *authctxt) 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int attempt = 0; 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char prompt[150]; 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *password; 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *host = options.host_key_alias ? options.host_key_alias : 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->host; 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt++ >= options.number_of_password_prompts) 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt != 1) 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Permission denied, please try again."); 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->server_user, host); 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = read_passphrase(prompt, 0); 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(0); 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(password); 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(password, 0, strlen(password)); 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(password); 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_add_padding(64); 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &input_userauth_passwd_changereq); 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *info, *lang, *password = NULL, *retype = NULL; 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char prompt[150]; 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *host = options.host_key_alias ? options.host_key_alias : 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->host; 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("input_userauth_passwd_changereq"); 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_passwd_changereq: " 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "no authentication context"); 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood info = packet_get_string(NULL); 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lang = packet_get_string(NULL); 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlen(info) > 0) 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("%s", info); 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(info); 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(lang); 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(1); /* additional info */ 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof(prompt), 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Enter %.30s@%.128s's old password: ", 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->server_user, host); 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = read_passphrase(prompt, 0); 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(password); 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(password, 0, strlen(password)); 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(password); 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = NULL; 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (password == NULL) { 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof(prompt), 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Enter %.30s@%.128s's new password: ", 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->server_user, host); 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = read_passphrase(prompt, RP_ALLOW_EOF); 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (password == NULL) { 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* bail out */ 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof(prompt), 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Retype %.30s@%.128s's new password: ", 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->server_user, host); 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood retype = read_passphrase(prompt, 0); 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(password, retype) != 0) { 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(password, 0, strlen(password)); 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(password); 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Mismatch; try again, EOF to quit."); 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = NULL; 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(retype, 0, strlen(retype)); 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(retype); 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(password); 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(password, 0, strlen(password)); 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(password); 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_add_padding(64); 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &input_userauth_passwd_changereq); 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef JPAKE 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpw_encrypt(const char *password, const char *crypt_scheme, const char *salt) 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* OpenBSD crypt(3) handles all of these */ 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(crypt_scheme, "crypt") == 0 || 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(crypt_scheme, "bcrypt") == 0 || 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(crypt_scheme, "md5crypt") == 0 || 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(crypt_scheme, "crypt-extended") == 0) 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return xstrdup(crypt(password, salt)); 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: unsupported password encryption scheme \"%.100s\"", 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, crypt_scheme); 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic BIGNUM * 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodjpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme, 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *salt) 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char prompt[256], *password, *crypted; 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *secret; 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int secret_len; 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *ret; 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ", 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->server_user, authctxt->host); 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood password = read_passphrase(prompt, 0); 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) { 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Disabling %s authentication", authctxt->method->name); 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->method->enabled = NULL; 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Continue with an empty password to fail gracefully */ 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood crypted = xstrdup(""); 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef JPAKE_DEBUG 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: salt = %s", __func__, salt); 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: scheme = %s", __func__, crypt_scheme); 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: crypted = %s", __func__, crypted); 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hash_buffer(crypted, strlen(crypted), EVP_sha256(), 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &secret, &secret_len) != 0) 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: hash_buffer", __func__); 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(password, strlen(password)); 10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(crypted, strlen(crypted)); 10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(password); 10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(crypted); 10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL) 10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_bin2bn (secret)", __func__); 10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(secret, secret_len); 10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(secret); 10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt) 10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct jpake_ctx *pctx = authctxt->methoddata; 10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *x3_proof, *x4_proof, *x2_s_proof; 10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int x3_proof_len, x4_proof_len, x2_s_proof_len; 10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *crypt_scheme, *salt; 10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Disable this message */ 10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL); 10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pctx->g_x3 = BN_new()) == NULL || 10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (pctx->g_x4 = BN_new()) == NULL) 10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new", __func__); 10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fetch step 1 values */ 10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood crypt_scheme = packet_get_string(NULL); 10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood salt = packet_get_string(NULL); 10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->server_id = packet_get_string(&pctx->server_id_len); 10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_bignum2(pctx->g_x3); 10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_bignum2(pctx->g_x4); 10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x3_proof = packet_get_string(&x3_proof_len); 10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x4_proof = packet_get_string(&x4_proof_len); 10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); 10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Obtain password and derive secret */ 10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt); 10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(crypt_scheme, strlen(crypt_scheme)); 10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(salt, strlen(salt)); 10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(crypt_scheme); 10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(salt); 10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__)); 10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Calculate step 2 values */ 10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood jpake_step2(pctx->grp, pctx->s, pctx->g_x1, 10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->g_x3, pctx->g_x4, pctx->x2, 10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->server_id, pctx->server_id_len, 10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->client_id, pctx->client_id_len, 10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x3_proof, x3_proof_len, 10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x4_proof, x4_proof_len, 10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &pctx->a, 10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &x2_s_proof, &x2_s_proof_len); 10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x3_proof, x3_proof_len); 10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x4_proof, x4_proof_len); 10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x3_proof); 10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x4_proof); 10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); 10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send values for step 2 */ 10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2); 10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_bignum2(pctx->a); 10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(x2_s_proof, x2_s_proof_len); 10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x2_s_proof, x2_s_proof_len); 10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x2_s_proof); 10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Expect step 2 packet from peer */ 10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, 10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input_userauth_jpake_server_step2); 10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt) 10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct jpake_ctx *pctx = authctxt->methoddata; 11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *x4_s_proof; 11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int x4_s_proof_len; 11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Disable this message */ 11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL); 11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pctx->b = BN_new()) == NULL) 11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new", __func__); 11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fetch step 2 values */ 11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_bignum2(pctx->b); 11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x4_s_proof = packet_get_string(&x4_s_proof_len); 11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); 11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Derive shared key and calculate confirmation hash */ 11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood jpake_key_confirm(pctx->grp, pctx->s, pctx->b, 11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4, 11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->client_id, pctx->client_id_len, 11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->server_id, pctx->server_id_len, 11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_id2, session_id2_len, 11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood x4_s_proof, x4_s_proof_len, 11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &pctx->k, 11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len); 11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x4_s_proof, x4_s_proof_len); 11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x4_s_proof); 11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); 11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Send key confirmation proof */ 11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM); 11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); 11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Expect confirmation from peer */ 11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, 11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input_userauth_jpake_server_confirm); 11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* ARGSUSED */ 11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt) 11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct jpake_ctx *pctx = authctxt->methoddata; 11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Disable this message */ 11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL); 11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len); 11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); 11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Verify expected confirmation hash */ 11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (jpake_check_confirm(pctx->k, 11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->server_id, pctx->server_id_len, 11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_id2, session_id2_len, 11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1) 11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: %s success", __func__, authctxt->method->name); 11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: confirmation mismatch", __func__); 11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX stash this so if auth succeeds then we can warn/kill */ 11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood userauth_jpake_cleanup(authctxt); 11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* JPAKE */ 11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodidentity_sign(Identity *id, u_char **sigp, u_int *lenp, 11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *data, u_int datalen) 11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *prv; 11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret; 11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* the agent supports this key */ 11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->ac) 11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (ssh_agent_sign(id->ac, id->key, sigp, lenp, 11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood data, datalen)); 11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * we have already loaded the private key or 11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the private key is stored in external hardware 11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) 11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (key_sign(id->key, sigp, lenp, data, datalen)); 11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* load the private key from the file */ 11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((prv = load_identity_file(id->filename)) == NULL) 11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = key_sign(prv, sigp, lenp, data, datalen); 11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(prv); 11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (ret); 11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsign_and_send_pubkey(Authctxt *authctxt, Identity *id) 11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob, *signature; 12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int bloblen, slen; 12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int skip = 0; 12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret = -1; 12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int have_sig = 1; 12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *fp; 12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); 12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); 12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(fp); 12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_to_blob(id->key, &blob, &bloblen) == 0) { 12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* we cannot handle this key */ 12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("sign_and_send_pubkey: cannot handle key"); 12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* data to be signed */ 12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_OLD_SESSIONID) { 12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, session_id2, session_id2_len); 12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood skip = session_id2_len; 12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, session_id2, session_id2_len); 12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood skip = buffer_len(&b); 12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->server_user); 12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, 12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood datafellows & SSH_BUG_PKSERVICE ? 12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "ssh-userauth" : 12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->service); 12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_BUG_PKAUTH) { 12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, have_sig); 12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->method->name); 12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, have_sig); 12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_ssh_name(id->key)); 12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, blob, bloblen); 12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* generate signature */ 12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = identity_sign(id, &signature, &slen, 12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&b), buffer_len(&b)); 12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ret == -1) { 12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_dump(&b); 12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (datafellows & SSH_BUG_PKSERVICE) { 12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&b); 12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, session_id2, session_id2_len); 12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood skip = session_id2_len; 12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->server_user); 12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->service); 12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->method->name); 12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, have_sig); 12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(datafellows & SSH_BUG_PKAUTH)) 12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, key_ssh_name(id->key)); 12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, blob, bloblen); 12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* append signature */ 12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, signature, slen); 12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* skip session id and packet type */ 12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&b) < skip + 1) 12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("userauth_pubkey: internal error"); 12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_consume(&b, skip + 1); 12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* put remaining data from buffer into packet */ 12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_raw(buffer_ptr(&b), buffer_len(&b)); 12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsend_pubkey_test(Authctxt *authctxt, Identity *id) 12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *blob; 12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int bloblen, have_sig = 0; 12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("send_pubkey_test"); 12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_to_blob(id->key, &blob, &bloblen) == 0) { 12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* we cannot handle this key */ 12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("send_pubkey_test: cannot handle key"); 12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* register callback for USERAUTH_PK_OK message */ 12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); 12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(have_sig); 13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(datafellows & SSH_BUG_PKAUTH)) 13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(key_ssh_name(id->key)); 13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(blob, bloblen); 13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Key * 13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodload_identity_file(char *filename) 13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *private; 13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char prompt[300], *passphrase; 13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int perm_ok = 0, quit, i; 13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(filename, &st) < 0) { 13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("no such identity: %s", filename); 13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok); 13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!perm_ok) 13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (private == NULL) { 13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.batch_mode) 13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(prompt, sizeof prompt, 13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Enter passphrase for key '%.100s': ", filename); 13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.number_of_password_prompts; i++) { 13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood passphrase = read_passphrase(prompt, 0); 13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(passphrase, "") != 0) { 13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood private = key_load_private_type(KEY_UNSPEC, 13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename, passphrase, NULL, NULL); 13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit = 0; 13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("no passphrase given, try next key"); 13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood quit = 1; 13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(passphrase, 0, strlen(passphrase)); 13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(passphrase); 13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (private != NULL || quit) 13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("bad passphrase given, try again..."); 13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return private; 13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * try keys in the following order: 13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. agent keys that are found in the config file 13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. other agent keys 13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3. keys that are only listed in the config file 13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpubkey_prepare(Authctxt *authctxt) 13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Idlist agent, files, *preferred; 13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *key; 13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood AuthenticationConnection *ac; 13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *comment; 13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, found; 13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INIT(&agent); /* keys from the agent */ 13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INIT(&files); /* keys from the config file */ 13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood preferred = &authctxt->keys; 13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INIT(preferred); /* preferred order of keys */ 13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* list of keys stored in the filesystem */ 13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.num_identity_files; i++) { 13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = options.identity_keys[i]; 13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key && key->type == KEY_RSA1) 13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) 13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.identity_keys[i] = NULL; 13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = xcalloc(1, sizeof(*id)); 13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = key; 13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->filename = xstrdup(options.identity_files[i]); 13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&files, id, next); 13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* list of keys supported by the agent */ 13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ac = ssh_get_authentication_connection())) { 13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (key = ssh_get_first_identity(ac, &comment, 2); 13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key != NULL; 13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key = ssh_get_next_identity(ac, &comment, 2)) { 13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood found = 0; 13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_FOREACH(id, &files, next) { 13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* agent keys from the config file are preferred */ 13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_equal(key, id->key)) { 13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(key); 13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(comment); 13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&files, id, next); 13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(preferred, id, next); 14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->ac = ac; 14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood found = 1; 14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!found && !options.identities_only) { 14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = xcalloc(1, sizeof(*id)); 14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = key; 14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->filename = comment; 14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->ac = ac; 14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&agent, id, next); 14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* append remaining agent keys */ 14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) { 14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&agent, id, next); 14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(preferred, id, next); 14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->agent = ac; 14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* append remaining keys from the config file */ 14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { 14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&files, id, next); 14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(preferred, id, next); 14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_FOREACH(id, preferred, next) { 14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("key: %s (%p)", id->filename, id->key); 14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpubkey_cleanup(Authctxt *authctxt) 14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->agent != NULL) 14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_close_authentication_connection(authctxt->agent); 14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (id = TAILQ_FIRST(&authctxt->keys); id; 14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id = TAILQ_FIRST(&authctxt->keys)) { 14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&authctxt->keys, id, next); 14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->key) 14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(id->key); 14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->filename) 14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id->filename); 14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(id); 14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_pubkey(Authctxt *authctxt) 14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Identity *id; 14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sent = 0; 14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while ((id = TAILQ_FIRST(&authctxt->keys))) { 14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->tried++) 14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* move key to the end of the queue */ 14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_REMOVE(&authctxt->keys, id, next); 14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TAILQ_INSERT_TAIL(&authctxt->keys, id, next); 14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * send a test message if we have the public key. for 14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * encrypted keys we cannot do this and have to load the 14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * private key instead 14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->key && id->key->type != KEY_RSA1) { 14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Offering %s public key: %s", key_type(id->key), 14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->filename); 14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sent = send_pubkey_test(authctxt, id); 14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (id->key == NULL) { 14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Trying private key: %s", id->filename); 14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = load_identity_file(id->filename); 14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id->key != NULL) { 14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->isprivate = 1; 14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sent = sign_and_send_pubkey(authctxt, id); 14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(id->key); 14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id->key = NULL; 14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sent) 14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (sent); 14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Send userauth request message specifying keyboard-interactive method. 14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_kbdint(Authctxt *authctxt) 14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int attempt = 0; 14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt++ >= options.number_of_password_prompts) 14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ 14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt > 1 && !authctxt->info_req_seen) { 14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("userauth_kbdint: disable: no info_req_seen"); 14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); 14991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 15001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("userauth_kbdint"); 15031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(""); /* lang */ 15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(options.kbd_interactive_devices ? 15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.kbd_interactive_devices : ""); 15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); 15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * parse INFO_REQUEST, prompt user and send INFO_RESPONSE 15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodinput_userauth_info_req(int type, u_int32_t seq, void *ctxt) 15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authctxt *authctxt = ctxt; 15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name, *inst, *lang, *prompt, *response; 15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int num_prompts, i; 15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int echo = 0; 15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("input_userauth_info_req"); 15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("input_userauth_info_req: no authentication context"); 15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->info_req_seen = 1; 15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood name = packet_get_string(NULL); 15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood inst = packet_get_string(NULL); 15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood lang = packet_get_string(NULL); 15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlen(name) > 0) 15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("%s", name); 15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlen(inst) > 0) 15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("%s", inst); 15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(inst); 15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(lang); 15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood num_prompts = packet_get_int(); 15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Begin to build info response packet based on prompts requested. 15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We commit to providing the correct number of responses, so if 15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * further on we run into a problem that prevents this, we have to 15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * be sure and clean this up and send a correct error response. 15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); 15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(num_prompts); 15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("input_userauth_info_req: num_prompts %d", num_prompts); 15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < num_prompts; i++) { 15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prompt = packet_get_string(NULL); 15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood echo = packet_get_char(); 15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood response = read_passphrase(prompt, echo ? RP_ECHO : 0); 15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(response); 15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(response, 0, strlen(response)); 15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(response); 15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(prompt); 15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); /* done with parsing incoming message. */ 15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_add_padding(64); 15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_keysign(Key *key, u_char **sigp, u_int *lenp, 15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *data, u_int datalen) 15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid; 15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int to[2], from[2], status, version = 2; 15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("ssh_keysign called"); 15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { 15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: not installed: %s", strerror(errno)); 15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fflush(stdout) != 0) 15891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: fflush: %s", strerror(errno)); 15901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pipe(to) < 0) { 15911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: pipe: %s", strerror(errno)); 15921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 15931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pipe(from) < 0) { 15951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: pipe: %s", strerror(errno)); 15961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 15971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pid = fork()) < 0) { 15991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: fork: %s", strerror(errno)); 16001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 16011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pid == 0) { 16031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* keep the socket on exec */ 16041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fcntl(packet_get_connection_in(), F_SETFD, 0); 16051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood permanently_drop_suid(getuid()); 16061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(from[0]); 16071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(from[1], STDOUT_FILENO) < 0) 16081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ssh_keysign: dup2: %s", strerror(errno)); 16091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(to[1]); 16101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(to[0], STDIN_FILENO) < 0) 16111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ssh_keysign: dup2: %s", strerror(errno)); 16121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(from[1]); 16131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(to[0]); 16141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); 16151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, 16161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 16171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(from[1]); 16191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(to[0]); 16201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 16221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ 16231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, data, datalen); 16241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ssh_msg_send(to[1], version, &b) == -1) 16251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ssh_keysign: couldn't send request"); 16261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ssh_msg_recv(from[0], &b) < 0) { 16281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: no reply"); 16291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 16301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 16311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(from[0]); 16331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(to[1]); 16341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (waitpid(pid, &status, 0) < 0) 16361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno != EINTR) 16371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_get_char(&b) != version) { 16401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ssh_keysign: bad version"); 16411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 16421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 16431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *sigp = buffer_get_string(&b, lenp); 16451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 16461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 16481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 16511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_hostbased(Authctxt *authctxt) 16521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *private = NULL; 16541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Sensitive *sensitive = authctxt->sensitive; 16551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 16561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *signature, *blob; 16571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *chost, *pkalg, *p; 16581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *service; 16591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int blen, slen; 16601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ok, i, found = 0; 16611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* check for a useful key */ 16631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sensitive->nkeys; i++) { 16641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood private = sensitive->keys[i]; 16651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (private && private->type != KEY_RSA1) { 16661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood found = 1; 16671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* we take and free the key */ 16681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sensitive->keys[i] = NULL; 16691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 16701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!found) { 16731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("No more client hostkeys for hostbased authentication."); 16741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 16751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_to_blob(private, &blob, &blen) == 0) { 16771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(private); 16781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 16791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* figure out a name for the client host */ 16811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = get_local_name(packet_get_connection_in()); 16821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (p == NULL) { 16831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("userauth_hostbased: cannot get local ipaddr/name"); 16841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(private); 16851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 16861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 16871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xasprintf(&chost, "%s.", p); 16891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("userauth_hostbased: chost %s", chost); 16901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(p); 16911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : 16931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->service; 16941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pkalg = xstrdup(key_ssh_name(private)); 16951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 16961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* construct data */ 16971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, session_id2, session_id2_len); 16981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 16991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->server_user); 17001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, service); 17011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->method->name); 17021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, pkalg); 17031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_string(&b, blob, blen); 17041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, chost); 17051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_put_cstring(&b, authctxt->local_user); 17061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_PK 17071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_dump(&b); 17081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 17091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sensitive->external_keysign) 17101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ok = ssh_keysign(private, &signature, &slen, 17111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&b), buffer_len(&b)); 17121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 17131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ok = key_sign(private, &signature, &slen, 17141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&b), buffer_len(&b)); 17151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_free(private); 17161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 17171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ok != 0) { 17181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("key_sign failed"); 17191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(chost); 17201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pkalg); 17211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 17221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 17231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 17251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 17261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 17271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 17281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(pkalg); 17291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(blob, blen); 17301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(chost); 17311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->local_user); 17321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(signature, slen); 17331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(signature, 's', slen); 17341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 17351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(chost); 17361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(pkalg); 17371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(blob); 17381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 17401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 17411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 17421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef JPAKE 17441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 17451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_jpake(Authctxt *authctxt) 17461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 17471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct jpake_ctx *pctx; 17481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *x1_proof, *x2_proof; 17491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int x1_proof_len, x2_proof_len; 17501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int attempt = 0; /* XXX share with userauth_password's? */ 17511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt++ >= options.number_of_password_prompts) 17531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 17541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (attempt != 1) 17551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Permission denied, please try again."); 17561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->methoddata != NULL) 17581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: authctxt->methoddata already set (%p)", 17591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, authctxt->methoddata); 17601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->methoddata = pctx = jpake_new(); 17621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Send request immediately, to get the protocol going while 17651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * we do the initial computations. 17661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_REQUEST); 17681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->server_user); 17691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->service); 17701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(authctxt->method->name); 17711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 17721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 17731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood jpake_step1(pctx->grp, 17751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &pctx->client_id, &pctx->client_id_len, 17761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2, 17771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &x1_proof, &x1_proof_len, 17781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &x2_proof, &x2_proof_len); 17791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); 17811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1); 17831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(pctx->client_id, pctx->client_id_len); 17841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_bignum2(pctx->g_x1); 17851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_bignum2(pctx->g_x2); 17861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(x1_proof, x1_proof_len); 17871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(x2_proof, x2_proof_len); 17881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 17891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x1_proof, x1_proof_len); 17911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(x2_proof, x2_proof_len); 17921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x1_proof); 17931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(x2_proof); 17941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Expect step 1 packet from peer */ 17961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, 17971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood input_userauth_jpake_server_step1); 17981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, 17991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &input_userauth_success_unexpected); 18001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 18021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 18051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooduserauth_jpake_cleanup(Authctxt *authctxt) 18061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: clean up", __func__); 18081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt->methoddata != NULL) { 18091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood jpake_free(authctxt->methoddata); 18101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->methoddata = NULL; 18111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); 18131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* JPAKE */ 18151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* find auth method */ 18171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 18191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * given auth method name, if configurable options permit this method fill 18201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * in auth_ident field and return true, otherwise return false. 18211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 18221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 18231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauthmethod_is_enabled(Authmethod *method) 18241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (method == NULL) 18261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* return false if options indicate this method is disabled */ 18281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (method->enabled == NULL || *method->enabled == 0) 18291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* return false if batch mode is enabled but method needs interactive mode */ 18311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (method->batch_flag != NULL && *method->batch_flag != 0) 18321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 18331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 18341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Authmethod * 18371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauthmethod_lookup(const char *name) 18381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authmethod *method = NULL; 18401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (name != NULL) 18411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (method = authmethods; method->name != NULL; method++) 18421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(name, method->name) == 0) 18431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return method; 18441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); 18451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* XXX internal state */ 18491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Authmethod *current = NULL; 18501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *supported = NULL; 18511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *preferred = NULL; 18521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 18541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Given the authentication method list sent by the server, return the 18551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * next method we should try. If the server initially sends a nil list, 18561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * use a built-in default list. 18571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 18581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Authmethod * 18591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauthmethod_get(char *authlist) 18601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name = NULL; 18621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int next; 18631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Use a suitable default if we're passed a nil list. */ 18651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authlist == NULL || strlen(authlist) == 0) 18661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authlist = options.preferred_authentications; 18671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (supported == NULL || strcmp(authlist, supported) != 0) { 18691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("start over, passed a different list %s", authlist); 18701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (supported != NULL) 18711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(supported); 18721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood supported = xstrdup(authlist); 18731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood preferred = options.preferred_authentications; 18741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("preferred %s", preferred); 18751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood current = NULL; 18761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (current != NULL && authmethod_is_enabled(current)) 18771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return current; 18781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (;;) { 18801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((name = match_list(preferred, supported, &next)) == NULL) { 18811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("No more authentication methods to try."); 18821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood current = NULL; 18831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood preferred += next; 18861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("authmethod_lookup %s", name); 18871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("remaining preferred: %s", preferred); 18881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((current = authmethod_lookup(name)) != NULL && 18891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authmethod_is_enabled(current)) { 18901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("authmethod_is_enabled %s", name); 18911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Next authentication method: %s", name); 18921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 18931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return current; 18941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (name != NULL) 18971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 18981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 19011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauthmethods_get(void) 19021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Authmethod *method = NULL; 19041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Buffer b; 19051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *list; 19061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_init(&b); 19081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (method = authmethods; method->name != NULL; method++) { 19091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authmethod_is_enabled(method)) { 19101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&b) > 0) 19111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, ",", 1); 19121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, method->name, strlen(method->name)); 19131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&b, "\0", 1); 19161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood list = xstrdup(buffer_ptr(&b)); 19171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_free(&b); 19181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return list; 19191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1921