1ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman/* $OpenBSD: sshconnect2.c,v 1.226 2015/07/30 00:01:34 djm Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2000 Markus Friedl. All rights reserved. 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2008 Damien Miller. All rights reserved. 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Redistribution and use in source and binary forms, with or without 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * modification, are permitted provided that the following conditions 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are met: 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. Redistributions of source code must retain the above copyright 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer. 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. Redistributions in binary form must reproduce the above copyright 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer in the 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * documentation and/or other materials provided with the distribution. 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/socket.h> 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/wait.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/stat.h> 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <errno.h> 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <fcntl.h> 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <netdb.h> 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <pwd.h> 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <signal.h> 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdio.h> 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 43d059297112922cabb0c674840589be8db821fd9aAdam Langley#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <vis.h> 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "openbsd-compat/sys-queue.h" 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh.h" 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh2.h" 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "buffer.h" 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "packet.h" 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "compat.h" 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "cipher.h" 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "key.h" 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "kex.h" 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "myproposal.h" 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "sshconnect.h" 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "authfile.h" 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "dh.h" 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "authfd.h" 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "misc.h" 65d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "readconf.h" 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "match.h" 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "dispatch.h" 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "canohost.h" 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "msg.h" 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "pathnames.h" 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "uidswap.h" 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "hostfile.h" 73d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h" 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh-gss.h" 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* import */ 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern char *client_version_string; 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern char *server_version_string; 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern Options options; 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * SSH2 key exchange 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_char *session_id2 = NULL; 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanu_int session_id2_len = 0; 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanchar *xxx_host; 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstruct sockaddr *xxx_hostaddr; 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 95d059297112922cabb0c674840589be8db821fd9aAdam Langleyverify_host_key_callback(Key *hostkey, struct ssh *ssh) 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Host key verification failed."); 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char * 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanorder_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *oavail, *avail, *first, *last, *alg, *hostname, *ret; 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman size_t maxlen; 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct hostkeys *hostkeys; 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ktype; 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int i; 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Find all hostkeys for this hostname */ 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman hostkeys = init_hostkeys(); 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_user_hostfiles; i++) 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]); 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_system_hostfiles; i++) 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]); 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maxlen = strlen(avail) + 1; 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman first = xmalloc(maxlen); 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman last = xmalloc(maxlen); 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *first = *last = '\0'; 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#define ALG_APPEND(to, from) \ 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman do { \ 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*to != '\0') \ 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strlcat(to, ",", maxlen); \ 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strlcat(to, from, maxlen); \ 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } while (0) 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while ((alg = strsep(&avail, ",")) && *alg != '\0') { 133d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("%s: unknown alg %s", __func__, alg); 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (lookup_key_in_hostkeys_by_type(hostkeys, 136d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_type_plain(ktype), NULL)) 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ALG_APPEND(first, alg); 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ALG_APPEND(last, alg); 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#undef ALG_APPEND 142d059297112922cabb0c674840589be8db821fd9aAdam Langley xasprintf(&ret, "%s%s%s", first, 143d059297112922cabb0c674840589be8db821fd9aAdam Langley (*first == '\0' || *last == '\0') ? "" : ",", last); 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (*first != '\0') 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("%s: prefer hostkeyalgs: %s", __func__, first); 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 147d059297112922cabb0c674840589be8db821fd9aAdam Langley free(first); 148d059297112922cabb0c674840589be8db821fd9aAdam Langley free(last); 149d059297112922cabb0c674840589be8db821fd9aAdam Langley free(hostname); 150d059297112922cabb0c674840589be8db821fd9aAdam Langley free(oavail); 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman free_hostkeys(hostkeys); 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return ret; 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 159d059297112922cabb0c674840589be8db821fd9aAdam Langley char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; 160d059297112922cabb0c674840589be8db821fd9aAdam Langley struct kex *kex; 161d059297112922cabb0c674840589be8db821fd9aAdam Langley int r; 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman xxx_host = host; 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman xxx_hostaddr = hostaddr; 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 166ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( 167ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman options.kex_algorithms); 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_ENC_ALGS_CTOS] = 169ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman compat_cipher_proposal(options.ciphers); 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_ENC_ALGS_STOC] = 171ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman compat_cipher_proposal(options.ciphers); 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.compression) { 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_COMP_ALGS_CTOS] = 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none"; 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_COMP_ALGS_CTOS] = 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib"; 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 179ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman myproposal[PROPOSAL_MAC_ALGS_CTOS] = 180ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 181ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (options.hostkeyalgorithms != NULL) { 182ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (kex_assemble_names(KEX_DEFAULT_PK_ALG, 183ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman &options.hostkeyalgorithms) != 0) 184ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman fatal("%s: kex_assemble_namelist", __func__); 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 186d059297112922cabb0c674840589be8db821fd9aAdam Langley compat_pkalg_proposal(options.hostkeyalgorithms); 187ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman } else { 188ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman /* Enforce default */ 189ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman options.hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Prefer algorithms that we already have keys for */ 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 192d059297112922cabb0c674840589be8db821fd9aAdam Langley compat_pkalg_proposal( 193d059297112922cabb0c674840589be8db821fd9aAdam Langley order_hostkeyalgs(host, hostaddr, port)); 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 196d059297112922cabb0c674840589be8db821fd9aAdam Langley if (options.rekey_limit || options.rekey_interval) 197d059297112922cabb0c674840589be8db821fd9aAdam Langley packet_set_rekey_limits((u_int32_t)options.rekey_limit, 198d059297112922cabb0c674840589be8db821fd9aAdam Langley (time_t)options.rekey_interval); 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* start key exchange */ 201d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = kex_setup(active_state, myproposal)) != 0) 202d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("kex_setup: %s", ssh_err(r)); 203d059297112922cabb0c674840589be8db821fd9aAdam Langley kex = active_state->kex; 204d059297112922cabb0c674840589be8db821fd9aAdam Langley#ifdef WITH_OPENSSL 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; 209d059297112922cabb0c674840589be8db821fd9aAdam Langley# ifdef OPENSSL_HAS_ECC 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->kex[KEX_ECDH_SHA2] = kexecdh_client; 211d059297112922cabb0c674840589be8db821fd9aAdam Langley# endif 212d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif 213d059297112922cabb0c674840589be8db821fd9aAdam Langley kex->kex[KEX_C25519_SHA256] = kexc25519_client; 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->client_version_string=client_version_string; 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->server_version_string=server_version_string; 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman kex->verify_host_key=&verify_host_key_callback; 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 218d059297112922cabb0c674840589be8db821fd9aAdam Langley dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.use_roaming && !kex->roaming) { 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Roaming not allowed by server"); 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.use_roaming = 0; 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman session_id2 = kex->session_id; 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman session_id2_len = kex->session_id_len; 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef DEBUG_KEXDH 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* send 1st encrypted/maced/compressed message */ 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_IGNORE); 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring("markus"); 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Authenticate user 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 241d059297112922cabb0c674840589be8db821fd9aAdam Langleytypedef struct cauthctxt Authctxt; 242d059297112922cabb0c674840589be8db821fd9aAdam Langleytypedef struct cauthmethod Authmethod; 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantypedef struct identity Identity; 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmantypedef struct idlist Idlist; 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstruct identity { 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_ENTRY(identity) next; 248d059297112922cabb0c674840589be8db821fd9aAdam Langley int agent_fd; /* >=0 if agent supports key */ 249d059297112922cabb0c674840589be8db821fd9aAdam Langley struct sshkey *key; /* public/private key */ 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *filename; /* comment for agent-only keys */ 251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int tried; 252bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int isprivate; /* key points to the private key */ 253d059297112922cabb0c674840589be8db821fd9aAdam Langley int userprovided; 254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}; 255bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanTAILQ_HEAD(idlist, identity); 256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 257d059297112922cabb0c674840589be8db821fd9aAdam Langleystruct cauthctxt { 258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *server_user; 259bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *local_user; 260bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *host; 261bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *service; 262d059297112922cabb0c674840589be8db821fd9aAdam Langley struct cauthmethod *method; 263bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sig_atomic_t success; 264bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *authlist; 265d059297112922cabb0c674840589be8db821fd9aAdam Langley int attempt; 266bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* pubkey */ 267d059297112922cabb0c674840589be8db821fd9aAdam Langley struct idlist keys; 268d059297112922cabb0c674840589be8db821fd9aAdam Langley int agent_fd; 269bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* hostbased */ 270bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Sensitive *sensitive; 271d059297112922cabb0c674840589be8db821fd9aAdam Langley char *oktypes, *ktypes; 272d059297112922cabb0c674840589be8db821fd9aAdam Langley const char *active_ktype; 273bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* kbd-interactive */ 274bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int info_req_seen; 275bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* generic */ 276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman void *methoddata; 277bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}; 278d059297112922cabb0c674840589be8db821fd9aAdam Langley 279d059297112922cabb0c674840589be8db821fd9aAdam Langleystruct cauthmethod { 280bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *name; /* string to compare against server's list */ 281bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int (*userauth)(Authctxt *authctxt); 282bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman void (*cleanup)(Authctxt *authctxt); 283bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int *enabled; /* flag in option struct that enables method */ 284bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int *batch_flag; /* flag in option struct that disables method */ 285bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}; 286bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 287d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_success(int, u_int32_t, void *); 288d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_success_unexpected(int, u_int32_t, void *); 289d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_failure(int, u_int32_t, void *); 290d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_banner(int, u_int32_t, void *); 291d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_error(int, u_int32_t, void *); 292d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_info_req(int, u_int32_t, void *); 293d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_pk_ok(int, u_int32_t, void *); 294d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_userauth_passwd_changereq(int, u_int32_t, void *); 295bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 296bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_none(Authctxt *); 297bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_pubkey(Authctxt *); 298bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_passwd(Authctxt *); 299bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_kbdint(Authctxt *); 300bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_hostbased(Authctxt *); 301bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 302bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 303bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint userauth_gssapi(Authctxt *authctxt); 304d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_gssapi_response(int type, u_int32_t, void *); 305d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_gssapi_token(int type, u_int32_t, void *); 306d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_gssapi_hash(int type, u_int32_t, void *); 307d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_gssapi_error(int, u_int32_t, void *); 308d059297112922cabb0c674840589be8db821fd9aAdam Langleyint input_gssapi_errtok(int, u_int32_t, void *); 309bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 310bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 311bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid userauth(Authctxt *, char *); 312bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 313bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int sign_and_send_pubkey(Authctxt *, Identity *); 314bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void pubkey_prepare(Authctxt *); 315bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void pubkey_cleanup(Authctxt *); 316d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic Key *load_identity_file(char *, int); 317bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 318bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Authmethod *authmethod_get(char *authlist); 319bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Authmethod *authmethod_lookup(const char *name); 320bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char *authmethods_get(void); 321bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 322bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanAuthmethod authmethods[] = { 323bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 324bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"gssapi-with-mic", 325bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_gssapi, 326bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 327bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.gss_authentication, 328bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL}, 329bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 330bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"hostbased", 331bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_hostbased, 332bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 333bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.hostbased_authentication, 334bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL}, 335bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"publickey", 336bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_pubkey, 337bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 338bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.pubkey_authentication, 339bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL}, 340bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"keyboard-interactive", 341bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_kbdint, 342bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 343bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.kbd_interactive_authentication, 344bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.batch_mode}, 345bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"password", 346bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_passwd, 347bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 348bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.password_authentication, 349bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.batch_mode}, 350bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {"none", 351bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_none, 352bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 353bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL, 354bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman NULL}, 355bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman {NULL, NULL, NULL, NULL, NULL} 356bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}; 357bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 358bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 359bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanssh_userauth2(const char *local_user, const char *server_user, char *host, 360bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Sensitive *sensitive) 361bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 362bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt authctxt; 363bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int type; 364bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 365bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.challenge_response_authentication) 366bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.kbd_interactive_authentication = 1; 367bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 368bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_SERVICE_REQUEST); 369bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring("ssh-userauth"); 370bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 371bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("SSH2_MSG_SERVICE_REQUEST sent"); 372bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_write_wait(); 373bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman type = packet_read(); 374bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (type != SSH2_MSG_SERVICE_ACCEPT) 375bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Server denied authentication request: %d", type); 376bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (packet_remaining() > 0) { 377bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *reply = packet_get_string(NULL); 378bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("service_accept: %s", reply); 379d059297112922cabb0c674840589be8db821fd9aAdam Langley free(reply); 380bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 381bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("buggy server: service_accept w/o service"); 382bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 383bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 384bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("SSH2_MSG_SERVICE_ACCEPT received"); 385bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 386bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (options.preferred_authentications == NULL) 387bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.preferred_authentications = authmethods_get(); 388bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 389bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* setup authentication context */ 390bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman memset(&authctxt, 0, sizeof(authctxt)); 391bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pubkey_prepare(&authctxt); 392bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.server_user = server_user; 393bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.local_user = local_user; 394bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.host = host; 395bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.service = "ssh-connection"; /* service name */ 396bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.success = 0; 397bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.method = authmethod_lookup("none"); 398bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.authlist = NULL; 399bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.methoddata = NULL; 400bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.sensitive = sensitive; 401d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL; 402bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt.info_req_seen = 0; 403d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt.agent_fd = -1; 404bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt.method == NULL) 405bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("ssh_userauth2: internal error: cannot send userauth none request"); 406bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 407bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* initial userauth request */ 408bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_none(&authctxt); 409bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 410bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_init(&input_userauth_error); 411bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); 412bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); 413bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); 414bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ 415bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 416bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pubkey_cleanup(&authctxt); 417bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); 418bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 419bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Authentication succeeded (%s).", authctxt.method->name); 420bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 421bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 422bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 423bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth(Authctxt *authctxt, char *authlist) 424bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 425bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt->method != NULL && authctxt->method->cleanup != NULL) 426bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->method->cleanup(authctxt); 427bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 428d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->methoddata); 429d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->methoddata = NULL; 430bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authlist == NULL) { 431bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authlist = authctxt->authlist; 432bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 433d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->authlist); 434bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->authlist = authlist; 435bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 436bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (;;) { 437bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authmethod *method = authmethod_get(authlist); 438bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (method == NULL) 439bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Permission denied (%s).", authlist); 440bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->method = method; 441bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 442bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* reset the per method handler */ 443bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, 444bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); 445bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 446bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* and try new method */ 447bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (method->userauth(authctxt) != 0) { 448bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("we sent a %s packet, wait for reply", method->name); 449bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 450bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 451bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("we did not send a packet, disable method"); 452bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman method->enabled = NULL; 453bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 454bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 455bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 456bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 457bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 458d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 459bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_error(int type, u_int32_t seq, void *ctxt) 460bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 461bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_error: bad message during authentication: " 462bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "type %d", type); 463d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 464bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 465bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 466bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 467d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 468bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_banner(int type, u_int32_t seq, void *ctxt) 469bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 470bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *msg, *raw, *lang; 471bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 472bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 473bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("input_userauth_banner"); 474bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman raw = packet_get_string(&len); 475bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman lang = packet_get_string(NULL); 476bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { 477bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (len > 65536) 478bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman len = 65536; 479bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ 480bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); 481bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fprintf(stderr, "%s", msg); 482d059297112922cabb0c674840589be8db821fd9aAdam Langley free(msg); 483bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 484d059297112922cabb0c674840589be8db821fd9aAdam Langley free(raw); 485d059297112922cabb0c674840589be8db821fd9aAdam Langley free(lang); 486d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 487bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 488bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 489bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 490d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 491bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_success(int type, u_int32_t seq, void *ctxt) 492bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 493bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 494bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 495bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 496bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_success: no authentication context"); 497d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->authlist); 498d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->authlist = NULL; 499bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt->method != NULL && authctxt->method->cleanup != NULL) 500bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->method->cleanup(authctxt); 501d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->methoddata); 502d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->methoddata = NULL; 503bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->success = 1; /* break out */ 504d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 505bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 506bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 507d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 508bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) 509bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 510bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 511bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 512bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 513bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("%s: no authentication context", __func__); 514bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 515bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Unexpected authentication success during %s.", 516bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->method->name); 517d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 518bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 519bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 520bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 521d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 522bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_failure(int type, u_int32_t seq, void *ctxt) 523bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 524bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 525bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *authlist = NULL; 526bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int partial; 527bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 528bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 529bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_failure: no authentication context"); 530bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 531bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authlist = packet_get_string(NULL); 532bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman partial = packet_get_char(); 533bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 534bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 535d059297112922cabb0c674840589be8db821fd9aAdam Langley if (partial != 0) { 536bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Authenticated with partial success."); 537d059297112922cabb0c674840589be8db821fd9aAdam Langley /* reset state */ 538d059297112922cabb0c674840589be8db821fd9aAdam Langley pubkey_cleanup(authctxt); 539d059297112922cabb0c674840589be8db821fd9aAdam Langley pubkey_prepare(authctxt); 540d059297112922cabb0c674840589be8db821fd9aAdam Langley } 541bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Authentications that can continue: %s", authlist); 542bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 543bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth(authctxt, authlist); 544d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 545bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 546bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 547bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 548d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 549bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) 550bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 551bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 552bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Key *key = NULL; 553bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Identity *id = NULL; 554bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 555bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int pktype, sent = 0; 556bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int alen, blen; 557bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *pkalg, *fp; 558bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char *pkblob; 559bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 560bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 561bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_pk_ok: no authentication context"); 562bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (datafellows & SSH_BUG_PKOK) { 563bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* this is similar to SSH_BUG_PKAUTH */ 564bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("input_userauth_pk_ok: SSH_BUG_PKOK"); 565bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pkblob = packet_get_string(&blen); 566bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_init(&b); 567bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, pkblob, blen); 568bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pkalg = buffer_get_string(&b, &alen); 569bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 570bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 571bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pkalg = packet_get_string(&alen); 572bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pkblob = packet_get_string(&blen); 573bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 574bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 575bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 576bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Server accepts key: pkalg %s blen %u", pkalg, blen); 577bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 578bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { 579bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("unknown pkalg %s", pkalg); 580bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto done; 581bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 582bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((key = key_from_blob(pkblob, blen)) == NULL) { 583bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("no key from blob. pkalg %s", pkalg); 584bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto done; 585bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 586bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key->type != pktype) { 587bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("input_userauth_pk_ok: type mismatch " 588bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "for decoded key (received %d, expected %d)", 589bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key->type, pktype); 590bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goto done; 591bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 592d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, 593d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_FP_DEFAULT)) == NULL) 594d059297112922cabb0c674840589be8db821fd9aAdam Langley goto done; 595bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("input_userauth_pk_ok: fp %s", fp); 596d059297112922cabb0c674840589be8db821fd9aAdam Langley free(fp); 597bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 598bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 599bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * search keys in the reverse order, because last candidate has been 600bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * moved to the end of the queue. this also avoids confusion by 601bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * duplicate keys 602bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 603bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) { 604bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key_equal(key, id->key)) { 605bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman sent = sign_and_send_pubkey(authctxt, id); 606bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 607bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 608bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 609bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmandone: 610bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key != NULL) 611bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key_free(key); 612d059297112922cabb0c674840589be8db821fd9aAdam Langley free(pkalg); 613d059297112922cabb0c674840589be8db821fd9aAdam Langley free(pkblob); 614bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 615bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* try another method if we did not send a packet */ 616bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (sent == 0) 617bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth(authctxt, NULL); 618d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 619bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 620bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 621bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 622bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 623bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_gssapi(Authctxt *authctxt) 624bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 625bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt = NULL; 626bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman static gss_OID_set gss_supported = NULL; 627bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman static u_int mech = 0; 628bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 min; 629bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ok = 0; 630bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 631bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Try one GSSAPI method at a time, rather than sending them all at 632bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * once. */ 633bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 634bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (gss_supported == NULL) 635bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_indicate_mechs(&min, &gss_supported); 636bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 637bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Check to see if the mechanism is usable before we offer it */ 638bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while (mech < gss_supported->count && !ok) { 639bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* My DER encoding requires length<128 */ 640bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (gss_supported->elements[mech].length < 128 && 641bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_gssapi_check_mechanism(&gssctxt, 642bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &gss_supported->elements[mech], authctxt->host)) { 643bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ok = 1; /* Mechanism works */ 644bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 645bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mech++; 646bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 647bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 648bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 649bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!ok) 650bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 651bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 652bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->methoddata=(void *)gssctxt; 653bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 654bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 655bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 656bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 657bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 658bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 659bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_int(1); 660bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 661bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_int((gss_supported->elements[mech].length) + 2); 662bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(SSH_GSS_OIDTYPE); 663bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(gss_supported->elements[mech].length); 664bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_raw(gss_supported->elements[mech].elements, 665bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_supported->elements[mech].length); 666bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 667bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 668bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 669bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); 670bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); 671bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); 672bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); 673bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 674bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mech++; /* Move along to next candidate */ 675bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 676bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 677bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 678bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 679bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic OM_uint32 680bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanprocess_gssapi_token(void *ctxt, gss_buffer_t recv_tok) 681bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 682bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 683bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt = authctxt->methoddata; 684bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 685bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc mic = GSS_C_EMPTY_BUFFER; 686bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc gssbuf; 687bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 status, ms, flags; 688bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 689bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 690bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, 691bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok, &send_tok, &flags); 692bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 693bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (send_tok.length > 0) { 694bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (GSS_ERROR(status)) 695bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); 696bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 697bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 698bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 699bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(send_tok.value, send_tok.length); 700bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 701bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_release_buffer(&ms, &send_tok); 702bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 703bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 704bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (status == GSS_S_COMPLETE) { 705bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* send either complete or MIC, depending on mechanism */ 706bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!(flags & GSS_C_INTEG_FLAG)) { 707bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); 708bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 709bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 710bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_gssapi_buildmic(&b, authctxt->server_user, 711bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->service, "gssapi-with-mic"); 712bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 713bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssbuf.value = buffer_ptr(&b); 714bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssbuf.length = buffer_len(&b); 715bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 716bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic); 717bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 718bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!GSS_ERROR(status)) { 719bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC); 720bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(mic.value, mic.length); 721bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 722bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 723bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 724bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 725bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 726bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_release_buffer(&ms, &mic); 727bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 728bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 729bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 730bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return status; 731bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 732bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 733bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 734d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 735bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_response(int type, u_int32_t plen, void *ctxt) 736bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 737bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 738bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt; 739bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int oidlen; 740bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *oidv; 741bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 742bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 743bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_gssapi_response: no authentication context"); 744bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssctxt = authctxt->methoddata; 745bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 746bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Setup our OID */ 747bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman oidv = packet_get_string(&oidlen); 748bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 749bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (oidlen <= 2 || 750bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman oidv[0] != SSH_GSS_OIDTYPE || 751bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman oidv[1] != oidlen - 2) { 752d059297112922cabb0c674840589be8db821fd9aAdam Langley free(oidv); 753bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Badly encoded mechanism OID received"); 754bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth(authctxt, NULL); 755d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 756bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 757bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 758bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) 759bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("Server returned different OID than expected"); 760bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 761bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 762bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 763d059297112922cabb0c674840589be8db821fd9aAdam Langley free(oidv); 764bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 765bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) { 766bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Start again with next method on list */ 767bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Trying to start again"); 768bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth(authctxt, NULL); 769d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 770bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 771d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 772bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 773bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 774bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 775d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 776bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_token(int type, u_int32_t plen, void *ctxt) 777bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 778bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 779bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc recv_tok; 780bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 status; 781bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int slen; 782bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 783bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 784bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_gssapi_response: no authentication context"); 785bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 786bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.value = packet_get_string(&slen); 787bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.length = slen; /* safe typecast */ 788bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 789bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 790bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 791bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman status = process_gssapi_token(ctxt, &recv_tok); 792bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 793d059297112922cabb0c674840589be8db821fd9aAdam Langley free(recv_tok.value); 794bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 795bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (GSS_ERROR(status)) { 796bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Start again with the next method in the list */ 797bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth(authctxt, NULL); 798d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 799bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 800d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 801bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 802bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 803bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 804d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 805bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 806bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 807bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 808bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt; 809bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 810bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc recv_tok; 811d059297112922cabb0c674840589be8db821fd9aAdam Langley OM_uint32 ms; 812bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 813bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 814bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 815bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_gssapi_response: no authentication context"); 816bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssctxt = authctxt->methoddata; 817bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 818bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.value = packet_get_string(&len); 819bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.length = len; 820bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 821bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 822bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 823bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Stick it into GSSAPI and see what it says */ 824d059297112922cabb0c674840589be8db821fd9aAdam Langley (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, 825bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &recv_tok, &send_tok, NULL); 826bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 827d059297112922cabb0c674840589be8db821fd9aAdam Langley free(recv_tok.value); 828bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_release_buffer(&ms, &send_tok); 829bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 830bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Server will be returning a failed packet after this one */ 831d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 832bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 833bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 834bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 835d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 836bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_error(int type, u_int32_t plen, void *ctxt) 837bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 838bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *msg; 839bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *lang; 840bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 841d059297112922cabb0c674840589be8db821fd9aAdam Langley /* maj */(void)packet_get_int(); 842d059297112922cabb0c674840589be8db821fd9aAdam Langley /* min */(void)packet_get_int(); 843bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman msg=packet_get_string(NULL); 844bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman lang=packet_get_string(NULL); 845bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 846bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 847bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 848bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Server GSSAPI Error:\n%s", msg); 849d059297112922cabb0c674840589be8db821fd9aAdam Langley free(msg); 850d059297112922cabb0c674840589be8db821fd9aAdam Langley free(lang); 851d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 852bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 853bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* GSSAPI */ 854bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 855bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 856bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_none(Authctxt *authctxt) 857bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 858bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* initial userauth request */ 859bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 860bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 861bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 862bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 863bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 864bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 865bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 866bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 867bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 868bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_passwd(Authctxt *authctxt) 869bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 870bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman static int attempt = 0; 871bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char prompt[150]; 872bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *password; 873bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *host = options.host_key_alias ? options.host_key_alias : 874bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->host; 875bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 876bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (attempt++ >= options.number_of_password_prompts) 877bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 878bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 879bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (attempt != 1) 880bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Permission denied, please try again."); 881bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 882bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ", 883bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_user, host); 884bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = read_passphrase(prompt, 0); 885bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 886bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 887bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 888bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 889bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(0); 890bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(password); 891d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(password, strlen(password)); 892d059297112922cabb0c674840589be8db821fd9aAdam Langley free(password); 893bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_add_padding(64); 894bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 895bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 896bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, 897bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &input_userauth_passwd_changereq); 898bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 899bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 900bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 901bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 902bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 903bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST 904bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 905bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* ARGSUSED */ 906d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 907bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) 908bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 909bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 910bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *info, *lang, *password = NULL, *retype = NULL; 911bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char prompt[150]; 912bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *host = options.host_key_alias ? options.host_key_alias : 913bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->host; 914bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 915bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("input_userauth_passwd_changereq"); 916bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 917bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 918bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_passwd_changereq: " 919bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "no authentication context"); 920bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 921bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman info = packet_get_string(NULL); 922bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman lang = packet_get_string(NULL); 923bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlen(info) > 0) 924bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("%s", info); 925d059297112922cabb0c674840589be8db821fd9aAdam Langley free(info); 926d059297112922cabb0c674840589be8db821fd9aAdam Langley free(lang); 927bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 928bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 929bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 930bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 931bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(1); /* additional info */ 932bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof(prompt), 933bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "Enter %.30s@%.128s's old password: ", 934bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_user, host); 935bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = read_passphrase(prompt, 0); 936bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(password); 937d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(password, strlen(password)); 938d059297112922cabb0c674840589be8db821fd9aAdam Langley free(password); 939bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = NULL; 940bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while (password == NULL) { 941bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof(prompt), 942bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "Enter %.30s@%.128s's new password: ", 943bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_user, host); 944bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = read_passphrase(prompt, RP_ALLOW_EOF); 945bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (password == NULL) { 946bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* bail out */ 947d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 948bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 949bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman snprintf(prompt, sizeof(prompt), 950bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "Retype %.30s@%.128s's new password: ", 951bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_user, host); 952bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman retype = read_passphrase(prompt, 0); 953bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(password, retype) != 0) { 954d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(password, strlen(password)); 955d059297112922cabb0c674840589be8db821fd9aAdam Langley free(password); 956bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Mismatch; try again, EOF to quit."); 957bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman password = NULL; 958bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 959d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(retype, strlen(retype)); 960d059297112922cabb0c674840589be8db821fd9aAdam Langley free(retype); 961bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 962bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(password); 963d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(password, strlen(password)); 964d059297112922cabb0c674840589be8db821fd9aAdam Langley free(password); 965bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_add_padding(64); 966bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 967bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 968bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, 969bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &input_userauth_passwd_changereq); 970d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 971bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 972bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 973bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 974d059297112922cabb0c674840589be8db821fd9aAdam Langleyidentity_sign(struct identity *id, u_char **sigp, size_t *lenp, 975d059297112922cabb0c674840589be8db821fd9aAdam Langley const u_char *data, size_t datalen, u_int compat) 976bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 977bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Key *prv; 978bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ret; 979bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 980bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* the agent supports this key */ 981d059297112922cabb0c674840589be8db821fd9aAdam Langley if (id->agent_fd) 982d059297112922cabb0c674840589be8db821fd9aAdam Langley return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, 983d059297112922cabb0c674840589be8db821fd9aAdam Langley data, datalen, compat); 984d059297112922cabb0c674840589be8db821fd9aAdam Langley 985bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 986bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * we have already loaded the private key or 987bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * the private key is stored in external hardware 988bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 989d059297112922cabb0c674840589be8db821fd9aAdam Langley if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)) 990d059297112922cabb0c674840589be8db821fd9aAdam Langley return (sshkey_sign(id->key, sigp, lenp, data, datalen, 991d059297112922cabb0c674840589be8db821fd9aAdam Langley compat)); 992bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* load the private key from the file */ 993d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL) 994d059297112922cabb0c674840589be8db821fd9aAdam Langley return (-1); /* XXX return decent error code */ 995d059297112922cabb0c674840589be8db821fd9aAdam Langley ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat); 996d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_free(prv); 997bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (ret); 998bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 999bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1000bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 1001bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmansign_and_send_pubkey(Authctxt *authctxt, Identity *id) 1002bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1003bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 1004bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char *blob, *signature; 1005d059297112922cabb0c674840589be8db821fd9aAdam Langley u_int bloblen; 1006d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t slen; 1007bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int skip = 0; 1008bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int ret = -1; 1009bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int have_sig = 1; 1010bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *fp; 1011bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1012d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, 1013d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_FP_DEFAULT)) == NULL) 1014d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 1015bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); 1016d059297112922cabb0c674840589be8db821fd9aAdam Langley free(fp); 1017bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1018bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key_to_blob(id->key, &blob, &bloblen) == 0) { 1019bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* we cannot handle this key */ 1020bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("sign_and_send_pubkey: cannot handle key"); 1021bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1022bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1023bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* data to be signed */ 1024bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_init(&b); 1025bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (datafellows & SSH_OLD_SESSIONID) { 1026bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, session_id2, session_id2_len); 1027bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman skip = session_id2_len; 1028bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 1029bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_string(&b, session_id2, session_id2_len); 1030bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman skip = buffer_len(&b); 1031bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1032bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 1033bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, authctxt->server_user); 1034bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, 1035bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman datafellows & SSH_BUG_PKSERVICE ? 1036bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "ssh-userauth" : 1037bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->service); 1038bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (datafellows & SSH_BUG_PKAUTH) { 1039bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_char(&b, have_sig); 1040bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 1041bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, authctxt->method->name); 1042bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_char(&b, have_sig); 1043bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, key_ssh_name(id->key)); 1044bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1045bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_string(&b, blob, bloblen); 1046bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1047bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* generate signature */ 1048bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ret = identity_sign(id, &signature, &slen, 1049d059297112922cabb0c674840589be8db821fd9aAdam Langley buffer_ptr(&b), buffer_len(&b), datafellows); 1050d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ret != 0) { 1051d059297112922cabb0c674840589be8db821fd9aAdam Langley free(blob); 1052bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 1053bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1054bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1055bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef DEBUG_PK 1056bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_dump(&b); 1057bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 1058bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (datafellows & SSH_BUG_PKSERVICE) { 1059bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_clear(&b); 1060bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, session_id2, session_id2_len); 1061bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman skip = session_id2_len; 1062bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 1063bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, authctxt->server_user); 1064bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, authctxt->service); 1065bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, authctxt->method->name); 1066bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_char(&b, have_sig); 1067bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!(datafellows & SSH_BUG_PKAUTH)) 1068bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_cstring(&b, key_ssh_name(id->key)); 1069bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_string(&b, blob, bloblen); 1070bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1071d059297112922cabb0c674840589be8db821fd9aAdam Langley free(blob); 1072bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1073bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* append signature */ 1074bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_put_string(&b, signature, slen); 1075d059297112922cabb0c674840589be8db821fd9aAdam Langley free(signature); 1076bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1077bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* skip session id and packet type */ 1078bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (buffer_len(&b) < skip + 1) 1079bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("userauth_pubkey: internal error"); 1080bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_consume(&b, skip + 1); 1081bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1082bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* put remaining data from buffer into packet */ 1083bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 1084bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_raw(buffer_ptr(&b), buffer_len(&b)); 1085bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 1086bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 1087bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1088bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 1089bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1090bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1091bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 1092bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmansend_pubkey_test(Authctxt *authctxt, Identity *id) 1093bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1094bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char *blob; 1095bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int bloblen, have_sig = 0; 1096bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1097bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("send_pubkey_test"); 1098bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1099bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key_to_blob(id->key, &blob, &bloblen) == 0) { 1100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* we cannot handle this key */ 1101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("send_pubkey_test: cannot handle key"); 1102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* register callback for USERAUTH_PK_OK message */ 1105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); 1106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 1108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 1109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 1110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 1111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_char(have_sig); 1112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!(datafellows & SSH_BUG_PKAUTH)) 1113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(key_ssh_name(id->key)); 1114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(blob, bloblen); 1115d059297112922cabb0c674840589be8db821fd9aAdam Langley free(blob); 1116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 1117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 1118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Key * 1121d059297112922cabb0c674840589be8db821fd9aAdam Langleyload_identity_file(char *filename, int userprovided) 1122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Key *private; 1124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char prompt[300], *passphrase; 1125d059297112922cabb0c674840589be8db821fd9aAdam Langley int r, perm_ok = 0, quit = 0, i; 1126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 1127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (stat(filename, &st) < 0) { 1129d059297112922cabb0c674840589be8db821fd9aAdam Langley (userprovided ? logit : debug3)("no such identity: %s: %s", 1130d059297112922cabb0c674840589be8db821fd9aAdam Langley filename, strerror(errno)); 1131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 1132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1133d059297112922cabb0c674840589be8db821fd9aAdam Langley snprintf(prompt, sizeof prompt, 1134d059297112922cabb0c674840589be8db821fd9aAdam Langley "Enter passphrase for key '%.100s': ", filename); 1135d059297112922cabb0c674840589be8db821fd9aAdam Langley for (i = 0; i <= options.number_of_password_prompts; i++) { 1136d059297112922cabb0c674840589be8db821fd9aAdam Langley if (i == 0) 1137d059297112922cabb0c674840589be8db821fd9aAdam Langley passphrase = ""; 1138d059297112922cabb0c674840589be8db821fd9aAdam Langley else { 1139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman passphrase = read_passphrase(prompt, 0); 1140d059297112922cabb0c674840589be8db821fd9aAdam Langley if (*passphrase == '\0') { 1141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("no passphrase given, try next key"); 1142d059297112922cabb0c674840589be8db821fd9aAdam Langley free(passphrase); 1143d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1144d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1145d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1146d059297112922cabb0c674840589be8db821fd9aAdam Langley switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename, 1147d059297112922cabb0c674840589be8db821fd9aAdam Langley passphrase, &private, NULL, &perm_ok))) { 1148d059297112922cabb0c674840589be8db821fd9aAdam Langley case 0: 1149d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1150d059297112922cabb0c674840589be8db821fd9aAdam Langley case SSH_ERR_KEY_WRONG_PASSPHRASE: 1151d059297112922cabb0c674840589be8db821fd9aAdam Langley if (options.batch_mode) { 1152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman quit = 1; 1153d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1155d059297112922cabb0c674840589be8db821fd9aAdam Langley if (i != 0) 1156d059297112922cabb0c674840589be8db821fd9aAdam Langley debug2("bad passphrase given, try again..."); 1157d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1158d059297112922cabb0c674840589be8db821fd9aAdam Langley case SSH_ERR_SYSTEM_ERROR: 1159d059297112922cabb0c674840589be8db821fd9aAdam Langley if (errno == ENOENT) { 1160d059297112922cabb0c674840589be8db821fd9aAdam Langley debug2("Load key \"%s\": %s", 1161d059297112922cabb0c674840589be8db821fd9aAdam Langley filename, ssh_err(r)); 1162d059297112922cabb0c674840589be8db821fd9aAdam Langley quit = 1; 1163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 1164d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1165d059297112922cabb0c674840589be8db821fd9aAdam Langley /* FALLTHROUGH */ 1166d059297112922cabb0c674840589be8db821fd9aAdam Langley default: 1167d059297112922cabb0c674840589be8db821fd9aAdam Langley error("Load key \"%s\": %s", filename, ssh_err(r)); 1168d059297112922cabb0c674840589be8db821fd9aAdam Langley quit = 1; 1169d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1171d059297112922cabb0c674840589be8db821fd9aAdam Langley if (i > 0) { 1172d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(passphrase, strlen(passphrase)); 1173d059297112922cabb0c674840589be8db821fd9aAdam Langley free(passphrase); 1174d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1175d059297112922cabb0c674840589be8db821fd9aAdam Langley if (private != NULL || quit) 1176d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return private; 1179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 1182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * try keys in the following order: 1183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. agent keys that are found in the config file 1184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. other agent keys 1185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 3. keys that are only listed in the config file 1186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void 1188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpubkey_prepare(Authctxt *authctxt) 1189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1190d059297112922cabb0c674840589be8db821fd9aAdam Langley struct identity *id, *id2, *tmp; 1191d059297112922cabb0c674840589be8db821fd9aAdam Langley struct idlist agent, files, *preferred; 1192d059297112922cabb0c674840589be8db821fd9aAdam Langley struct sshkey *key; 1193d059297112922cabb0c674840589be8db821fd9aAdam Langley int agent_fd, i, r, found; 1194d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t j; 1195d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh_identitylist *idlist; 1196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INIT(&agent); /* keys from the agent */ 1198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INIT(&files); /* keys from the config file */ 1199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman preferred = &authctxt->keys; 1200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INIT(preferred); /* preferred order of keys */ 1201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1202d059297112922cabb0c674840589be8db821fd9aAdam Langley /* list of keys stored in the filesystem and PKCS#11 */ 1203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < options.num_identity_files; i++) { 1204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key = options.identity_keys[i]; 1205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key && key->type == KEY_RSA1) 1206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman continue; 1207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER) 1208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman continue; 1209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.identity_keys[i] = NULL; 1210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id = xcalloc(1, sizeof(*id)); 1211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id->key = key; 1212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id->filename = xstrdup(options.identity_files[i]); 1213d059297112922cabb0c674840589be8db821fd9aAdam Langley id->userprovided = options.identity_file_userprovided[i]; 1214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(&files, id, next); 1215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1216d059297112922cabb0c674840589be8db821fd9aAdam Langley /* Prefer PKCS11 keys that are explicitly listed */ 1217d059297112922cabb0c674840589be8db821fd9aAdam Langley TAILQ_FOREACH_SAFE(id, &files, next, tmp) { 1218d059297112922cabb0c674840589be8db821fd9aAdam Langley if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0) 1219d059297112922cabb0c674840589be8db821fd9aAdam Langley continue; 1220d059297112922cabb0c674840589be8db821fd9aAdam Langley found = 0; 1221d059297112922cabb0c674840589be8db821fd9aAdam Langley TAILQ_FOREACH(id2, &files, next) { 1222d059297112922cabb0c674840589be8db821fd9aAdam Langley if (id2->key == NULL || 1223d059297112922cabb0c674840589be8db821fd9aAdam Langley (id2->key->flags & SSHKEY_FLAG_EXT) == 0) 1224d059297112922cabb0c674840589be8db821fd9aAdam Langley continue; 1225d059297112922cabb0c674840589be8db821fd9aAdam Langley if (sshkey_equal(id->key, id2->key)) { 1226d059297112922cabb0c674840589be8db821fd9aAdam Langley TAILQ_REMOVE(&files, id, next); 1227d059297112922cabb0c674840589be8db821fd9aAdam Langley TAILQ_INSERT_TAIL(preferred, id, next); 1228d059297112922cabb0c674840589be8db821fd9aAdam Langley found = 1; 1229d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1230d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1231d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1232d059297112922cabb0c674840589be8db821fd9aAdam Langley /* If IdentitiesOnly set and key not found then don't use it */ 1233d059297112922cabb0c674840589be8db821fd9aAdam Langley if (!found && options.identities_only) { 1234d059297112922cabb0c674840589be8db821fd9aAdam Langley TAILQ_REMOVE(&files, id, next); 1235d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(id, sizeof(*id)); 1236d059297112922cabb0c674840589be8db821fd9aAdam Langley free(id); 1237d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1238d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* list of keys supported by the agent */ 1240d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { 1241d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r != SSH_ERR_AGENT_NOT_PRESENT) 1242d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: ssh_get_authentication_socket: %s", 1243d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, ssh_err(r)); 1244d059297112922cabb0c674840589be8db821fd9aAdam Langley } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) { 1245d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r != SSH_ERR_AGENT_NO_IDENTITIES) 1246d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: ssh_fetch_identitylist: %s", 1247d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, ssh_err(r)); 1248d059297112922cabb0c674840589be8db821fd9aAdam Langley } else { 1249d059297112922cabb0c674840589be8db821fd9aAdam Langley for (j = 0; j < idlist->nkeys; j++) { 1250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman found = 0; 1251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_FOREACH(id, &files, next) { 1252d059297112922cabb0c674840589be8db821fd9aAdam Langley /* 1253d059297112922cabb0c674840589be8db821fd9aAdam Langley * agent keys from the config file are 1254d059297112922cabb0c674840589be8db821fd9aAdam Langley * preferred 1255d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 1256d059297112922cabb0c674840589be8db821fd9aAdam Langley if (sshkey_equal(idlist->keys[j], id->key)) { 1257bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_REMOVE(&files, id, next); 1258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(preferred, id, next); 1259d059297112922cabb0c674840589be8db821fd9aAdam Langley id->agent_fd = agent_fd; 1260bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman found = 1; 1261bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 1262bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1263bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1264bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!found && !options.identities_only) { 1265bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id = xcalloc(1, sizeof(*id)); 1266d059297112922cabb0c674840589be8db821fd9aAdam Langley /* XXX "steals" key/comment from idlist */ 1267d059297112922cabb0c674840589be8db821fd9aAdam Langley id->key = idlist->keys[j]; 1268d059297112922cabb0c674840589be8db821fd9aAdam Langley id->filename = idlist->comments[j]; 1269d059297112922cabb0c674840589be8db821fd9aAdam Langley idlist->keys[j] = NULL; 1270d059297112922cabb0c674840589be8db821fd9aAdam Langley idlist->comments[j] = NULL; 1271d059297112922cabb0c674840589be8db821fd9aAdam Langley id->agent_fd = agent_fd; 1272bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(&agent, id, next); 1273bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1274bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1275d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_free_identitylist(idlist); 1276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* append remaining agent keys */ 1277bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) { 1278bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_REMOVE(&agent, id, next); 1279bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(preferred, id, next); 1280bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1281d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->agent_fd = agent_fd; 1282bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1283bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* append remaining keys from the config file */ 1284bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { 1285bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_REMOVE(&files, id, next); 1286bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(preferred, id, next); 1287bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1288bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_FOREACH(id, preferred, next) { 1289d059297112922cabb0c674840589be8db821fd9aAdam Langley debug2("key: %s (%p),%s", id->filename, id->key, 1290d059297112922cabb0c674840589be8db821fd9aAdam Langley id->userprovided ? " explicit" : ""); 1291bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1292bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1293bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1294bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic void 1295bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpubkey_cleanup(Authctxt *authctxt) 1296bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1297bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Identity *id; 1298bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1299d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->agent_fd != -1) 1300d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_close_authentication_socket(authctxt->agent_fd); 1301bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (id = TAILQ_FIRST(&authctxt->keys); id; 1302bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id = TAILQ_FIRST(&authctxt->keys)) { 1303bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_REMOVE(&authctxt->keys, id, next); 1304bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (id->key) 1305d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_free(id->key); 1306d059297112922cabb0c674840589be8db821fd9aAdam Langley free(id->filename); 1307d059297112922cabb0c674840589be8db821fd9aAdam Langley free(id); 1308bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1309bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1310bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1311ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartmanstatic int 1312ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartmantry_identity(Identity *id) 1313ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman{ 1314ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (!id->key) 1315ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman return (0); 1316ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (match_pattern_list(sshkey_ssh_name(id->key), 1317ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman options.pubkey_key_types, 0) != 1) { 1318ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman debug("Skipping %s key %s for not in PubkeyAcceptedKeyTypes", 1319ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman sshkey_ssh_name(id->key), id->filename); 1320ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman return (0); 1321ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman } 1322ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (key_type_plain(id->key->type) == KEY_RSA && 1323ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman (datafellows & SSH_BUG_RSASIGMD5) != 0) { 1324ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman debug("Skipped %s key %s for RSA/MD5 server", 1325ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman key_type(id->key), id->filename); 1326ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman return (0); 1327ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman } 1328ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman return (id->key->type != KEY_RSA1); 1329ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman} 1330ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman 1331bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 1332bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_pubkey(Authctxt *authctxt) 1333bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1334bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Identity *id; 1335bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int sent = 0; 1336bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1337bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman while ((id = TAILQ_FIRST(&authctxt->keys))) { 1338bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (id->tried++) 1339bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 1340bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* move key to the end of the queue */ 1341bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_REMOVE(&authctxt->keys, id, next); 1342bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman TAILQ_INSERT_TAIL(&authctxt->keys, id, next); 1343bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 1344bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * send a test message if we have the public key. for 1345bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * encrypted keys we cannot do this and have to load the 1346bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * private key instead 1347bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1348d059297112922cabb0c674840589be8db821fd9aAdam Langley if (id->key != NULL) { 1349ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (try_identity(id)) { 1350d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("Offering %s public key: %s", 1351d059297112922cabb0c674840589be8db821fd9aAdam Langley key_type(id->key), id->filename); 1352d059297112922cabb0c674840589be8db821fd9aAdam Langley sent = send_pubkey_test(authctxt, id); 1353d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1354d059297112922cabb0c674840589be8db821fd9aAdam Langley } else { 1355bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Trying private key: %s", id->filename); 1356d059297112922cabb0c674840589be8db821fd9aAdam Langley id->key = load_identity_file(id->filename, 1357d059297112922cabb0c674840589be8db821fd9aAdam Langley id->userprovided); 1358bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (id->key != NULL) { 1359ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (try_identity(id)) { 1360ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman id->isprivate = 1; 1361d059297112922cabb0c674840589be8db821fd9aAdam Langley sent = sign_and_send_pubkey( 1362d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt, id); 1363d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1364bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman key_free(id->key); 1365bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman id->key = NULL; 1366bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1367bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1368bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (sent) 1369bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (sent); 1370bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1371bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 1372bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1373bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1374bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 1375bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Send userauth request message specifying keyboard-interactive method. 1376bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1377bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 1378bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_kbdint(Authctxt *authctxt) 1379bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1380bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman static int attempt = 0; 1381bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1382bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (attempt++ >= options.number_of_password_prompts) 1383bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1384bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */ 1385bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (attempt > 1 && !authctxt->info_req_seen) { 1386bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("userauth_kbdint: disable: no info_req_seen"); 1387bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL); 1388bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1389bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1390bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1391bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("userauth_kbdint"); 1392bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_REQUEST); 1393bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->server_user); 1394bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->service); 1395bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(authctxt->method->name); 1396bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(""); /* lang */ 1397bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(options.kbd_interactive_devices ? 1398bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman options.kbd_interactive_devices : ""); 1399bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 1400bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1401bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req); 1402bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 1403bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1404bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1405bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 1406bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * parse INFO_REQUEST, prompt user and send INFO_RESPONSE 1407bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1408d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 1409bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_userauth_info_req(int type, u_int32_t seq, void *ctxt) 1410bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1411bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 1412bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *name, *inst, *lang, *prompt, *response; 1413bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int num_prompts, i; 1414bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int echo = 0; 1415bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1416bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("input_userauth_info_req"); 1417bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1418bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL) 1419bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("input_userauth_info_req: no authentication context"); 1420bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1421bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->info_req_seen = 1; 1422bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1423bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman name = packet_get_string(NULL); 1424bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman inst = packet_get_string(NULL); 1425bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman lang = packet_get_string(NULL); 1426bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlen(name) > 0) 1427bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("%s", name); 1428bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strlen(inst) > 0) 1429bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("%s", inst); 1430d059297112922cabb0c674840589be8db821fd9aAdam Langley free(name); 1431d059297112922cabb0c674840589be8db821fd9aAdam Langley free(inst); 1432d059297112922cabb0c674840589be8db821fd9aAdam Langley free(lang); 1433bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1434bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman num_prompts = packet_get_int(); 1435bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 1436bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Begin to build info response packet based on prompts requested. 1437bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * We commit to providing the correct number of responses, so if 1438bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * further on we run into a problem that prevents this, we have to 1439bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * be sure and clean this up and send a correct error response. 1440bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1441bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE); 1442bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_int(num_prompts); 1443bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1444bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("input_userauth_info_req: num_prompts %d", num_prompts); 1445bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (i = 0; i < num_prompts; i++) { 1446bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman prompt = packet_get_string(NULL); 1447bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman echo = packet_get_char(); 1448bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1449bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman response = read_passphrase(prompt, echo ? RP_ECHO : 0); 1450bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1451bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_cstring(response); 1452d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(response, strlen(response)); 1453d059297112922cabb0c674840589be8db821fd9aAdam Langley free(response); 1454d059297112922cabb0c674840589be8db821fd9aAdam Langley free(prompt); 1455bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1456bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); /* done with parsing incoming message. */ 1457bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1458bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_add_padding(64); 1459bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 1460d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 1461bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1462bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1463bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 1464d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, 1465d059297112922cabb0c674840589be8db821fd9aAdam Langley const u_char *data, size_t datalen) 1466bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1467d059297112922cabb0c674840589be8db821fd9aAdam Langley struct sshbuf *b; 1468bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 1469bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman pid_t pid; 1470d059297112922cabb0c674840589be8db821fd9aAdam Langley int i, r, to[2], from[2], status, sock = packet_get_connection_in(); 1471d059297112922cabb0c674840589be8db821fd9aAdam Langley u_char rversion = 0, version = 2; 1472d059297112922cabb0c674840589be8db821fd9aAdam Langley void (*osigchld)(int); 1473bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1474d059297112922cabb0c674840589be8db821fd9aAdam Langley *sigp = NULL; 1475d059297112922cabb0c674840589be8db821fd9aAdam Langley *lenp = 0; 1476bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1477bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { 1478d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: not installed: %s", __func__, strerror(errno)); 1479d059297112922cabb0c674840589be8db821fd9aAdam Langley return -1; 1480d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1481d059297112922cabb0c674840589be8db821fd9aAdam Langley if (fflush(stdout) != 0) { 1482d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: fflush: %s", __func__, strerror(errno)); 1483bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 1484bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1485bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pipe(to) < 0) { 1486d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: pipe: %s", __func__, strerror(errno)); 1487bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 1488bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1489bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pipe(from) < 0) { 1490d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: pipe: %s", __func__, strerror(errno)); 1491bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 1492bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1493bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((pid = fork()) < 0) { 1494d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: fork: %s", __func__, strerror(errno)); 1495bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 1496bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1497d059297112922cabb0c674840589be8db821fd9aAdam Langley osigchld = signal(SIGCHLD, SIG_DFL); 1498bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (pid == 0) { 1499bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* keep the socket on exec */ 1500d059297112922cabb0c674840589be8db821fd9aAdam Langley fcntl(sock, F_SETFD, 0); 1501bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman permanently_drop_suid(getuid()); 1502bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(from[0]); 1503bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (dup2(from[1], STDOUT_FILENO) < 0) 1504d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: dup2: %s", __func__, strerror(errno)); 1505bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(to[1]); 1506bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (dup2(to[0], STDIN_FILENO) < 0) 1507d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: dup2: %s", __func__, strerror(errno)); 1508bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(from[1]); 1509bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(to[0]); 1510d059297112922cabb0c674840589be8db821fd9aAdam Langley /* Close everything but stdio and the socket */ 1511d059297112922cabb0c674840589be8db821fd9aAdam Langley for (i = STDERR_FILENO + 1; i < sock; i++) 1512d059297112922cabb0c674840589be8db821fd9aAdam Langley close(i); 1513d059297112922cabb0c674840589be8db821fd9aAdam Langley closefrom(sock + 1); 1514d059297112922cabb0c674840589be8db821fd9aAdam Langley debug3("%s: [child] pid=%ld, exec %s", 1515d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, (long)getpid(), _PATH_SSH_KEY_SIGN); 1516bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); 1517d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, 1518bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 1519bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1520bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(from[1]); 1521bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(to[0]); 1522bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1523d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((b = sshbuf_new()) == NULL) 1524d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: sshbuf_new failed", __func__); 1525d059297112922cabb0c674840589be8db821fd9aAdam Langley /* send # of sock, data to be signed */ 1526d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_u32(b, sock) != 0) || 1527d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_string(b, data, datalen)) != 0) 1528d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: buffer error: %s", __func__, ssh_err(r)); 1529d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ssh_msg_send(to[1], version, b) == -1) 1530d059297112922cabb0c674840589be8db821fd9aAdam Langley fatal("%s: couldn't send request", __func__); 1531d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_reset(b); 1532d059297112922cabb0c674840589be8db821fd9aAdam Langley r = ssh_msg_recv(from[0], b); 1533bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(from[0]); 1534bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(to[1]); 1535d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r < 0) { 1536d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: no reply", __func__); 1537d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1538d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1539bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1540d059297112922cabb0c674840589be8db821fd9aAdam Langley errno = 0; 1541d059297112922cabb0c674840589be8db821fd9aAdam Langley while (waitpid(pid, &status, 0) < 0) { 1542d059297112922cabb0c674840589be8db821fd9aAdam Langley if (errno != EINTR) { 1543d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: waitpid %ld: %s", 1544d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, (long)pid, strerror(errno)); 1545d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1546d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1547d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1548d059297112922cabb0c674840589be8db821fd9aAdam Langley if (!WIFEXITED(status)) { 1549d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: exited abnormally", __func__); 1550d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1551d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1552d059297112922cabb0c674840589be8db821fd9aAdam Langley if (WEXITSTATUS(status) != 0) { 1553d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: exited with status %d", 1554d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, WEXITSTATUS(status)); 1555d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1556d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1557d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_u8(b, &rversion)) != 0) { 1558d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: buffer error: %s", __func__, ssh_err(r)); 1559d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1560d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1561d059297112922cabb0c674840589be8db821fd9aAdam Langley if (rversion != version) { 1562d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: bad version", __func__); 1563d059297112922cabb0c674840589be8db821fd9aAdam Langley goto fail; 1564d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1565d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) { 1566d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: buffer error: %s", __func__, ssh_err(r)); 1567d059297112922cabb0c674840589be8db821fd9aAdam Langley fail: 1568d059297112922cabb0c674840589be8db821fd9aAdam Langley signal(SIGCHLD, osigchld); 1569d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_free(b); 1570bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return -1; 1571bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1572d059297112922cabb0c674840589be8db821fd9aAdam Langley signal(SIGCHLD, osigchld); 1573d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_free(b); 1574bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1575bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1576bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1577bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1578bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 1579bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_hostbased(Authctxt *authctxt) 1580bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1581d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh *ssh = active_state; 1582d059297112922cabb0c674840589be8db821fd9aAdam Langley struct sshkey *private = NULL; 1583d059297112922cabb0c674840589be8db821fd9aAdam Langley struct sshbuf *b = NULL; 1584bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman const char *service; 1585d059297112922cabb0c674840589be8db821fd9aAdam Langley u_char *sig = NULL, *keyblob = NULL; 1586d059297112922cabb0c674840589be8db821fd9aAdam Langley char *fp = NULL, *chost = NULL, *lname = NULL; 1587d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t siglen = 0, keylen = 0; 1588d059297112922cabb0c674840589be8db821fd9aAdam Langley int i, r, success = 0; 1589d059297112922cabb0c674840589be8db821fd9aAdam Langley 1590d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->ktypes == NULL) { 1591d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->oktypes = xstrdup(options.hostbased_key_types); 1592d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->ktypes = authctxt->oktypes; 1593d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1594d059297112922cabb0c674840589be8db821fd9aAdam Langley 1595d059297112922cabb0c674840589be8db821fd9aAdam Langley /* 1596d059297112922cabb0c674840589be8db821fd9aAdam Langley * Work through each listed type pattern in HostbasedKeyTypes, 1597d059297112922cabb0c674840589be8db821fd9aAdam Langley * trying each hostkey that matches the type in turn. 1598d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 1599d059297112922cabb0c674840589be8db821fd9aAdam Langley for (;;) { 1600d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->active_ktype == NULL) 1601d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->active_ktype = strsep(&authctxt->ktypes, ","); 1602d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->active_ktype == NULL || 1603d059297112922cabb0c674840589be8db821fd9aAdam Langley *authctxt->active_ktype == '\0') 1604d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1605d059297112922cabb0c674840589be8db821fd9aAdam Langley debug3("%s: trying key type %s", __func__, 1606d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->active_ktype); 1607d059297112922cabb0c674840589be8db821fd9aAdam Langley 1608d059297112922cabb0c674840589be8db821fd9aAdam Langley /* check for a useful key */ 1609d059297112922cabb0c674840589be8db821fd9aAdam Langley private = NULL; 1610d059297112922cabb0c674840589be8db821fd9aAdam Langley for (i = 0; i < authctxt->sensitive->nkeys; i++) { 1611d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->sensitive->keys[i] == NULL || 1612d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->sensitive->keys[i]->type == KEY_RSA1 || 1613d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->sensitive->keys[i]->type == KEY_UNSPEC) 1614d059297112922cabb0c674840589be8db821fd9aAdam Langley continue; 1615d059297112922cabb0c674840589be8db821fd9aAdam Langley if (match_pattern_list( 1616d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_ssh_name(authctxt->sensitive->keys[i]), 1617ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman authctxt->active_ktype, 0) != 1) 1618d059297112922cabb0c674840589be8db821fd9aAdam Langley continue; 1619bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* we take and free the key */ 1620d059297112922cabb0c674840589be8db821fd9aAdam Langley private = authctxt->sensitive->keys[i]; 1621d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->sensitive->keys[i] = NULL; 1622bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman break; 1623bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1624d059297112922cabb0c674840589be8db821fd9aAdam Langley /* Found one */ 1625d059297112922cabb0c674840589be8db821fd9aAdam Langley if (private != NULL) 1626d059297112922cabb0c674840589be8db821fd9aAdam Langley break; 1627d059297112922cabb0c674840589be8db821fd9aAdam Langley /* No more keys of this type; advance */ 1628d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->active_ktype = NULL; 1629bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1630d059297112922cabb0c674840589be8db821fd9aAdam Langley if (private == NULL) { 1631d059297112922cabb0c674840589be8db821fd9aAdam Langley free(authctxt->oktypes); 1632d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->oktypes = authctxt->ktypes = NULL; 1633d059297112922cabb0c674840589be8db821fd9aAdam Langley authctxt->active_ktype = NULL; 1634bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("No more client hostkeys for hostbased authentication."); 1635d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1636bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1637d059297112922cabb0c674840589be8db821fd9aAdam Langley 1638d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, 1639d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_FP_DEFAULT)) == NULL) { 1640d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: sshkey_fingerprint failed", __func__); 1641d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1642bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1643d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: trying hostkey %s %s", 1644d059297112922cabb0c674840589be8db821fd9aAdam Langley __func__, sshkey_ssh_name(private), fp); 1645d059297112922cabb0c674840589be8db821fd9aAdam Langley 1646bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* figure out a name for the client host */ 1647d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((lname = get_local_name(packet_get_connection_in())) == NULL) { 1648d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: cannot get local ipaddr/name", __func__); 1649d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1650bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1651d059297112922cabb0c674840589be8db821fd9aAdam Langley 1652d059297112922cabb0c674840589be8db821fd9aAdam Langley /* XXX sshbuf_put_stringf? */ 1653d059297112922cabb0c674840589be8db821fd9aAdam Langley xasprintf(&chost, "%s.", lname); 1654d059297112922cabb0c674840589be8db821fd9aAdam Langley debug2("%s: chost %s", __func__, chost); 1655bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1656bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : 1657bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->service; 1658d059297112922cabb0c674840589be8db821fd9aAdam Langley 1659bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* construct data */ 1660d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((b = sshbuf_new()) == NULL) { 1661d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: sshbuf_new failed", __func__); 1662d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1663d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1664d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) { 1665d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); 1666d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1667d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1668d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || 1669d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || 1670d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || 1671d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, service)) != 0 || 1672d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || 1673d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 || 1674d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_string(b, keyblob, keylen)) != 0 || 1675d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, chost)) != 0 || 1676d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) { 1677d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: buffer error: %s", __func__, ssh_err(r)); 1678d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1679d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1680d059297112922cabb0c674840589be8db821fd9aAdam Langley 1681bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef DEBUG_PK 1682d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_dump(b, stderr); 1683bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 1684d059297112922cabb0c674840589be8db821fd9aAdam Langley if (authctxt->sensitive->external_keysign) 1685d059297112922cabb0c674840589be8db821fd9aAdam Langley r = ssh_keysign(private, &sig, &siglen, 1686d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_ptr(b), sshbuf_len(b)); 1687d059297112922cabb0c674840589be8db821fd9aAdam Langley else if ((r = sshkey_sign(private, &sig, &siglen, 1688d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_ptr(b), sshbuf_len(b), datafellows)) != 0) 1689d059297112922cabb0c674840589be8db821fd9aAdam Langley debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); 1690d059297112922cabb0c674840589be8db821fd9aAdam Langley if (r != 0) { 1691d059297112922cabb0c674840589be8db821fd9aAdam Langley error("sign using hostkey %s %s failed", 1692d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_ssh_name(private), fp); 1693d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1694bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1695d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || 1696d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || 1697d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || 1698d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || 1699d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 || 1700d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 || 1701d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, chost)) != 0 || 1702d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 || 1703d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_put_string(ssh, sig, siglen)) != 0 || 1704d059297112922cabb0c674840589be8db821fd9aAdam Langley (r = sshpkt_send(ssh)) != 0) { 1705d059297112922cabb0c674840589be8db821fd9aAdam Langley error("%s: packet error: %s", __func__, ssh_err(r)); 1706d059297112922cabb0c674840589be8db821fd9aAdam Langley goto out; 1707d059297112922cabb0c674840589be8db821fd9aAdam Langley } 1708d059297112922cabb0c674840589be8db821fd9aAdam Langley success = 1; 1709bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1710d059297112922cabb0c674840589be8db821fd9aAdam Langley out: 1711d059297112922cabb0c674840589be8db821fd9aAdam Langley if (sig != NULL) { 1712d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(sig, siglen); 1713d059297112922cabb0c674840589be8db821fd9aAdam Langley free(sig); 1714bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1715d059297112922cabb0c674840589be8db821fd9aAdam Langley free(keyblob); 1716d059297112922cabb0c674840589be8db821fd9aAdam Langley free(lname); 1717d059297112922cabb0c674840589be8db821fd9aAdam Langley free(fp); 1718d059297112922cabb0c674840589be8db821fd9aAdam Langley free(chost); 1719d059297112922cabb0c674840589be8db821fd9aAdam Langley sshkey_free(private); 1720d059297112922cabb0c674840589be8db821fd9aAdam Langley sshbuf_free(b); 1721d059297112922cabb0c674840589be8db821fd9aAdam Langley 1722d059297112922cabb0c674840589be8db821fd9aAdam Langley return success; 1723bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1724bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1725bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* find auth method */ 1726bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1727bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 1728bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * given auth method name, if configurable options permit this method fill 1729bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * in auth_ident field and return true, otherwise return false. 1730bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1731bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 1732bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauthmethod_is_enabled(Authmethod *method) 1733bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1734bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (method == NULL) 1735bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1736bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* return false if options indicate this method is disabled */ 1737bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (method->enabled == NULL || *method->enabled == 0) 1738bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1739bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* return false if batch mode is enabled but method needs interactive mode */ 1740bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (method->batch_flag != NULL && *method->batch_flag != 0) 1741bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 1742bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 1743bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1744bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1745bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Authmethod * 1746bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauthmethod_lookup(const char *name) 1747bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1748bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authmethod *method = NULL; 1749bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (name != NULL) 1750bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (method = authmethods; method->name != NULL; method++) 1751bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (strcmp(name, method->name) == 0) 1752bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return method; 1753bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); 1754bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 1755bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1756bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1757bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* XXX internal state */ 1758bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Authmethod *current = NULL; 1759bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char *supported = NULL; 1760bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char *preferred = NULL; 1761bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1762bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 1763bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Given the authentication method list sent by the server, return the 1764bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * next method we should try. If the server initially sends a nil list, 1765bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * use a built-in default list. 1766bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 1767bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic Authmethod * 1768bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauthmethod_get(char *authlist) 1769bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1770bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *name = NULL; 1771bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int next; 1772bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1773bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Use a suitable default if we're passed a nil list. */ 1774bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authlist == NULL || strlen(authlist) == 0) 1775bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authlist = options.preferred_authentications; 1776bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1777bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (supported == NULL || strcmp(authlist, supported) != 0) { 1778bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("start over, passed a different list %s", authlist); 1779d059297112922cabb0c674840589be8db821fd9aAdam Langley free(supported); 1780bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman supported = xstrdup(authlist); 1781bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman preferred = options.preferred_authentications; 1782bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("preferred %s", preferred); 1783bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman current = NULL; 1784bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else if (current != NULL && authmethod_is_enabled(current)) 1785bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return current; 1786bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1787bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (;;) { 1788bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((name = match_list(preferred, supported, &next)) == NULL) { 1789bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("No more authentication methods to try."); 1790bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman current = NULL; 1791bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return NULL; 1792bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1793bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman preferred += next; 1794bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("authmethod_lookup %s", name); 1795bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("remaining preferred: %s", preferred); 1796bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((current = authmethod_lookup(name)) != NULL && 1797bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authmethod_is_enabled(current)) { 1798bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug3("authmethod_is_enabled %s", name); 1799bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Next authentication method: %s", name); 1800d059297112922cabb0c674840589be8db821fd9aAdam Langley free(name); 1801bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return current; 1802bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1803d059297112922cabb0c674840589be8db821fd9aAdam Langley free(name); 1804bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1805bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1806bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1807bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic char * 1808bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanauthmethods_get(void) 1809bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 1810bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authmethod *method = NULL; 1811bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 1812bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *list; 1813bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1814bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_init(&b); 1815bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman for (method = authmethods; method->name != NULL; method++) { 1816bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authmethod_is_enabled(method)) { 1817bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (buffer_len(&b) > 0) 1818bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, ",", 1); 1819bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, method->name, strlen(method->name)); 1820bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1821bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 1822bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_append(&b, "\0", 1); 1823bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman list = xstrdup(buffer_ptr(&b)); 1824bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 1825bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return list; 1826bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 1827bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 1828