Bug Summary

File:src/usr.bin/ssh/ssh/../sshconnect2.c
Warning:line 2232, column 7
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sshconnect2.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/ssh/ssh/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/ssh/ssh/.. -D WITH_OPENSSL -D WITH_ZLIB -D ENABLE_PKCS11 -D HAVE_DLOPEN -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/usr/src/usr.bin/ssh/ssh/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/ssh/ssh/../sshconnect2.c
1/* $OpenBSD: sshconnect2.c,v 1.355 2022/01/06 22:06:51 djm Exp $ */
2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/types.h>
28#include <sys/socket.h>
29#include <sys/wait.h>
30#include <sys/queue.h>
31#include <sys/stat.h>
32
33#include <errno(*__errno()).h>
34#include <fcntl.h>
35#include <limits.h>
36#include <netdb.h>
37#include <stdio.h>
38#include <string.h>
39#include <stdarg.h>
40#include <signal.h>
41#include <pwd.h>
42#include <unistd.h>
43#include <vis.h>
44
45#include "xmalloc.h"
46#include "ssh.h"
47#include "ssh2.h"
48#include "sshbuf.h"
49#include "packet.h"
50#include "compat.h"
51#include "cipher.h"
52#include "sshkey.h"
53#include "kex.h"
54#include "myproposal.h"
55#include "sshconnect.h"
56#include "authfile.h"
57#include "dh.h"
58#include "authfd.h"
59#include "log.h"
60#include "misc.h"
61#include "readconf.h"
62#include "match.h"
63#include "dispatch.h"
64#include "canohost.h"
65#include "msg.h"
66#include "pathnames.h"
67#include "uidswap.h"
68#include "hostfile.h"
69#include "ssherr.h"
70#include "utf8.h"
71#include "ssh-sk.h"
72#include "sk-api.h"
73
74#ifdef GSSAPI
75#include "ssh-gss.h"
76#endif
77
78/* import */
79extern char *client_version_string;
80extern char *server_version_string;
81extern Options options;
82
83/*
84 * SSH2 key exchange
85 */
86
87static char *xxx_host;
88static struct sockaddr *xxx_hostaddr;
89static const struct ssh_conn_info *xxx_conn_info;
90
91static int
92verify_host_key_callback(struct sshkey *hostkey, struct ssh *ssh)
93{
94 if (verify_host_key(xxx_host, xxx_hostaddr, hostkey,
95 xxx_conn_info) == -1)
96 fatal("Host key verification failed.")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 96, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "Host key verification failed."
)
;
97 return 0;
98}
99
100/* Returns the first item from a comma-separated algorithm list */
101static char *
102first_alg(const char *algs)
103{
104 char *ret, *cp;
105
106 ret = xstrdup(algs);
107 if ((cp = strchr(ret, ',')) != NULL((void*)0))
108 *cp = '\0';
109 return ret;
110}
111
112static char *
113order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port,
114 const struct ssh_conn_info *cinfo)
115{
116 char *oavail = NULL((void*)0), *avail = NULL((void*)0), *first = NULL((void*)0), *last = NULL((void*)0);
117 char *alg = NULL((void*)0), *hostname = NULL((void*)0), *ret = NULL((void*)0), *best = NULL((void*)0);
118 size_t maxlen;
119 struct hostkeys *hostkeys = NULL((void*)0);
120 int ktype;
121 u_int i;
122
123 /* Find all hostkeys for this hostname */
124 get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL((void*)0));
125 hostkeys = init_hostkeys();
126 for (i = 0; i < options.num_user_hostfiles; i++)
127 load_hostkeys(hostkeys, hostname, options.user_hostfiles[i], 0);
128 for (i = 0; i < options.num_system_hostfiles; i++) {
129 load_hostkeys(hostkeys, hostname,
130 options.system_hostfiles[i], 0);
131 }
132 if (options.known_hosts_command != NULL((void*)0)) {
133 load_hostkeys_command(hostkeys, options.known_hosts_command,
134 "ORDER", cinfo, NULL((void*)0), host);
135 }
136 /*
137 * If a plain public key exists that matches the type of the best
138 * preference HostkeyAlgorithms, then use the whole list as is.
139 * Note that we ignore whether the best preference algorithm is a
140 * certificate type, as sshconnect.c will downgrade certs to
141 * plain keys if necessary.
142 */
143 best = first_alg(options.hostkeyalgorithms);
144 if (lookup_key_in_hostkeys_by_type(hostkeys,
145 sshkey_type_plain(sshkey_type_from_name(best)),
146 sshkey_ecdsa_nid_from_name(best), NULL((void*)0))) {
147 debug3_f("have matching best-preference key type %s, "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
148, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "have matching best-preference key type %s, "
"using HostkeyAlgorithms verbatim", best)
148 "using HostkeyAlgorithms verbatim", best)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
148, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "have matching best-preference key type %s, "
"using HostkeyAlgorithms verbatim", best)
;
149 ret = xstrdup(options.hostkeyalgorithms);
150 goto out;
151 }
152
153 /*
154 * Otherwise, prefer the host key algorithms that match known keys
155 * while keeping the ordering of HostkeyAlgorithms as much as possible.
156 */
157 oavail = avail = xstrdup(options.hostkeyalgorithms);
158 maxlen = strlen(avail) + 1;
159 first = xmalloc(maxlen);
160 last = xmalloc(maxlen);
161 *first = *last = '\0';
162
163#define ALG_APPEND(to, from) \
164 do { \
165 if (*to != '\0') \
166 strlcat(to, ",", maxlen); \
167 strlcat(to, from, maxlen); \
168 } while (0)
169
170 while ((alg = strsep(&avail, ",")) && *alg != '\0') {
171 if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
172 fatal_f("unknown alg %s", alg)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 172, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "unknown alg %s", alg
)
;
173 /*
174 * If we have a @cert-authority marker in known_hosts then
175 * prefer all certificate algorithms.
176 */
177 if (sshkey_type_is_cert(ktype) &&
178 lookup_marker_in_hostkeys(hostkeys, MRK_CA)) {
179 ALG_APPEND(first, alg);
180 continue;
181 }
182 /* If the key appears in known_hosts then prefer it */
183 if (lookup_key_in_hostkeys_by_type(hostkeys,
184 sshkey_type_plain(ktype),
185 sshkey_ecdsa_nid_from_name(alg), NULL((void*)0))) {
186 ALG_APPEND(first, alg);
187 continue;
188 }
189 /* Otherwise, put it last */
190 ALG_APPEND(last, alg);
191 }
192#undef ALG_APPEND
193 xasprintf(&ret, "%s%s%s", first,
194 (*first == '\0' || *last == '\0') ? "" : ",", last);
195 if (*first != '\0')
196 debug3_f("prefer hostkeyalgs: %s", first)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
196, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "prefer hostkeyalgs: %s"
, first)
;
197 else
198 debug3_f("no algorithms matched; accept original")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
198, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "no algorithms matched; accept original"
)
;
199 out:
200 free(best);
201 free(first);
202 free(last);
203 free(hostname);
204 free(oavail);
205 free_hostkeys(hostkeys);
206
207 return ret;
208}
209
210void
211ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
212 const struct ssh_conn_info *cinfo)
213{
214 char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT"curve25519-sha256," "curve25519-sha256@libssh.org," "ecdh-sha2-nistp256,"
"ecdh-sha2-nistp384," "ecdh-sha2-nistp521," "sntrup761x25519-sha512@openssh.com,"
"diffie-hellman-group-exchange-sha256," "diffie-hellman-group16-sha512,"
"diffie-hellman-group18-sha512," "diffie-hellman-group14-sha256"
, "ssh-ed25519-cert-v01@openssh.com," "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"ecdsa-sha2-nistp384-cert-v01@openssh.com," "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
"sk-ssh-ed25519-cert-v01@openssh.com," "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"rsa-sha2-512-cert-v01@openssh.com," "rsa-sha2-256-cert-v01@openssh.com,"
"ssh-ed25519," "ecdsa-sha2-nistp256," "ecdsa-sha2-nistp384,"
"ecdsa-sha2-nistp521," "sk-ssh-ed25519@openssh.com," "sk-ecdsa-sha2-nistp256@openssh.com,"
"rsa-sha2-512," "rsa-sha2-256", "chacha20-poly1305@openssh.com,"
"aes128-ctr,aes192-ctr,aes256-ctr," "aes128-gcm@openssh.com,aes256-gcm@openssh.com"
, "chacha20-poly1305@openssh.com," "aes128-ctr,aes192-ctr,aes256-ctr,"
"aes128-gcm@openssh.com,aes256-gcm@openssh.com", "umac-64-etm@openssh.com,"
"umac-128-etm@openssh.com," "hmac-sha2-256-etm@openssh.com,"
"hmac-sha2-512-etm@openssh.com," "hmac-sha1-etm@openssh.com,"
"umac-64@openssh.com," "umac-128@openssh.com," "hmac-sha2-256,"
"hmac-sha2-512," "hmac-sha1", "umac-64-etm@openssh.com," "umac-128-etm@openssh.com,"
"hmac-sha2-256-etm@openssh.com," "hmac-sha2-512-etm@openssh.com,"
"hmac-sha1-etm@openssh.com," "umac-64@openssh.com," "umac-128@openssh.com,"
"hmac-sha2-256," "hmac-sha2-512," "hmac-sha1", "none,zlib@openssh.com"
, "none,zlib@openssh.com", "", ""
};
215 char *s, *all_key;
216 int r, use_known_hosts_order = 0;
217
218 xxx_host = host;
219 xxx_hostaddr = hostaddr;
220 xxx_conn_info = cinfo;
221
222 /*
223 * If the user has not specified HostkeyAlgorithms, or has only
224 * appended or removed algorithms from that list then prefer algorithms
225 * that are in the list that are supported by known_hosts keys.
226 */
227 if (options.hostkeyalgorithms == NULL((void*)0) ||
228 options.hostkeyalgorithms[0] == '-' ||
229 options.hostkeyalgorithms[0] == '+')
230 use_known_hosts_order = 1;
231
232 /* Expand or fill in HostkeyAlgorithms */
233 all_key = sshkey_alg_list(0, 0, 1, ',');
234 if ((r = kex_assemble_names(&options.hostkeyalgorithms,
235 kex_default_pk_alg(), all_key)) != 0)
236 fatal_fr(r, "kex_assemble_namelist")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 236, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "kex_assemble_namelist"
)
;
237 free(all_key);
238
239 if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL((void*)0))
240 fatal_f("kex_names_cat")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 240, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "kex_names_cat")
;
241 myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh, s);
242 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
243 compat_cipher_proposal(ssh, options.ciphers);
244 myproposal[PROPOSAL_ENC_ALGS_STOC] =
245 compat_cipher_proposal(ssh, options.ciphers);
246 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
247 myproposal[PROPOSAL_COMP_ALGS_STOC] =
248 (char *)compression_alg_list(options.compression);
249 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
250 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
251 if (use_known_hosts_order) {
252 /* Query known_hosts and prefer algorithms that appear there */
253 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
254 compat_pkalg_proposal(ssh,
255 order_hostkeyalgs(host, hostaddr, port, cinfo));
256 } else {
257 /* Use specified HostkeyAlgorithms exactly */
258 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
259 compat_pkalg_proposal(ssh, options.hostkeyalgorithms);
260 }
261
262 if (options.rekey_limit || options.rekey_interval)
263 ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
264 options.rekey_interval);
265
266 /* start key exchange */
267 if ((r = kex_setup(ssh, myproposal)) != 0)
268 fatal_r(r, "kex_setup")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 268, 0, SYSLOG_LEVEL_FATAL, ssh_err(r), "kex_setup")
;
269#ifdef WITH_OPENSSL1
270 ssh->kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_client;
271 ssh->kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_client;
272 ssh->kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_client;
273 ssh->kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_client;
274 ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
275 ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
276 ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
277 ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
278#endif
279 ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client;
280 ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client;
281 ssh->kex->verify_host_key=&verify_host_key_callback;
282
283 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done);
284
285 /* remove ext-info from the KEX proposals for rekeying */
286 myproposal[PROPOSAL_KEX_ALGS] =
287 compat_kex_proposal(ssh, options.kex_algorithms);
288 if ((r = kex_prop2buf(ssh->kex->my, myproposal)) != 0)
289 fatal_r(r, "kex_prop2buf")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 289, 0, SYSLOG_LEVEL_FATAL, ssh_err(r), "kex_prop2buf")
;
290
291#ifdef DEBUG_KEXDH
292 /* send 1st encrypted/maced/compressed message */
293 if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE2)) != 0 ||
294 (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
295 (r = sshpkt_send(ssh)) != 0 ||
296 (r = ssh_packet_write_wait(ssh)) != 0)
297 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 297, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
298#endif
299}
300
301/*
302 * Authenticate user
303 */
304
305typedef struct cauthctxt Authctxt;
306typedef struct cauthmethod Authmethod;
307typedef struct identity Identity;
308typedef struct idlist Idlist;
309
310struct identity {
311 TAILQ_ENTRY(identity)struct { struct identity *tqe_next; struct identity **tqe_prev
; }
next;
312 int agent_fd; /* >=0 if agent supports key */
313 struct sshkey *key; /* public/private key */
314 char *filename; /* comment for agent-only keys */
315 int tried;
316 int isprivate; /* key points to the private key */
317 int userprovided;
318};
319TAILQ_HEAD(idlist, identity)struct idlist { struct identity *tqh_first; struct identity *
*tqh_last; }
;
320
321struct cauthctxt {
322 const char *server_user;
323 const char *local_user;
324 const char *host;
325 const char *service;
326 struct cauthmethod *method;
327 sig_atomic_t success;
328 char *authlist;
329#ifdef GSSAPI
330 /* gssapi */
331 gss_OID_set gss_supported_mechs;
332 u_int mech_tried;
333#endif
334 /* pubkey */
335 struct idlist keys;
336 int agent_fd;
337 /* hostbased */
338 Sensitive *sensitive;
339 char *oktypes, *ktypes;
340 const char *active_ktype;
341 /* kbd-interactive */
342 int info_req_seen;
343 int attempt_kbdint;
344 /* password */
345 int attempt_passwd;
346 /* generic */
347 void *methoddata;
348};
349
350struct cauthmethod {
351 char *name; /* string to compare against server's list */
352 int (*userauth)(struct ssh *ssh);
353 void (*cleanup)(struct ssh *ssh);
354 int *enabled; /* flag in option struct that enables method */
355 int *batch_flag; /* flag in option struct that disables method */
356};
357
358static int input_userauth_service_accept(int, u_int32_t, struct ssh *);
359static int input_userauth_ext_info(int, u_int32_t, struct ssh *);
360static int input_userauth_success(int, u_int32_t, struct ssh *);
361static int input_userauth_failure(int, u_int32_t, struct ssh *);
362static int input_userauth_banner(int, u_int32_t, struct ssh *);
363static int input_userauth_error(int, u_int32_t, struct ssh *);
364static int input_userauth_info_req(int, u_int32_t, struct ssh *);
365static int input_userauth_pk_ok(int, u_int32_t, struct ssh *);
366static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *);
367
368static int userauth_none(struct ssh *);
369static int userauth_pubkey(struct ssh *);
370static int userauth_passwd(struct ssh *);
371static int userauth_kbdint(struct ssh *);
372static int userauth_hostbased(struct ssh *);
373
374#ifdef GSSAPI
375static int userauth_gssapi(struct ssh *);
376static void userauth_gssapi_cleanup(struct ssh *);
377static int input_gssapi_response(int type, u_int32_t, struct ssh *);
378static int input_gssapi_token(int type, u_int32_t, struct ssh *);
379static int input_gssapi_error(int, u_int32_t, struct ssh *);
380static int input_gssapi_errtok(int, u_int32_t, struct ssh *);
381#endif
382
383void userauth(struct ssh *, char *);
384
385static void pubkey_cleanup(struct ssh *);
386static int sign_and_send_pubkey(struct ssh *ssh, Identity *);
387static void pubkey_prepare(struct ssh *, Authctxt *);
388static void pubkey_reset(Authctxt *);
389static struct sshkey *load_identity_file(Identity *);
390
391static Authmethod *authmethod_get(char *authlist);
392static Authmethod *authmethod_lookup(const char *name);
393static char *authmethods_get(void);
394
395Authmethod authmethods[] = {
396#ifdef GSSAPI
397 {"gssapi-with-mic",
398 userauth_gssapi,
399 userauth_gssapi_cleanup,
400 &options.gss_authentication,
401 NULL((void*)0)},
402#endif
403 {"hostbased",
404 userauth_hostbased,
405 NULL((void*)0),
406 &options.hostbased_authentication,
407 NULL((void*)0)},
408 {"publickey",
409 userauth_pubkey,
410 NULL((void*)0),
411 &options.pubkey_authentication,
412 NULL((void*)0)},
413 {"keyboard-interactive",
414 userauth_kbdint,
415 NULL((void*)0),
416 &options.kbd_interactive_authentication,
417 &options.batch_mode},
418 {"password",
419 userauth_passwd,
420 NULL((void*)0),
421 &options.password_authentication,
422 &options.batch_mode},
423 {"none",
424 userauth_none,
425 NULL((void*)0),
426 NULL((void*)0),
427 NULL((void*)0)},
428 {NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)}
429};
430
431void
432ssh_userauth2(struct ssh *ssh, const char *local_user,
433 const char *server_user, char *host, Sensitive *sensitive)
434{
435 Authctxt authctxt;
436 int r;
437
438 if (options.preferred_authentications == NULL((void*)0))
439 options.preferred_authentications = authmethods_get();
440
441 /* setup authentication context */
442 memset(&authctxt, 0, sizeof(authctxt));
443 authctxt.server_user = server_user;
444 authctxt.local_user = local_user;
445 authctxt.host = host;
446 authctxt.service = "ssh-connection"; /* service name */
447 authctxt.success = 0;
448 authctxt.method = authmethod_lookup("none");
449 authctxt.authlist = NULL((void*)0);
450 authctxt.methoddata = NULL((void*)0);
451 authctxt.sensitive = sensitive;
452 authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL((void*)0);
453 authctxt.info_req_seen = 0;
454 authctxt.attempt_kbdint = 0;
455 authctxt.attempt_passwd = 0;
456#if GSSAPI
457 authctxt.gss_supported_mechs = NULL((void*)0);
458 authctxt.mech_tried = 0;
459#endif
460 authctxt.agent_fd = -1;
461 pubkey_prepare(ssh, &authctxt);
462 if (authctxt.method == NULL((void*)0)) {
463 fatal_f("internal error: cannot send userauth none request")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 463, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "internal error: cannot send userauth none request"
)
;
464 }
465
466 if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST5)) != 0 ||
467 (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 ||
468 (r = sshpkt_send(ssh)) != 0)
469 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 469, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
470
471 ssh->authctxt = &authctxt;
472 ssh_dispatch_init(ssh, &input_userauth_error);
473 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO7, &input_userauth_ext_info);
474 ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT6, &input_userauth_service_accept);
475 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
476 pubkey_cleanup(ssh);
477 ssh->authctxt = NULL((void*)0);
478
479 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN50, SSH2_MSG_USERAUTH_MAX79, NULL((void*)0));
480
481 if (!authctxt.success)
482 fatal("Authentication failed.")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 482, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "Authentication failed."
)
;
483 if (ssh_packet_connection_is_on_socket(ssh)) {
484 verbose("Authenticated to %s ([%s]:%d) using \"%s\".", host,sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
486, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated to %s ([%s]:%d) using \"%s\"."
, host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), authctxt
.method->name)
485 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh),sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
486, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated to %s ([%s]:%d) using \"%s\"."
, host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), authctxt
.method->name)
486 authctxt.method->name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
486, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated to %s ([%s]:%d) using \"%s\"."
, host, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), authctxt
.method->name)
;
487 } else {
488 verbose("Authenticated to %s (via proxy) using \"%s\".", host,sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
489, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated to %s (via proxy) using \"%s\"."
, host, authctxt.method->name)
489 authctxt.method->name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
489, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated to %s (via proxy) using \"%s\"."
, host, authctxt.method->name)
;
490 }
491}
492
493/* ARGSUSED */
494static int
495input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
496{
497 int r;
498
499 if (ssh_packet_remaining(ssh) > 0) {
500 char *reply;
501
502 if ((r = sshpkt_get_cstring(ssh, &reply, NULL((void*)0))) != 0)
503 goto out;
504 debug2("service_accept: %s", reply)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
504, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "service_accept: %s"
, reply)
;
505 free(reply);
506 } else {
507 debug2("buggy server: service_accept w/o service")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
507, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "buggy server: service_accept w/o service"
)
;
508 }
509 if ((r = sshpkt_get_end(ssh)) != 0)
510 goto out;
511 debug("SSH2_MSG_SERVICE_ACCEPT received")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
511, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "SSH2_MSG_SERVICE_ACCEPT received"
)
;
512
513 /* initial userauth request */
514 userauth_none(ssh);
515
516 ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO7, &input_userauth_error);
517 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS52, &input_userauth_success);
518 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_FAILURE51, &input_userauth_failure);
519 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_BANNER53, &input_userauth_banner);
520 r = 0;
521 out:
522 return r;
523}
524
525/* ARGSUSED */
526static int
527input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
528{
529 return kex_input_ext_info(type, seqnr, ssh);
530}
531
532void
533userauth(struct ssh *ssh, char *authlist)
534{
535 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
536
537 if (authctxt->method != NULL((void*)0) && authctxt->method->cleanup != NULL((void*)0))
538 authctxt->method->cleanup(ssh);
539
540 free(authctxt->methoddata);
541 authctxt->methoddata = NULL((void*)0);
542 if (authlist == NULL((void*)0)) {
543 authlist = authctxt->authlist;
544 } else {
545 free(authctxt->authlist);
546 authctxt->authlist = authlist;
547 }
548 for (;;) {
549 Authmethod *method = authmethod_get(authlist);
550 if (method == NULL((void*)0))
551 fatal("%s@%s: Permission denied (%s).",sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 552, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "%s@%s: Permission denied (%s)."
, authctxt->server_user, authctxt->host, authlist)
552 authctxt->server_user, authctxt->host, authlist)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 552, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "%s@%s: Permission denied (%s)."
, authctxt->server_user, authctxt->host, authlist)
;
553 authctxt->method = method;
554
555 /* reset the per method handler */
556 ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_PER_METHOD_MIN60,
557 SSH2_MSG_USERAUTH_PER_METHOD_MAX79, NULL((void*)0));
558
559 /* and try new method */
560 if (method->userauth(ssh) != 0) {
561 debug2("we sent a %s packet, wait for reply", method->name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
561, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "we sent a %s packet, wait for reply"
, method->name)
;
562 break;
563 } else {
564 debug2("we did not send a packet, disable method")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
564, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "we did not send a packet, disable method"
)
;
565 method->enabled = NULL((void*)0);
566 }
567 }
568}
569
570/* ARGSUSED */
571static int
572input_userauth_error(int type, u_int32_t seq, struct ssh *ssh)
573{
574 fatal_f("bad message during authentication: type %d", type)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 574, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "bad message during authentication: type %d"
, type)
;
575 return 0;
576}
577
578/* ARGSUSED */
579static int
580input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh)
581{
582 char *msg = NULL((void*)0);
583 size_t len;
584 int r;
585
586 debug3_f("entering")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
586, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "entering")
;
587 if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 ||
588 (r = sshpkt_get_cstring(ssh, NULL((void*)0), NULL((void*)0))) != 0)
589 goto out;
590 if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO)
591 fmprintf(stderr(&__sF[2]), "%s", msg);
592 r = 0;
593 out:
594 free(msg);
595 return r;
596}
597
598/* ARGSUSED */
599static int
600input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
601{
602 Authctxt *authctxt = ssh->authctxt;
603
604 if (authctxt == NULL((void*)0))
605 fatal_f("no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 605, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "no authentication context"
)
;
606 free(authctxt->authlist);
607 authctxt->authlist = NULL((void*)0);
608 if (authctxt->method != NULL((void*)0) && authctxt->method->cleanup != NULL((void*)0))
609 authctxt->method->cleanup(ssh);
610 free(authctxt->methoddata);
611 authctxt->methoddata = NULL((void*)0);
612 authctxt->success = 1; /* break out */
613 return 0;
614}
615
616#if 0
617static int
618input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh)
619{
620 Authctxt *authctxt = ssh->authctxt;
621
622 if (authctxt == NULL((void*)0))
623 fatal_f("no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 623, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "no authentication context"
)
;
624
625 fatal("Unexpected authentication success during %s.",sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 626, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "Unexpected authentication success during %s."
, authctxt->method->name)
626 authctxt->method->name)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 626, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "Unexpected authentication success during %s."
, authctxt->method->name)
;
627 return 0;
628}
629#endif
630
631/* ARGSUSED */
632static int
633input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh)
634{
635 Authctxt *authctxt = ssh->authctxt;
636 char *authlist = NULL((void*)0);
637 u_char partial;
638
639 if (authctxt == NULL((void*)0))
640 fatal("input_userauth_failure: no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 640, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_userauth_failure: no authentication context"
)
;
641
642 if (sshpkt_get_cstring(ssh, &authlist, NULL((void*)0)) != 0 ||
643 sshpkt_get_u8(ssh, &partial) != 0 ||
644 sshpkt_get_end(ssh) != 0)
645 goto out;
646
647 if (partial != 0) {
648 verbose("Authenticated using \"%s\" with partial success.",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
649, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated using \"%s\" with partial success."
, authctxt->method->name)
649 authctxt->method->name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
649, 0, SYSLOG_LEVEL_VERBOSE, ((void*)0), "Authenticated using \"%s\" with partial success."
, authctxt->method->name)
;
650 /* reset state */
651 pubkey_reset(authctxt);
652 }
653 debug("Authentications that can continue: %s", authlist)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
653, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Authentications that can continue: %s"
, authlist)
;
654
655 userauth(ssh, authlist);
656 authlist = NULL((void*)0);
657 out:
658 free(authlist);
659 return 0;
660}
661
662/*
663 * Format an identity for logging including filename, key type, fingerprint
664 * and location (agent, etc.). Caller must free.
665 */
666static char *
667format_identity(Identity *id)
668{
669 char *fp = NULL((void*)0), *ret = NULL((void*)0);
670 const char *note = "";
671
672 if (id->key != NULL((void*)0)) {
673 fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
674 SSH_FP_DEFAULT);
675 }
676 if (id->key) {
677 if ((id->key->flags & SSHKEY_FLAG_EXT0x0001) != 0)
678 note = " token";
679 else if (sshkey_is_sk(id->key))
680 note = " authenticator";
681 }
682 xasprintf(&ret, "%s %s%s%s%s%s%s",
683 id->filename,
684 id->key ? sshkey_type(id->key) : "", id->key ? " " : "",
685 fp ? fp : "",
686 id->userprovided ? " explicit" : "", note,
687 id->agent_fd != -1 ? " agent" : "");
688 free(fp);
689 return ret;
690}
691
692/* ARGSUSED */
693static int
694input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
695{
696 Authctxt *authctxt = ssh->authctxt;
697 struct sshkey *key = NULL((void*)0);
698 Identity *id = NULL((void*)0);
699 int pktype, found = 0, sent = 0;
700 size_t blen;
701 char *pkalg = NULL((void*)0), *fp = NULL((void*)0), *ident = NULL((void*)0);
702 u_char *pkblob = NULL((void*)0);
703 int r;
704
705 if (authctxt == NULL((void*)0))
706 fatal("input_userauth_pk_ok: no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 706, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_userauth_pk_ok: no authentication context"
)
;
707
708 if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL((void*)0))) != 0 ||
709 (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
710 (r = sshpkt_get_end(ssh)) != 0)
711 goto done;
712
713 if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) {
714 debug_f("server sent unknown pkalg %s", pkalg)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
714, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "server sent unknown pkalg %s"
, pkalg)
;
715 goto done;
716 }
717 if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
718 debug_r(r, "no key from blob. pkalg %s", pkalg)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
718, 0, SYSLOG_LEVEL_DEBUG1, ssh_err(r), "no key from blob. pkalg %s"
, pkalg)
;
719 goto done;
720 }
721 if (key->type != pktype) {
722 error("input_userauth_pk_ok: type mismatch "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
724, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "input_userauth_pk_ok: type mismatch "
"for decoded key (received %d, expected %d)", key->type, pktype
)
723 "for decoded key (received %d, expected %d)",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
724, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "input_userauth_pk_ok: type mismatch "
"for decoded key (received %d, expected %d)", key->type, pktype
)
724 key->type, pktype)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
724, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "input_userauth_pk_ok: type mismatch "
"for decoded key (received %d, expected %d)", key->type, pktype
)
;
725 goto done;
726 }
727
728 /*
729 * search keys in the reverse order, because last candidate has been
730 * moved to the end of the queue. this also avoids confusion by
731 * duplicate keys
732 */
733 TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next)for((id) = (*(((struct idlist *)((&authctxt->keys)->
tqh_last))->tqh_last)); (id) != ((void*)0); (id) = (*(((struct
idlist *)((id)->next.tqe_prev))->tqh_last)))
{
734 if (sshkey_equal(key, id->key)) {
735 found = 1;
736 break;
737 }
738 }
739 if (!found || id == NULL((void*)0)) {
740 fp = sshkey_fingerprint(key, options.fingerprint_hash,
741 SSH_FP_DEFAULT);
742 error_f("server replied with unknown key: %s %s",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
743, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "server replied with unknown key: %s %s"
, sshkey_type(key), fp == ((void*)0) ? "<ERROR>" : fp)
743 sshkey_type(key), fp == NULL ? "<ERROR>" : fp)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
743, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "server replied with unknown key: %s %s"
, sshkey_type(key), fp == ((void*)0) ? "<ERROR>" : fp)
;
744 goto done;
745 }
746 ident = format_identity(id);
747 debug("Server accepts key: %s", ident)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
747, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Server accepts key: %s"
, ident)
;
748 sent = sign_and_send_pubkey(ssh, id);
749 r = 0;
750 done:
751 sshkey_free(key);
752 free(ident);
753 free(fp);
754 free(pkalg);
755 free(pkblob);
756
757 /* try another method if we did not send a packet */
758 if (r == 0 && sent == 0)
759 userauth(ssh, NULL((void*)0));
760 return r;
761}
762
763#ifdef GSSAPI
764static int
765userauth_gssapi(struct ssh *ssh)
766{
767 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
768 Gssctxt *gssctxt = NULL((void*)0);
769 OM_uint32 min;
770 int r, ok = 0;
771 gss_OID mech = NULL((void*)0);
772
773 /* Try one GSSAPI method at a time, rather than sending them all at
774 * once. */
775
776 if (authctxt->gss_supported_mechs == NULL((void*)0))
777 gss_indicate_mechs(&min, &authctxt->gss_supported_mechs);
778
779 /* Check to see whether the mechanism is usable before we offer it */
780 while (authctxt->mech_tried < authctxt->gss_supported_mechs->count &&
781 !ok) {
782 mech = &authctxt->gss_supported_mechs->
783 elements[authctxt->mech_tried];
784 /* My DER encoding requires length<128 */
785 if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt,
786 mech, authctxt->host)) {
787 ok = 1; /* Mechanism works */
788 } else {
789 authctxt->mech_tried++;
790 }
791 }
792
793 if (!ok || mech == NULL((void*)0))
794 return 0;
795
796 authctxt->methoddata=(void *)gssctxt;
797
798 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
799 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
800 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
801 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
802 (r = sshpkt_put_u32(ssh, 1)) != 0 ||
803 (r = sshpkt_put_u32(ssh, (mech->length) + 2)) != 0 ||
804 (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 ||
805 (r = sshpkt_put_u8(ssh, mech->length)) != 0 ||
806 (r = sshpkt_put(ssh, mech->elements, mech->length)) != 0 ||
807 (r = sshpkt_send(ssh)) != 0)
808 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 808, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
809
810 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
811 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
812 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
813 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
814
815 authctxt->mech_tried++; /* Move along to next candidate */
816
817 return 1;
818}
819
820static void
821userauth_gssapi_cleanup(struct ssh *ssh)
822{
823 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
824 Gssctxt *gssctxt = (Gssctxt *)authctxt->methoddata;
825
826 ssh_gssapi_delete_ctx(&gssctxt);
827 authctxt->methoddata = NULL((void*)0);
828
829 free(authctxt->gss_supported_mechs);
830 authctxt->gss_supported_mechs = NULL((void*)0);
831}
832
833static OM_uint32
834process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok)
835{
836 Authctxt *authctxt = ssh->authctxt;
837 Gssctxt *gssctxt = authctxt->methoddata;
838 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
839 gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
840 gss_buffer_desc gssbuf;
841 OM_uint32 status, ms, flags;
842 int r;
843
844 status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
845 recv_tok, &send_tok, &flags);
846
847 if (send_tok.length > 0) {
848 u_char type = GSS_ERROR(status) ?
849 SSH2_MSG_USERAUTH_GSSAPI_ERRTOK :
850 SSH2_MSG_USERAUTH_GSSAPI_TOKEN;
851
852 if ((r = sshpkt_start(ssh, type)) != 0 ||
853 (r = sshpkt_put_string(ssh, send_tok.value,
854 send_tok.length)) != 0 ||
855 (r = sshpkt_send(ssh)) != 0)
856 fatal_fr(r, "send %u packet", type)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 856, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send %u packet", type
)
;
857
858 gss_release_buffer(&ms, &send_tok);
859 }
860
861 if (status == GSS_S_COMPLETE) {
862 /* send either complete or MIC, depending on mechanism */
863 if (!(flags & GSS_C_INTEG_FLAG)) {
864 if ((r = sshpkt_start(ssh,
865 SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 ||
866 (r = sshpkt_send(ssh)) != 0)
867 fatal_fr(r, "send completion")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 867, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send completion")
;
868 } else {
869 struct sshbuf *b;
870
871 if ((b = sshbuf_new()) == NULL((void*)0))
872 fatal_f("sshbuf_new failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 872, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_new failed"
)
;
873 ssh_gssapi_buildmic(b, authctxt->server_user,
874 authctxt->service, "gssapi-with-mic",
875 ssh->kex->session_id);
876
877 if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL((void*)0))
878 fatal_f("sshbuf_mutable_ptr failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 878, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_mutable_ptr failed"
)
;
879 gssbuf.length = sshbuf_len(b);
880
881 status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
882
883 if (!GSS_ERROR(status)) {
884 if ((r = sshpkt_start(ssh,
885 SSH2_MSG_USERAUTH_GSSAPI_MIC)) != 0 ||
886 (r = sshpkt_put_string(ssh, mic.value,
887 mic.length)) != 0 ||
888 (r = sshpkt_send(ssh)) != 0)
889 fatal_fr(r, "send MIC")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 889, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send MIC")
;
890 }
891
892 sshbuf_free(b);
893 gss_release_buffer(&ms, &mic);
894 }
895 }
896
897 return status;
898}
899
900/* ARGSUSED */
901static int
902input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh)
903{
904 Authctxt *authctxt = ssh->authctxt;
905 Gssctxt *gssctxt;
906 size_t oidlen;
907 u_char *oidv = NULL((void*)0);
908 int r;
909
910 if (authctxt == NULL((void*)0))
911 fatal("input_gssapi_response: no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 911, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_gssapi_response: no authentication context"
)
;
912 gssctxt = authctxt->methoddata;
913
914 /* Setup our OID */
915 if ((r = sshpkt_get_string(ssh, &oidv, &oidlen)) != 0)
916 goto done;
917
918 if (oidlen <= 2 ||
919 oidv[0] != SSH_GSS_OIDTYPE ||
920 oidv[1] != oidlen - 2) {
921 debug("Badly encoded mechanism OID received")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
921, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Badly encoded mechanism OID received"
)
;
922 userauth(ssh, NULL((void*)0));
923 goto ok;
924 }
925
926 if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))
927 fatal("Server returned different OID than expected")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 927, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "Server returned different OID than expected"
)
;
928
929 if ((r = sshpkt_get_end(ssh)) != 0)
930 goto done;
931
932 if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
933 /* Start again with next method on list */
934 debug("Trying to start again")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
934, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Trying to start again"
)
;
935 userauth(ssh, NULL((void*)0));
936 goto ok;
937 }
938 ok:
939 r = 0;
940 done:
941 free(oidv);
942 return r;
943}
944
945/* ARGSUSED */
946static int
947input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh)
948{
949 Authctxt *authctxt = ssh->authctxt;
950 gss_buffer_desc recv_tok;
951 u_char *p = NULL((void*)0);
952 size_t len;
953 OM_uint32 status;
954 int r;
955
956 if (authctxt == NULL((void*)0))
957 fatal("input_gssapi_response: no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 957, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_gssapi_response: no authentication context"
)
;
958
959 if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
960 (r = sshpkt_get_end(ssh)) != 0)
961 goto out;
962
963 recv_tok.value = p;
964 recv_tok.length = len;
965 status = process_gssapi_token(ssh, &recv_tok);
966
967 /* Start again with the next method in the list */
968 if (GSS_ERROR(status)) {
969 userauth(ssh, NULL((void*)0));
970 /* ok */
971 }
972 r = 0;
973 out:
974 free(p);
975 return r;
976}
977
978/* ARGSUSED */
979static int
980input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh)
981{
982 Authctxt *authctxt = ssh->authctxt;
983 Gssctxt *gssctxt;
984 gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
985 gss_buffer_desc recv_tok;
986 OM_uint32 ms;
987 u_char *p = NULL((void*)0);
988 size_t len;
989 int r;
990
991 if (authctxt == NULL((void*)0))
992 fatal("input_gssapi_response: no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 992, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_gssapi_response: no authentication context"
)
;
993 gssctxt = authctxt->methoddata;
994
995 if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
996 (r = sshpkt_get_end(ssh)) != 0) {
997 free(p);
998 return r;
999 }
1000
1001 /* Stick it into GSSAPI and see what it says */
1002 recv_tok.value = p;
1003 recv_tok.length = len;
1004 (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
1005 &recv_tok, &send_tok, NULL((void*)0));
1006 free(p);
1007 gss_release_buffer(&ms, &send_tok);
1008
1009 /* Server will be returning a failed packet after this one */
1010 return 0;
1011}
1012
1013/* ARGSUSED */
1014static int
1015input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
1016{
1017 char *msg = NULL((void*)0);
1018 char *lang = NULL((void*)0);
1019 int r;
1020
1021 if ((r = sshpkt_get_u32(ssh, NULL((void*)0))) != 0 || /* maj */
1022 (r = sshpkt_get_u32(ssh, NULL((void*)0))) != 0 || /* min */
1023 (r = sshpkt_get_cstring(ssh, &msg, NULL((void*)0))) != 0 ||
1024 (r = sshpkt_get_cstring(ssh, &lang, NULL((void*)0))) != 0)
1025 goto out;
1026 r = sshpkt_get_end(ssh);
1027 debug("Server GSSAPI Error:\n%s", msg)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1027, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Server GSSAPI Error:\n%s"
, msg)
;
1028 out:
1029 free(msg);
1030 free(lang);
1031 return r;
1032}
1033#endif /* GSSAPI */
1034
1035static int
1036userauth_none(struct ssh *ssh)
1037{
1038 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1039 int r;
1040
1041 /* initial userauth request */
1042 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1043 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
1044 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
1045 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
1046 (r = sshpkt_send(ssh)) != 0)
1047 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1047, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
1048 return 1;
1049}
1050
1051static int
1052userauth_passwd(struct ssh *ssh)
1053{
1054 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1055 char *password, *prompt = NULL((void*)0);
1056 const char *host = options.host_key_alias ? options.host_key_alias :
1057 authctxt->host;
1058 int r;
1059
1060 if (authctxt->attempt_passwd++ >= options.number_of_password_prompts)
1061 return 0;
1062
1063 if (authctxt->attempt_passwd != 1)
1064 error("Permission denied, please try again.")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1064, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "Permission denied, please try again."
)
;
1065
1066 xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host);
1067 password = read_passphrase(prompt, 0);
1068 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1069 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
1070 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
1071 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
1072 (r = sshpkt_put_u8(ssh, 0)) != 0 ||
1073 (r = sshpkt_put_cstring(ssh, password)) != 0 ||
1074 (r = sshpkt_add_padding(ssh, 64)) != 0 ||
1075 (r = sshpkt_send(ssh)) != 0)
1076 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1076, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
1077
1078 free(prompt);
1079 if (password != NULL((void*)0))
1080 freezero(password, strlen(password));
1081
1082 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ60,
1083 &input_userauth_passwd_changereq);
1084
1085 return 1;
1086}
1087
1088/*
1089 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
1090 */
1091/* ARGSUSED */
1092static int
1093input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
1094{
1095 Authctxt *authctxt = ssh->authctxt;
1096 char *info = NULL((void*)0), *lang = NULL((void*)0), *password = NULL((void*)0), *retype = NULL((void*)0);
1097 char prompt[256];
1098 const char *host;
1099 int r;
1100
1101 debug2("input_userauth_passwd_changereq")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1101, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "input_userauth_passwd_changereq"
)
;
1102
1103 if (authctxt == NULL((void*)0))
1104 fatal("input_userauth_passwd_changereq: "sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1105, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_userauth_passwd_changereq: "
"no authentication context")
1105 "no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1105, 0, SYSLOG_LEVEL_FATAL, ((void*)0), "input_userauth_passwd_changereq: "
"no authentication context")
;
1106 host = options.host_key_alias ? options.host_key_alias : authctxt->host;
1107
1108 if ((r = sshpkt_get_cstring(ssh, &info, NULL((void*)0))) != 0 ||
1109 (r = sshpkt_get_cstring(ssh, &lang, NULL((void*)0))) != 0)
1110 goto out;
1111 if (strlen(info) > 0)
1112 logit("%s", info)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1112, 0, SYSLOG_LEVEL_INFO, ((void*)0), "%s", info)
;
1113 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1114 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
1115 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
1116 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
1117 (r = sshpkt_put_u8(ssh, 1)) != 0) /* additional info */
1118 goto out;
1119
1120 snprintf(prompt, sizeof(prompt),
1121 "Enter %.30s@%.128s's old password: ",
1122 authctxt->server_user, host);
1123 password = read_passphrase(prompt, 0);
1124 if ((r = sshpkt_put_cstring(ssh, password)) != 0)
1125 goto out;
1126
1127 freezero(password, strlen(password));
1128 password = NULL((void*)0);
1129 while (password == NULL((void*)0)) {
1130 snprintf(prompt, sizeof(prompt),
1131 "Enter %.30s@%.128s's new password: ",
1132 authctxt->server_user, host);
1133 password = read_passphrase(prompt, RP_ALLOW_EOF0x0004);
1134 if (password == NULL((void*)0)) {
1135 /* bail out */
1136 r = 0;
1137 goto out;
1138 }
1139 snprintf(prompt, sizeof(prompt),
1140 "Retype %.30s@%.128s's new password: ",
1141 authctxt->server_user, host);
1142 retype = read_passphrase(prompt, 0);
1143 if (strcmp(password, retype) != 0) {
1144 freezero(password, strlen(password));
1145 logit("Mismatch; try again, EOF to quit.")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1145, 0, SYSLOG_LEVEL_INFO, ((void*)0), "Mismatch; try again, EOF to quit."
)
;
1146 password = NULL((void*)0);
1147 }
1148 freezero(retype, strlen(retype));
1149 }
1150 if ((r = sshpkt_put_cstring(ssh, password)) != 0 ||
1151 (r = sshpkt_add_padding(ssh, 64)) != 0 ||
1152 (r = sshpkt_send(ssh)) != 0)
1153 goto out;
1154
1155 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ60,
1156 &input_userauth_passwd_changereq);
1157 r = 0;
1158 out:
1159 if (password)
1160 freezero(password, strlen(password));
1161 free(info);
1162 free(lang);
1163 return r;
1164}
1165
1166/*
1167 * Select an algorithm for publickey signatures.
1168 * Returns algorithm (caller must free) or NULL if no mutual algorithm found.
1169 *
1170 * Call with ssh==NULL to ignore server-sig-algs extension list and
1171 * only attempt with the key's base signature type.
1172 */
1173static char *
1174key_sig_algorithm(struct ssh *ssh, const struct sshkey *key)
1175{
1176 char *allowed, *oallowed, *cp, *tmp, *alg = NULL((void*)0);
1177 const char *server_sig_algs;
1178
1179 /*
1180 * The signature algorithm will only differ from the key algorithm
1181 * for RSA keys/certs and when the server advertises support for
1182 * newer (SHA2) algorithms.
1183 */
1184 if (ssh == NULL((void*)0) || ssh->kex->server_sig_algs == NULL((void*)0) ||
1185 (key->type != KEY_RSA && key->type != KEY_RSA_CERT) ||
1186 (key->type == KEY_RSA_CERT && (ssh->compat & SSH_BUG_SIGTYPE0x00000002))) {
1187 /* Filter base key signature alg against our configuration */
1188 return match_list(sshkey_ssh_name(key),
1189 options.pubkey_accepted_algos, NULL((void*)0));
1190 }
1191
1192 /*
1193 * Workaround OpenSSH 7.4 bug: this version supports RSA/SHA-2 but
1194 * fails to advertise it via SSH2_MSG_EXT_INFO.
1195 */
1196 server_sig_algs = ssh->kex->server_sig_algs;
1197 if (key->type == KEY_RSA && (ssh->compat & SSH_BUG_SIGTYPE740x00000004))
1198 server_sig_algs = "rsa-sha2-256,rsa-sha2-512";
1199
1200 /*
1201 * For RSA keys/certs, since these might have a different sig type:
1202 * find the first entry in PubkeyAcceptedAlgorithms of the right type
1203 * that also appears in the supported signature algorithms list from
1204 * the server.
1205 */
1206 oallowed = allowed = xstrdup(options.pubkey_accepted_algos);
1207 while ((cp = strsep(&allowed, ",")) != NULL((void*)0)) {
1208 if (sshkey_type_from_name(cp) != key->type)
1209 continue;
1210 tmp = match_list(sshkey_sigalg_by_name(cp),
1211 server_sig_algs, NULL((void*)0));
1212 if (tmp != NULL((void*)0))
1213 alg = xstrdup(cp);
1214 free(tmp);
1215 if (alg != NULL((void*)0))
1216 break;
1217 }
1218 free(oallowed);
1219 return alg;
1220}
1221
1222static int
1223identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
1224 const u_char *data, size_t datalen, u_int compat, const char *alg)
1225{
1226 struct sshkey *sign_key = NULL((void*)0), *prv = NULL((void*)0);
1227 int retried = 0, r = SSH_ERR_INTERNAL_ERROR-1;
1228 struct notifier_ctx *notifier = NULL((void*)0);
1229 char *fp = NULL((void*)0), *pin = NULL((void*)0), *prompt = NULL((void*)0);
1230
1231 *sigp = NULL((void*)0);
1232 *lenp = 0;
1233
1234 /* The agent supports this key. */
1235 if (id->key != NULL((void*)0) && id->agent_fd != -1) {
1236 return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
1237 data, datalen, alg, compat);
1238 }
1239
1240 /*
1241 * We have already loaded the private key or the private key is
1242 * stored in external hardware.
1243 */
1244 if (id->key != NULL((void*)0) &&
1245 (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT0x0001))) {
1246 sign_key = id->key;
1247 } else {
1248 /* Load the private key from the file. */
1249 if ((prv = load_identity_file(id)) == NULL((void*)0))
1250 return SSH_ERR_KEY_NOT_FOUND-46;
1251 if (id->key != NULL((void*)0) && !sshkey_equal_public(prv, id->key)) {
1252 error_f("private key %s contents do not match public",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1253, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "private key %s contents do not match public"
, id->filename)
1253 id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1253, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "private key %s contents do not match public"
, id->filename)
;
1254 r = SSH_ERR_KEY_NOT_FOUND-46;
1255 goto out;
1256 }
1257 sign_key = prv;
1258 if (sshkey_is_sk(sign_key)) {
1259 if ((sign_key->sk_flags &
1260 SSH_SK_USER_VERIFICATION_REQD0x04)) {
1261 retry_pin:
1262 xasprintf(&prompt, "Enter PIN for %s key %s: ",
1263 sshkey_type(sign_key), id->filename);
1264 pin = read_passphrase(prompt, 0);
1265 }
1266 if ((sign_key->sk_flags & SSH_SK_USER_PRESENCE_REQD0x01)) {
1267 /* XXX should batch mode just skip these? */
1268 if ((fp = sshkey_fingerprint(sign_key,
1269 options.fingerprint_hash,
1270 SSH_FP_DEFAULT)) == NULL((void*)0))
1271 fatal_f("fingerprint failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1271, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "fingerprint failed"
)
;
1272 notifier = notify_start(options.batch_mode,
1273 "Confirm user presence for key %s %s",
1274 sshkey_type(sign_key), fp);
1275 free(fp);
1276 }
1277 }
1278 }
1279 if ((r = sshkey_sign(sign_key, sigp, lenp, data, datalen,
1280 alg, options.sk_provider, pin, compat)) != 0) {
1281 debug_fr(r, "sshkey_sign")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1281, 1, SYSLOG_LEVEL_DEBUG1, ssh_err(r), "sshkey_sign")
;
1282 if (pin == NULL((void*)0) && !retried && sshkey_is_sk(sign_key) &&
1283 r == SSH_ERR_KEY_WRONG_PASSPHRASE-43) {
1284 notify_complete(notifier, NULL((void*)0));
1285 notifier = NULL((void*)0);
1286 retried = 1;
1287 goto retry_pin;
1288 }
1289 goto out;
1290 }
1291
1292 /*
1293 * PKCS#11 tokens may not support all signature algorithms,
1294 * so check what we get back.
1295 */
1296 if ((r = sshkey_check_sigtype(*sigp, *lenp, alg)) != 0) {
1297 debug_fr(r, "sshkey_check_sigtype")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1297, 1, SYSLOG_LEVEL_DEBUG1, ssh_err(r), "sshkey_check_sigtype"
)
;
1298 goto out;
1299 }
1300 /* success */
1301 r = 0;
1302 out:
1303 free(prompt);
1304 if (pin != NULL((void*)0))
1305 freezero(pin, strlen(pin));
1306 notify_complete(notifier, r == 0 ? "User presence confirmed" : NULL((void*)0));
1307 sshkey_free(prv);
1308 return r;
1309}
1310
1311static int
1312id_filename_matches(Identity *id, Identity *private_id)
1313{
1314 const char *suffixes[] = { ".pub", "-cert.pub", NULL((void*)0) };
1315 size_t len = strlen(id->filename), plen = strlen(private_id->filename);
1316 size_t i, slen;
1317
1318 if (strcmp(id->filename, private_id->filename) == 0)
1319 return 1;
1320 for (i = 0; suffixes[i]; i++) {
1321 slen = strlen(suffixes[i]);
1322 if (len > slen && plen == len - slen &&
1323 strcmp(id->filename + (len - slen), suffixes[i]) == 0 &&
1324 memcmp(id->filename, private_id->filename, plen) == 0)
1325 return 1;
1326 }
1327 return 0;
1328}
1329
1330static int
1331sign_and_send_pubkey(struct ssh *ssh, Identity *id)
1332{
1333 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1334 struct sshbuf *b = NULL((void*)0);
1335 Identity *private_id, *sign_id = NULL((void*)0);
1336 u_char *signature = NULL((void*)0);
1337 size_t slen = 0, skip = 0;
1338 int r, fallback_sigtype, sent = 0;
1339 char *alg = NULL((void*)0), *fp = NULL((void*)0);
1340 const char *loc = "", *method = "publickey";
1341 int hostbound = 0;
1342
1343 /* prefer host-bound pubkey signatures if supported by server */
1344 if ((ssh->kex->flags & KEX_HAS_PUBKEY_HOSTBOUND0x0004) != 0 &&
1345 (options.pubkey_authentication & SSH_PUBKEY_AUTH_HBOUND0x02) != 0) {
1346 hostbound = 1;
1347 method = "publickey-hostbound-v00@openssh.com";
1348 }
1349
1350 if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash,
1351 SSH_FP_DEFAULT)) == NULL((void*)0))
1352 return 0;
1353
1354 debug3_f("using %s with %s %s", method, sshkey_type(id->key), fp)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1354, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "using %s with %s %s"
, method, sshkey_type(id->key), fp)
;
1355
1356 /*
1357 * If the key is an certificate, try to find a matching private key
1358 * and use it to complete the signature.
1359 * If no such private key exists, fall back to trying the certificate
1360 * key itself in case it has a private half already loaded.
1361 * This will try to set sign_id to the private key that will perform
1362 * the signature.
1363 */
1364 if (sshkey_is_cert(id->key)) {
1365 TAILQ_FOREACH(private_id, &authctxt->keys, next)for((private_id) = ((&authctxt->keys)->tqh_first); (
private_id) != ((void*)0); (private_id) = ((private_id)->next
.tqe_next))
{
1366 if (sshkey_equal_public(id->key, private_id->key) &&
1367 id->key->type != private_id->key->type) {
1368 sign_id = private_id;
1369 break;
1370 }
1371 }
1372 /*
1373 * Exact key matches are preferred, but also allow
1374 * filename matches for non-PKCS#11/agent keys that
1375 * didn't load public keys. This supports the case
1376 * of keeping just a private key file and public
1377 * certificate on disk.
1378 */
1379 if (sign_id == NULL((void*)0) &&
1380 !id->isprivate && id->agent_fd == -1 &&
1381 (id->key->flags & SSHKEY_FLAG_EXT0x0001) == 0) {
1382 TAILQ_FOREACH(private_id, &authctxt->keys, next)for((private_id) = ((&authctxt->keys)->tqh_first); (
private_id) != ((void*)0); (private_id) = ((private_id)->next
.tqe_next))
{
1383 if (private_id->key == NULL((void*)0) &&
1384 id_filename_matches(id, private_id)) {
1385 sign_id = private_id;
1386 break;
1387 }
1388 }
1389 }
1390 if (sign_id != NULL((void*)0)) {
1391 debug2_f("using private key \"%s\"%s for "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1393, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "using private key \"%s\"%s for "
"certificate", sign_id->filename, sign_id->agent_fd !=
-1 ? " from agent" : "")
1392 "certificate", sign_id->filename,sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1393, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "using private key \"%s\"%s for "
"certificate", sign_id->filename, sign_id->agent_fd !=
-1 ? " from agent" : "")
1393 sign_id->agent_fd != -1 ? " from agent" : "")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1393, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "using private key \"%s\"%s for "
"certificate", sign_id->filename, sign_id->agent_fd !=
-1 ? " from agent" : "")
;
1394 } else {
1395 debug_f("no separate private key for certificate "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1396, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "no separate private key for certificate "
"\"%s\"", id->filename)
1396 "\"%s\"", id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1396, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "no separate private key for certificate "
"\"%s\"", id->filename)
;
1397 }
1398 }
1399
1400 /*
1401 * If the above didn't select another identity to do the signing
1402 * then default to the one we started with.
1403 */
1404 if (sign_id == NULL((void*)0))
1405 sign_id = id;
1406
1407 /* assemble and sign data */
1408 for (fallback_sigtype = 0; fallback_sigtype <= 1; fallback_sigtype++) {
1409 free(alg);
1410 slen = 0;
1411 signature = NULL((void*)0);
1412 if ((alg = key_sig_algorithm(fallback_sigtype ? NULL((void*)0) : ssh,
1413 id->key)) == NULL((void*)0)) {
1414 error_f("no mutual signature supported")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1414, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "no mutual signature supported"
)
;
1415 goto out;
1416 }
1417 debug3_f("signing using %s %s", alg, fp)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1417, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "signing using %s %s"
, alg, fp)
;
1418
1419 sshbuf_free(b);
1420 if ((b = sshbuf_new()) == NULL((void*)0))
1421 fatal_f("sshbuf_new failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1421, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_new failed"
)
;
1422 if (ssh->compat & SSH_OLD_SESSIONID0x00000010) {
1423 if ((r = sshbuf_putb(b, ssh->kex->session_id)) != 0)
1424 fatal_fr(r, "sshbuf_putb")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1424, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "sshbuf_putb")
;
1425 } else {
1426 if ((r = sshbuf_put_stringb(b,
1427 ssh->kex->session_id)) != 0)
1428 fatal_fr(r, "sshbuf_put_stringb")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1428, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "sshbuf_put_stringb"
)
;
1429 }
1430 skip = sshbuf_len(b);
1431 if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1432 (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
1433 (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
1434 (r = sshbuf_put_cstring(b, method)) != 0 ||
1435 (r = sshbuf_put_u8(b, 1)) != 0 ||
1436 (r = sshbuf_put_cstring(b, alg)) != 0 ||
1437 (r = sshkey_puts(id->key, b)) != 0) {
1438 fatal_fr(r, "assemble signed data")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1438, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "assemble signed data"
)
;
1439 }
1440 if (hostbound) {
1441 if (ssh->kex->initial_hostkey == NULL((void*)0)) {
1442 fatal_f("internal error: initial hostkey "sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1443, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "internal error: initial hostkey "
"not recorded")
1443 "not recorded")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1443, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "internal error: initial hostkey "
"not recorded")
;
1444 }
1445 if ((r = sshkey_puts(ssh->kex->initial_hostkey, b)) != 0)
1446 fatal_fr(r, "assemble %s hostkey", method)sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1446, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "assemble %s hostkey"
, method)
;
1447 }
1448 /* generate signature */
1449 r = identity_sign(sign_id, &signature, &slen,
1450 sshbuf_ptr(b), sshbuf_len(b), ssh->compat, alg);
1451 if (r == 0)
1452 break;
1453 else if (r == SSH_ERR_KEY_NOT_FOUND-46)
1454 goto out; /* soft failure */
1455 else if (r == SSH_ERR_SIGN_ALG_UNSUPPORTED-58 &&
1456 !fallback_sigtype) {
1457 if (sign_id->agent_fd != -1)
1458 loc = "agent ";
1459 else if ((sign_id->key->flags & SSHKEY_FLAG_EXT0x0001) != 0)
1460 loc = "token ";
1461 logit("%skey %s %s returned incorrect signature type",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1462, 0, SYSLOG_LEVEL_INFO, ((void*)0), "%skey %s %s returned incorrect signature type"
, loc, sshkey_type(id->key), fp)
1462 loc, sshkey_type(id->key), fp)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1462, 0, SYSLOG_LEVEL_INFO, ((void*)0), "%skey %s %s returned incorrect signature type"
, loc, sshkey_type(id->key), fp)
;
1463 continue;
1464 }
1465 error_fr(r, "signing failed for %s \"%s\"%s",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1467, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "signing failed for %s \"%s\"%s"
, sshkey_type(sign_id->key), sign_id->filename, id->
agent_fd != -1 ? " from agent" : "")
1466 sshkey_type(sign_id->key), sign_id->filename,sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1467, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "signing failed for %s \"%s\"%s"
, sshkey_type(sign_id->key), sign_id->filename, id->
agent_fd != -1 ? " from agent" : "")
1467 id->agent_fd != -1 ? " from agent" : "")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1467, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "signing failed for %s \"%s\"%s"
, sshkey_type(sign_id->key), sign_id->filename, id->
agent_fd != -1 ? " from agent" : "")
;
1468 goto out;
1469 }
1470 if (slen == 0 || signature == NULL((void*)0)) /* shouldn't happen */
1471 fatal_f("no signature")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1471, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "no signature")
;
1472
1473 /* append signature */
1474 if ((r = sshbuf_put_string(b, signature, slen)) != 0)
1475 fatal_fr(r, "append signature")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1475, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "append signature"
)
;
1476
1477#ifdef DEBUG_PK
1478 sshbuf_dump(b, stderr(&__sF[2]));
1479#endif
1480 /* skip session id and packet type */
1481 if ((r = sshbuf_consume(b, skip + 1)) != 0)
1482 fatal_fr(r, "consume")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1482, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "consume")
;
1483
1484 /* put remaining data from buffer into packet */
1485 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1486 (r = sshpkt_putb(ssh, b)) != 0 ||
1487 (r = sshpkt_send(ssh)) != 0)
1488 fatal_fr(r, "enqueue request")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1488, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "enqueue request")
;
1489
1490 /* success */
1491 sent = 1;
1492
1493 out:
1494 free(fp);
1495 free(alg);
1496 sshbuf_free(b);
1497 freezero(signature, slen);
1498 return sent;
1499}
1500
1501static int
1502send_pubkey_test(struct ssh *ssh, Identity *id)
1503{
1504 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1505 u_char *blob = NULL((void*)0);
1506 char *alg = NULL((void*)0);
1507 size_t bloblen;
1508 u_int have_sig = 0;
1509 int sent = 0, r;
1510
1511 if ((alg = key_sig_algorithm(ssh, id->key)) == NULL((void*)0)) {
1512 debug_f("no mutual signature algorithm")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1512, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "no mutual signature algorithm"
)
;
1513 goto out;
1514 }
1515
1516 if ((r = sshkey_to_blob(id->key, &blob, &bloblen)) != 0) {
1517 /* we cannot handle this key */
1518 debug3_f("cannot handle key")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1518, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "cannot handle key"
)
;
1519 goto out;
1520 }
1521 /* register callback for USERAUTH_PK_OK message */
1522 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PK_OK60, &input_userauth_pk_ok);
1523
1524 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1525 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
1526 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
1527 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
1528 (r = sshpkt_put_u8(ssh, have_sig)) != 0 ||
1529 (r = sshpkt_put_cstring(ssh, alg)) != 0 ||
1530 (r = sshpkt_put_string(ssh, blob, bloblen)) != 0 ||
1531 (r = sshpkt_send(ssh)) != 0)
1532 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1532, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
1533 sent = 1;
1534
1535 out:
1536 free(alg);
1537 free(blob);
1538 return sent;
1539}
1540
1541static struct sshkey *
1542load_identity_file(Identity *id)
1543{
1544 struct sshkey *private = NULL((void*)0);
1545 char prompt[300], *passphrase, *comment;
1546 int r, quit = 0, i;
1547 struct stat st;
1548
1549 if (stat(id->filename, &st) == -1) {
1550 do_log2(id->userprovided ?sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1552, 0, id->userprovided ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_DEBUG3
, ((void*)0), "no such identity: %s: %s", id->filename, strerror
((*__errno())))
1551 SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_DEBUG3,sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1552, 0, id->userprovided ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_DEBUG3
, ((void*)0), "no such identity: %s: %s", id->filename, strerror
((*__errno())))
1552 "no such identity: %s: %s", id->filename, strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1552, 0, id->userprovided ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_DEBUG3
, ((void*)0), "no such identity: %s: %s", id->filename, strerror
((*__errno())))
;
1553 return NULL((void*)0);
1554 }
1555 snprintf(prompt, sizeof prompt,
1556 "Enter passphrase for key '%.100s': ", id->filename);
1557 for (i = 0; i <= options.number_of_password_prompts; i++) {
1558 if (i == 0)
1559 passphrase = "";
1560 else {
1561 passphrase = read_passphrase(prompt, 0);
1562 if (*passphrase == '\0') {
1563 debug2("no passphrase given, try next key")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1563, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "no passphrase given, try next key"
)
;
1564 free(passphrase);
1565 break;
1566 }
1567 }
1568 switch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename,
1569 passphrase, &private, &comment))) {
1570 case 0:
1571 break;
1572 case SSH_ERR_KEY_WRONG_PASSPHRASE-43:
1573 if (options.batch_mode) {
1574 quit = 1;
1575 break;
1576 }
1577 if (i != 0)
1578 debug2("bad passphrase given, try again...")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1578, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "bad passphrase given, try again..."
)
;
1579 break;
1580 case SSH_ERR_SYSTEM_ERROR-24:
1581 if (errno(*__errno()) == ENOENT2) {
1582 debug2_r(r, "Load key \"%s\"", id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1582, 0, SYSLOG_LEVEL_DEBUG2, ssh_err(r), "Load key \"%s\"",
id->filename)
;
1583 quit = 1;
1584 break;
1585 }
1586 /* FALLTHROUGH */
1587 default:
1588 error_r(r, "Load key \"%s\"", id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1588, 0, SYSLOG_LEVEL_ERROR, ssh_err(r), "Load key \"%s\"", id
->filename)
;
1589 quit = 1;
1590 break;
1591 }
1592 if (private != NULL((void*)0) && sshkey_is_sk(private) &&
1593 options.sk_provider == NULL((void*)0)) {
1594 debug("key \"%s\" is an authenticator-hosted key, "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1595, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "key \"%s\" is an authenticator-hosted key, "
"but no provider specified", id->filename)
1595 "but no provider specified", id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1595, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "key \"%s\" is an authenticator-hosted key, "
"but no provider specified", id->filename)
;
1596 sshkey_free(private);
1597 private = NULL((void*)0);
1598 quit = 1;
1599 }
1600 if (!quit && private != NULL((void*)0) && id->agent_fd == -1 &&
1601 !(id->key && id->isprivate))
1602 maybe_add_key_to_agent(id->filename, private, comment,
1603 passphrase);
1604 if (i > 0)
1605 freezero(passphrase, strlen(passphrase));
1606 free(comment);
1607 if (private != NULL((void*)0) || quit)
1608 break;
1609 }
1610 return private;
1611}
1612
1613static int
1614key_type_allowed_by_config(struct sshkey *key)
1615{
1616 if (match_pattern_list(sshkey_ssh_name(key),
1617 options.pubkey_accepted_algos, 0) == 1)
1618 return 1;
1619
1620 /* RSA keys/certs might be allowed by alternate signature types */
1621 switch (key->type) {
1622 case KEY_RSA:
1623 if (match_pattern_list("rsa-sha2-512",
1624 options.pubkey_accepted_algos, 0) == 1)
1625 return 1;
1626 if (match_pattern_list("rsa-sha2-256",
1627 options.pubkey_accepted_algos, 0) == 1)
1628 return 1;
1629 break;
1630 case KEY_RSA_CERT:
1631 if (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com",
1632 options.pubkey_accepted_algos, 0) == 1)
1633 return 1;
1634 if (match_pattern_list("rsa-sha2-256-cert-v01@openssh.com",
1635 options.pubkey_accepted_algos, 0) == 1)
1636 return 1;
1637 break;
1638 }
1639 return 0;
1640}
1641
1642/* obtain a list of keys from the agent */
1643static int
1644get_agent_identities(struct ssh *ssh, int *agent_fdp,
1645 struct ssh_identitylist **idlistp)
1646{
1647 int r, agent_fd;
1648 struct ssh_identitylist *idlist;
1649
1650 if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
1651 if (r != SSH_ERR_AGENT_NOT_PRESENT-47)
1652 debug_fr(r, "ssh_get_authentication_socket")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1652, 1, SYSLOG_LEVEL_DEBUG1, ssh_err(r), "ssh_get_authentication_socket"
)
;
1653 return r;
1654 }
1655 if ((r = ssh_agent_bind_hostkey(agent_fd, ssh->kex->initial_hostkey,
1656 ssh->kex->session_id, ssh->kex->initial_sig, 0)) == 0)
1657 debug_f("bound agent to hostkey")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1657, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "bound agent to hostkey"
)
;
1658 else
1659 debug2_fr(r, "ssh_agent_bind_hostkey")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1659, 1, SYSLOG_LEVEL_DEBUG2, ssh_err(r), "ssh_agent_bind_hostkey"
)
;
1660
1661 if ((r = ssh_fetch_identitylist(agent_fd, &idlist)) != 0) {
1662 debug_fr(r, "ssh_fetch_identitylist")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1662, 1, SYSLOG_LEVEL_DEBUG1, ssh_err(r), "ssh_fetch_identitylist"
)
;
1663 close(agent_fd);
1664 return r;
1665 }
1666 /* success */
1667 *agent_fdp = agent_fd;
1668 *idlistp = idlist;
1669 debug_f("agent returned %zu keys", idlist->nkeys)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1669, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "agent returned %zu keys"
, idlist->nkeys)
;
1670 return 0;
1671}
1672
1673/*
1674 * try keys in the following order:
1675 * 1. certificates listed in the config file
1676 * 2. other input certificates
1677 * 3. agent keys that are found in the config file
1678 * 4. other agent keys
1679 * 5. keys that are only listed in the config file
1680 */
1681static void
1682pubkey_prepare(struct ssh *ssh, Authctxt *authctxt)
1683{
1684 struct identity *id, *id2, *tmp;
1685 struct idlist agent, files, *preferred;
1686 struct sshkey *key;
1687 int agent_fd = -1, i, r, found;
1688 size_t j;
1689 struct ssh_identitylist *idlist;
1690 char *ident;
1691
1692 TAILQ_INIT(&agent)do { (&agent)->tqh_first = ((void*)0); (&agent)->
tqh_last = &(&agent)->tqh_first; } while (0)
; /* keys from the agent */
1693 TAILQ_INIT(&files)do { (&files)->tqh_first = ((void*)0); (&files)->
tqh_last = &(&files)->tqh_first; } while (0)
; /* keys from the config file */
1694 preferred = &authctxt->keys;
1695 TAILQ_INIT(preferred)do { (preferred)->tqh_first = ((void*)0); (preferred)->
tqh_last = &(preferred)->tqh_first; } while (0)
; /* preferred order of keys */
1696
1697 /* list of keys stored in the filesystem and PKCS#11 */
1698 for (i = 0; i < options.num_identity_files; i++) {
1699 key = options.identity_keys[i];
1700 if (key && key->cert &&
1701 key->cert->type != SSH2_CERT_TYPE_USER1) {
1702 debug_f("ignoring certificate %s: not a user "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1703, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring certificate %s: not a user "
"certificate", options.identity_files[i])
1703 "certificate", options.identity_files[i])sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1703, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring certificate %s: not a user "
"certificate", options.identity_files[i])
;
1704 continue;
1705 }
1706 if (key && sshkey_is_sk(key) && options.sk_provider == NULL((void*)0)) {
1707 debug_f("ignoring authenticator-hosted key %s as no "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1709, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key %s as no "
"SecurityKeyProvider has been specified", options.identity_files
[i])
1708 "SecurityKeyProvider has been specified",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1709, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key %s as no "
"SecurityKeyProvider has been specified", options.identity_files
[i])
1709 options.identity_files[i])sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1709, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key %s as no "
"SecurityKeyProvider has been specified", options.identity_files
[i])
;
1710 continue;
1711 }
1712 options.identity_keys[i] = NULL((void*)0);
1713 id = xcalloc(1, sizeof(*id));
1714 id->agent_fd = -1;
1715 id->key = key;
1716 id->filename = xstrdup(options.identity_files[i]);
1717 id->userprovided = options.identity_file_userprovided[i];
1718 TAILQ_INSERT_TAIL(&files, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (&files)->tqh_last; *(&files)->tqh_last = (id
); (&files)->tqh_last = &(id)->next.tqe_next; }
while (0)
;
1719 }
1720 /* list of certificates specified by user */
1721 for (i = 0; i < options.num_certificate_files; i++) {
1722 key = options.certificates[i];
1723 if (!sshkey_is_cert(key) || key->cert == NULL((void*)0) ||
1724 key->cert->type != SSH2_CERT_TYPE_USER1) {
1725 debug_f("ignoring certificate %s: not a user "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1726, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring certificate %s: not a user "
"certificate", options.identity_files[i])
1726 "certificate", options.identity_files[i])sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1726, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring certificate %s: not a user "
"certificate", options.identity_files[i])
;
1727 continue;
1728 }
1729 if (key && sshkey_is_sk(key) && options.sk_provider == NULL((void*)0)) {
1730 debug_f("ignoring authenticator-hosted key "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1733, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key "
"certificate %s as no " "SecurityKeyProvider has been specified"
, options.identity_files[i])
1731 "certificate %s as no "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1733, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key "
"certificate %s as no " "SecurityKeyProvider has been specified"
, options.identity_files[i])
1732 "SecurityKeyProvider has been specified",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1733, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key "
"certificate %s as no " "SecurityKeyProvider has been specified"
, options.identity_files[i])
1733 options.identity_files[i])sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1733, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "ignoring authenticator-hosted key "
"certificate %s as no " "SecurityKeyProvider has been specified"
, options.identity_files[i])
;
1734 continue;
1735 }
1736 id = xcalloc(1, sizeof(*id));
1737 id->agent_fd = -1;
1738 id->key = key;
1739 id->filename = xstrdup(options.certificate_files[i]);
1740 id->userprovided = options.certificate_file_userprovided[i];
1741 TAILQ_INSERT_TAIL(preferred, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (preferred)->tqh_last; *(preferred)->tqh_last = (id)
; (preferred)->tqh_last = &(id)->next.tqe_next; } while
(0)
;
1742 }
1743 /* list of keys supported by the agent */
1744 if ((r = get_agent_identities(ssh, &agent_fd, &idlist)) == 0) {
1745 for (j = 0; j < idlist->nkeys; j++) {
1746 found = 0;
1747 TAILQ_FOREACH(id, &files, next)for((id) = ((&files)->tqh_first); (id) != ((void*)0); (
id) = ((id)->next.tqe_next))
{
1748 /*
1749 * agent keys from the config file are
1750 * preferred
1751 */
1752 if (sshkey_equal(idlist->keys[j], id->key)) {
1753 TAILQ_REMOVE(&files, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (&
files)->tqh_last = (id)->next.tqe_prev; *(id)->next.
tqe_prev = (id)->next.tqe_next; ; ; } while (0)
;
1754 TAILQ_INSERT_TAIL(preferred, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (preferred)->tqh_last; *(preferred)->tqh_last = (id)
; (preferred)->tqh_last = &(id)->next.tqe_next; } while
(0)
;
1755 id->agent_fd = agent_fd;
1756 found = 1;
1757 break;
1758 }
1759 }
1760 if (!found && !options.identities_only) {
1761 id = xcalloc(1, sizeof(*id));
1762 /* XXX "steals" key/comment from idlist */
1763 id->key = idlist->keys[j];
1764 id->filename = idlist->comments[j];
1765 idlist->keys[j] = NULL((void*)0);
1766 idlist->comments[j] = NULL((void*)0);
1767 id->agent_fd = agent_fd;
1768 TAILQ_INSERT_TAIL(&agent, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (&agent)->tqh_last; *(&agent)->tqh_last = (id
); (&agent)->tqh_last = &(id)->next.tqe_next; }
while (0)
;
1769 }
1770 }
1771 ssh_free_identitylist(idlist);
1772 /* append remaining agent keys */
1773 TAILQ_CONCAT(preferred, &agent, next)do { if (!(((&agent)->tqh_first) == ((void*)0))) { *(preferred
)->tqh_last = (&agent)->tqh_first; (&agent)->
tqh_first->next.tqe_prev = (preferred)->tqh_last; (preferred
)->tqh_last = (&agent)->tqh_last; do { ((&agent
))->tqh_first = ((void*)0); ((&agent))->tqh_last = &
((&agent))->tqh_first; } while (0); } } while (0)
;
1774 authctxt->agent_fd = agent_fd;
1775 }
1776 /* Prefer PKCS11 keys that are explicitly listed */
1777 TAILQ_FOREACH_SAFE(id, &files, next, tmp)for ((id) = ((&files)->tqh_first); (id) != ((void*)0) &&
((tmp) = ((id)->next.tqe_next), 1); (id) = (tmp))
{
1778 if (id->key == NULL((void*)0) || (id->key->flags & SSHKEY_FLAG_EXT0x0001) == 0)
1779 continue;
1780 found = 0;
1781 TAILQ_FOREACH(id2, &files, next)for((id2) = ((&files)->tqh_first); (id2) != ((void*)0)
; (id2) = ((id2)->next.tqe_next))
{
1782 if (id2->key == NULL((void*)0) ||
1783 (id2->key->flags & SSHKEY_FLAG_EXT0x0001) != 0)
1784 continue;
1785 if (sshkey_equal(id->key, id2->key)) {
1786 TAILQ_REMOVE(&files, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (&
files)->tqh_last = (id)->next.tqe_prev; *(id)->next.
tqe_prev = (id)->next.tqe_next; ; ; } while (0)
;
1787 TAILQ_INSERT_TAIL(preferred, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (preferred)->tqh_last; *(preferred)->tqh_last = (id)
; (preferred)->tqh_last = &(id)->next.tqe_next; } while
(0)
;
1788 found = 1;
1789 break;
1790 }
1791 }
1792 /* If IdentitiesOnly set and key not found then don't use it */
1793 if (!found && options.identities_only) {
1794 TAILQ_REMOVE(&files, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (&
files)->tqh_last = (id)->next.tqe_prev; *(id)->next.
tqe_prev = (id)->next.tqe_next; ; ; } while (0)
;
1795 freezero(id, sizeof(*id));
1796 }
1797 }
1798 /* append remaining keys from the config file */
1799 TAILQ_CONCAT(preferred, &files, next)do { if (!(((&files)->tqh_first) == ((void*)0))) { *(preferred
)->tqh_last = (&files)->tqh_first; (&files)->
tqh_first->next.tqe_prev = (preferred)->tqh_last; (preferred
)->tqh_last = (&files)->tqh_last; do { ((&files
))->tqh_first = ((void*)0); ((&files))->tqh_last = &
((&files))->tqh_first; } while (0); } } while (0)
;
1800 /* finally, filter by PubkeyAcceptedAlgorithms */
1801 TAILQ_FOREACH_SAFE(id, preferred, next, id2)for ((id) = ((preferred)->tqh_first); (id) != ((void*)0) &&
((id2) = ((id)->next.tqe_next), 1); (id) = (id2))
{
1802 if (id->key != NULL((void*)0) && !key_type_allowed_by_config(id->key)) {
1803 debug("Skipping %s key %s - "sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1805, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Skipping %s key %s - "
"corresponding algo not in PubkeyAcceptedAlgorithms", sshkey_ssh_name
(id->key), id->filename)
1804 "corresponding algo not in PubkeyAcceptedAlgorithms",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1805, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Skipping %s key %s - "
"corresponding algo not in PubkeyAcceptedAlgorithms", sshkey_ssh_name
(id->key), id->filename)
1805 sshkey_ssh_name(id->key), id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1805, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Skipping %s key %s - "
"corresponding algo not in PubkeyAcceptedAlgorithms", sshkey_ssh_name
(id->key), id->filename)
;
1806 TAILQ_REMOVE(preferred, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (preferred
)->tqh_last = (id)->next.tqe_prev; *(id)->next.tqe_prev
= (id)->next.tqe_next; ; ; } while (0)
;
1807 sshkey_free(id->key);
1808 free(id->filename);
1809 memset(id, 0, sizeof(*id));
1810 continue;
1811 }
1812 }
1813 /* List the keys we plan on using */
1814 TAILQ_FOREACH_SAFE(id, preferred, next, id2)for ((id) = ((preferred)->tqh_first); (id) != ((void*)0) &&
((id2) = ((id)->next.tqe_next), 1); (id) = (id2))
{
1815 ident = format_identity(id);
1816 debug("Will attempt key: %s", ident)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1816, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Will attempt key: %s"
, ident)
;
1817 free(ident);
1818 }
1819 debug2_f("done")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1819, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "done")
;
1820}
1821
1822static void
1823pubkey_cleanup(struct ssh *ssh)
1824{
1825 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1826 Identity *id;
1827
1828 if (authctxt->agent_fd != -1) {
1829 ssh_close_authentication_socket(authctxt->agent_fd);
1830 authctxt->agent_fd = -1;
1831 }
1832 for (id = TAILQ_FIRST(&authctxt->keys)((&authctxt->keys)->tqh_first); id;
1833 id = TAILQ_FIRST(&authctxt->keys)((&authctxt->keys)->tqh_first)) {
1834 TAILQ_REMOVE(&authctxt->keys, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (&
authctxt->keys)->tqh_last = (id)->next.tqe_prev; *(id
)->next.tqe_prev = (id)->next.tqe_next; ; ; } while (0)
;
1835 sshkey_free(id->key);
1836 free(id->filename);
1837 free(id);
1838 }
1839}
1840
1841static void
1842pubkey_reset(Authctxt *authctxt)
1843{
1844 Identity *id;
1845
1846 TAILQ_FOREACH(id, &authctxt->keys, next)for((id) = ((&authctxt->keys)->tqh_first); (id) != (
(void*)0); (id) = ((id)->next.tqe_next))
1847 id->tried = 0;
1848}
1849
1850static int
1851try_identity(struct ssh *ssh, Identity *id)
1852{
1853 if (!id->key)
1854 return (0);
1855 if (sshkey_type_plain(id->key->type) == KEY_RSA &&
1856 (ssh->compat & SSH_BUG_RSASIGMD50x00002000) != 0) {
1857 debug("Skipped %s key %s for RSA/MD5 server",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1858, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Skipped %s key %s for RSA/MD5 server"
, sshkey_type(id->key), id->filename)
1858 sshkey_type(id->key), id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1858, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Skipped %s key %s for RSA/MD5 server"
, sshkey_type(id->key), id->filename)
;
1859 return (0);
1860 }
1861 return 1;
1862}
1863
1864static int
1865userauth_pubkey(struct ssh *ssh)
1866{
1867 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1868 Identity *id;
1869 int sent = 0;
1870 char *ident;
1871
1872 while ((id = TAILQ_FIRST(&authctxt->keys)((&authctxt->keys)->tqh_first))) {
1873 if (id->tried++)
1874 return (0);
1875 /* move key to the end of the queue */
1876 TAILQ_REMOVE(&authctxt->keys, id, next)do { if (((id)->next.tqe_next) != ((void*)0)) (id)->next
.tqe_next->next.tqe_prev = (id)->next.tqe_prev; else (&
authctxt->keys)->tqh_last = (id)->next.tqe_prev; *(id
)->next.tqe_prev = (id)->next.tqe_next; ; ; } while (0)
;
1877 TAILQ_INSERT_TAIL(&authctxt->keys, id, next)do { (id)->next.tqe_next = ((void*)0); (id)->next.tqe_prev
= (&authctxt->keys)->tqh_last; *(&authctxt->
keys)->tqh_last = (id); (&authctxt->keys)->tqh_last
= &(id)->next.tqe_next; } while (0)
;
1878 /*
1879 * send a test message if we have the public key. for
1880 * encrypted keys we cannot do this and have to load the
1881 * private key instead
1882 */
1883 if (id->key != NULL((void*)0)) {
1884 if (try_identity(ssh, id)) {
1885 ident = format_identity(id);
1886 debug("Offering public key: %s", ident)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1886, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Offering public key: %s"
, ident)
;
1887 free(ident);
1888 sent = send_pubkey_test(ssh, id);
1889 }
1890 } else {
1891 debug("Trying private key: %s", id->filename)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1891, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Trying private key: %s"
, id->filename)
;
1892 id->key = load_identity_file(id);
1893 if (id->key != NULL((void*)0)) {
1894 if (try_identity(ssh, id)) {
1895 id->isprivate = 1;
1896 sent = sign_and_send_pubkey(ssh, id);
1897 }
1898 sshkey_free(id->key);
1899 id->key = NULL((void*)0);
1900 id->isprivate = 0;
1901 }
1902 }
1903 if (sent)
1904 return (sent);
1905 }
1906 return (0);
1907}
1908
1909/*
1910 * Send userauth request message specifying keyboard-interactive method.
1911 */
1912static int
1913userauth_kbdint(struct ssh *ssh)
1914{
1915 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
1916 int r;
1917
1918 if (authctxt->attempt_kbdint++ >= options.number_of_password_prompts)
1919 return 0;
1920 /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
1921 if (authctxt->attempt_kbdint > 1 && !authctxt->info_req_seen) {
1922 debug3("userauth_kbdint: disable: no info_req_seen")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1922, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "userauth_kbdint: disable: no info_req_seen"
)
;
1923 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST60, NULL((void*)0));
1924 return 0;
1925 }
1926
1927 debug2("userauth_kbdint")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1927, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "userauth_kbdint")
;
1928 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
1929 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
1930 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
1931 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
1932 (r = sshpkt_put_cstring(ssh, "")) != 0 || /* lang */
1933 (r = sshpkt_put_cstring(ssh, options.kbd_interactive_devices ?
1934 options.kbd_interactive_devices : "")) != 0 ||
1935 (r = sshpkt_send(ssh)) != 0)
1936 fatal_fr(r, "send packet")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1936, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "send packet")
;
1937
1938 ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST60, &input_userauth_info_req);
1939 return 1;
1940}
1941
1942/*
1943 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1944 */
1945static int
1946input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
1947{
1948 Authctxt *authctxt = ssh->authctxt;
1949 char *name = NULL((void*)0), *inst = NULL((void*)0), *lang = NULL((void*)0), *prompt = NULL((void*)0);
1950 char *display_prompt = NULL((void*)0), *response = NULL((void*)0);
1951 u_char echo = 0;
1952 u_int num_prompts, i;
1953 int r;
1954
1955 debug2_f("entering")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1955, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "entering")
;
1956
1957 if (authctxt == NULL((void*)0))
1958 fatal_f("no authentication context")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1958, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "no authentication context"
)
;
1959
1960 authctxt->info_req_seen = 1;
1961
1962 if ((r = sshpkt_get_cstring(ssh, &name, NULL((void*)0))) != 0 ||
1963 (r = sshpkt_get_cstring(ssh, &inst, NULL((void*)0))) != 0 ||
1964 (r = sshpkt_get_cstring(ssh, &lang, NULL((void*)0))) != 0)
1965 goto out;
1966 if (strlen(name) > 0)
1967 logit("%s", name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1967, 0, SYSLOG_LEVEL_INFO, ((void*)0), "%s", name)
;
1968 if (strlen(inst) > 0)
1969 logit("%s", inst)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1969, 0, SYSLOG_LEVEL_INFO, ((void*)0), "%s", inst)
;
1970
1971 if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0)
1972 goto out;
1973 /*
1974 * Begin to build info response packet based on prompts requested.
1975 * We commit to providing the correct number of responses, so if
1976 * further on we run into a problem that prevents this, we have to
1977 * be sure and clean this up and send a correct error response.
1978 */
1979 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE61)) != 0 ||
1980 (r = sshpkt_put_u32(ssh, num_prompts)) != 0)
1981 goto out;
1982
1983 debug2_f("num_prompts %d", num_prompts)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
1983, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "num_prompts %d", num_prompts
)
;
1984 for (i = 0; i < num_prompts; i++) {
1985 if ((r = sshpkt_get_cstring(ssh, &prompt, NULL((void*)0))) != 0 ||
1986 (r = sshpkt_get_u8(ssh, &echo)) != 0)
1987 goto out;
1988 if (asmprintf(&display_prompt, INT_MAX2147483647, NULL((void*)0), "(%s@%s) %s",
1989 authctxt->server_user, options.host_key_alias ?
1990 options.host_key_alias : authctxt->host, prompt) == -1)
1991 fatal_f("asmprintf failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 1991, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "asmprintf failed"
)
;
1992 response = read_passphrase(display_prompt, echo ? RP_ECHO0x0001 : 0);
1993 if ((r = sshpkt_put_cstring(ssh, response)) != 0)
1994 goto out;
1995 freezero(response, strlen(response));
1996 free(prompt);
1997 free(display_prompt);
1998 display_prompt = response = prompt = NULL((void*)0);
1999 }
2000 /* done with parsing incoming message. */
2001 if ((r = sshpkt_get_end(ssh)) != 0 ||
2002 (r = sshpkt_add_padding(ssh, 64)) != 0)
2003 goto out;
2004 r = sshpkt_send(ssh);
2005 out:
2006 if (response)
2007 freezero(response, strlen(response));
2008 free(prompt);
2009 free(display_prompt);
2010 free(name);
2011 free(inst);
2012 free(lang);
2013 return r;
2014}
2015
2016static int
2017ssh_keysign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp,
2018 const u_char *data, size_t datalen)
2019{
2020 struct sshbuf *b;
2021 struct stat st;
2022 pid_t pid;
2023 int r, to[2], from[2], status;
2024 int sock = ssh_packet_get_connection_in(ssh);
2025 u_char rversion = 0, version = 2;
2026 void (*osigchld)(int);
2027
2028 *sigp = NULL((void*)0);
2029 *lenp = 0;
2030
2031 if (stat(_PATH_SSH_KEY_SIGN"/usr/libexec/ssh-keysign", &st) == -1) {
2032 error_f("not installed: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2032, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "not installed: %s"
, strerror((*__errno())))
;
2033 return -1;
2034 }
2035 if (fflush(stdout(&__sF[1])) != 0) {
2036 error_f("fflush: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2036, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "fflush: %s", strerror
((*__errno())))
;
2037 return -1;
2038 }
2039 if (pipe(to) == -1) {
2040 error_f("pipe: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2040, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "pipe: %s", strerror
((*__errno())))
;
2041 return -1;
2042 }
2043 if (pipe(from) == -1) {
2044 error_f("pipe: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2044, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "pipe: %s", strerror
((*__errno())))
;
2045 return -1;
2046 }
2047 if ((pid = fork()) == -1) {
2048 error_f("fork: %s", strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2048, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "fork: %s", strerror
((*__errno())))
;
2049 return -1;
2050 }
2051 osigchld = ssh_signal(SIGCHLD20, SIG_DFL(void (*)(int))0);
2052 if (pid == 0) {
2053 close(from[0]);
2054 if (dup2(from[1], STDOUT_FILENO1) == -1)
2055 fatal_f("dup2: %s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2055, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "dup2: %s", strerror
((*__errno())))
;
2056 close(to[1]);
2057 if (dup2(to[0], STDIN_FILENO0) == -1)
2058 fatal_f("dup2: %s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2058, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "dup2: %s", strerror
((*__errno())))
;
2059 close(from[1]);
2060 close(to[0]);
2061
2062 if (dup2(sock, STDERR_FILENO2 + 1) == -1)
2063 fatal_f("dup2: %s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2063, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "dup2: %s", strerror
((*__errno())))
;
2064 sock = STDERR_FILENO2 + 1;
2065 fcntl(sock, F_SETFD2, 0); /* keep the socket on exec */
2066 closefrom(sock + 1);
2067
2068 debug3_f("[child] pid=%ld, exec %s",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2069, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "[child] pid=%ld, exec %s"
, (long)getpid(), "/usr/libexec/ssh-keysign")
2069 (long)getpid(), _PATH_SSH_KEY_SIGN)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2069, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "[child] pid=%ld, exec %s"
, (long)getpid(), "/usr/libexec/ssh-keysign")
;
2070 execl(_PATH_SSH_KEY_SIGN"/usr/libexec/ssh-keysign", _PATH_SSH_KEY_SIGN"/usr/libexec/ssh-keysign", (char *)NULL((void*)0));
2071 fatal_f("exec(%s): %s", _PATH_SSH_KEY_SIGN,sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2072, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "exec(%s): %s", "/usr/libexec/ssh-keysign"
, strerror((*__errno())))
2072 strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2072, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "exec(%s): %s", "/usr/libexec/ssh-keysign"
, strerror((*__errno())))
;
2073 }
2074 close(from[1]);
2075 close(to[0]);
2076 sock = STDERR_FILENO2 + 1;
2077
2078 if ((b = sshbuf_new()) == NULL((void*)0))
2079 fatal_f("sshbuf_new failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2079, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_new failed"
)
;
2080 /* send # of sock, data to be signed */
2081 if ((r = sshbuf_put_u32(b, sock)) != 0 ||
2082 (r = sshbuf_put_string(b, data, datalen)) != 0)
2083 fatal_fr(r, "buffer error")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2083, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "buffer error")
;
2084 if (ssh_msg_send(to[1], version, b) == -1)
2085 fatal_f("couldn't send request")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2085, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "couldn't send request"
)
;
2086 sshbuf_reset(b);
2087 r = ssh_msg_recv(from[0], b);
2088 close(from[0]);
2089 close(to[1]);
2090 if (r < 0) {
2091 error_f("no reply")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2091, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "no reply")
;
2092 goto fail;
2093 }
2094
2095 errno(*__errno()) = 0;
2096 while (waitpid(pid, &status, 0) == -1) {
2097 if (errno(*__errno()) != EINTR4) {
2098 error_f("waitpid %ld: %s", (long)pid, strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2098, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "waitpid %ld: %s", (
long)pid, strerror((*__errno())))
;
2099 goto fail;
2100 }
2101 }
2102 if (!WIFEXITED(status)(((status) & 0177) == 0)) {
2103 error_f("exited abnormally")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2103, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "exited abnormally"
)
;
2104 goto fail;
2105 }
2106 if (WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff) != 0) {
2107 error_f("exited with status %d", WEXITSTATUS(status))sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2107, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "exited with status %d"
, (int)(((unsigned)(status) >> 8) & 0xff))
;
2108 goto fail;
2109 }
2110 if ((r = sshbuf_get_u8(b, &rversion)) != 0) {
2111 error_fr(r, "buffer error")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2111, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "buffer error")
;
2112 goto fail;
2113 }
2114 if (rversion != version) {
2115 error_f("bad version")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2115, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "bad version")
;
2116 goto fail;
2117 }
2118 if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) {
2119 error_fr(r, "buffer error")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2119, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "buffer error")
;
2120 fail:
2121 ssh_signal(SIGCHLD20, osigchld);
2122 sshbuf_free(b);
2123 return -1;
2124 }
2125 ssh_signal(SIGCHLD20, osigchld);
2126 sshbuf_free(b);
2127
2128 return 0;
2129}
2130
2131static int
2132userauth_hostbased(struct ssh *ssh)
2133{
2134 Authctxt *authctxt = (Authctxt *)ssh->authctxt;
2135 struct sshkey *private = NULL((void*)0);
2136 struct sshbuf *b = NULL((void*)0);
2137 u_char *sig = NULL((void*)0), *keyblob = NULL((void*)0);
2138 char *fp = NULL((void*)0), *chost = NULL((void*)0), *lname = NULL((void*)0);
2139 size_t siglen = 0, keylen = 0;
2140 int i, r, success = 0;
2141
2142 if (authctxt->ktypes == NULL((void*)0)) {
2143 authctxt->oktypes = xstrdup(options.hostbased_accepted_algos);
2144 authctxt->ktypes = authctxt->oktypes;
2145 }
2146
2147 /*
2148 * Work through each listed type pattern in HostbasedAcceptedAlgorithms,
2149 * trying each hostkey that matches the type in turn.
2150 */
2151 for (;;) {
2152 if (authctxt->active_ktype == NULL((void*)0))
2153 authctxt->active_ktype = strsep(&authctxt->ktypes, ",");
2154 if (authctxt->active_ktype == NULL((void*)0) ||
2155 *authctxt->active_ktype == '\0')
2156 break;
2157 debug3_f("trying key type %s", authctxt->active_ktype)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2157, 1, SYSLOG_LEVEL_DEBUG3, ((void*)0), "trying key type %s"
, authctxt->active_ktype)
;
2158
2159 /* check for a useful key */
2160 private = NULL((void*)0);
2161 for (i = 0; i < authctxt->sensitive->nkeys; i++) {
2162 if (authctxt->sensitive->keys[i] == NULL((void*)0) ||
2163 authctxt->sensitive->keys[i]->type == KEY_UNSPEC)
2164 continue;
2165 if (!sshkey_match_keyname_to_sigalgs(
2166 sshkey_ssh_name(authctxt->sensitive->keys[i]),
2167 authctxt->active_ktype))
2168 continue;
2169 /* we take and free the key */
2170 private = authctxt->sensitive->keys[i];
2171 authctxt->sensitive->keys[i] = NULL((void*)0);
2172 break;
2173 }
2174 /* Found one */
2175 if (private != NULL((void*)0))
2176 break;
2177 /* No more keys of this type; advance */
2178 authctxt->active_ktype = NULL((void*)0);
2179 }
2180 if (private == NULL((void*)0)) {
2181 free(authctxt->oktypes);
2182 authctxt->oktypes = authctxt->ktypes = NULL((void*)0);
2183 authctxt->active_ktype = NULL((void*)0);
2184 debug("No more client hostkeys for hostbased authentication.")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2184, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "No more client hostkeys for hostbased authentication."
)
;
2185 goto out;
2186 }
2187
2188 if ((fp = sshkey_fingerprint(private, options.fingerprint_hash,
2189 SSH_FP_DEFAULT)) == NULL((void*)0)) {
2190 error_f("sshkey_fingerprint failed")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2190, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "sshkey_fingerprint failed"
)
;
2191 goto out;
2192 }
2193 debug_f("trying hostkey %s %s using sigalg %s",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2194, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "trying hostkey %s %s using sigalg %s"
, sshkey_ssh_name(private), fp, authctxt->active_ktype)
2194 sshkey_ssh_name(private), fp, authctxt->active_ktype)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2194, 1, SYSLOG_LEVEL_DEBUG1, ((void*)0), "trying hostkey %s %s using sigalg %s"
, sshkey_ssh_name(private), fp, authctxt->active_ktype)
;
2195
2196 /* figure out a name for the client host */
2197 lname = get_local_name(ssh_packet_get_connection_in(ssh));
2198 if (lname == NULL((void*)0)) {
2199 error_f("cannot get local ipaddr/name")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2199, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "cannot get local ipaddr/name"
)
;
2200 goto out;
2201 }
2202
2203 /* XXX sshbuf_put_stringf? */
2204 xasprintf(&chost, "%s.", lname);
2205 debug2_f("chost %s", chost)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2205, 1, SYSLOG_LEVEL_DEBUG2, ((void*)0), "chost %s", chost)
;
2206
2207 /* construct data */
2208 if ((b = sshbuf_new()) == NULL((void*)0)) {
2209 error_f("sshbuf_new failed")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2209, 1, SYSLOG_LEVEL_ERROR, ((void*)0), "sshbuf_new failed"
)
;
2210 goto out;
2211 }
2212 if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) {
2213 error_fr(r, "sshkey_to_blob")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2213, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "sshkey_to_blob")
;
2214 goto out;
2215 }
2216 if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
2217 (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
2218 (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
2219 (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
2220 (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 ||
2221 (r = sshbuf_put_cstring(b, authctxt->active_ktype)) != 0 ||
2222 (r = sshbuf_put_string(b, keyblob, keylen)) != 0 ||
2223 (r = sshbuf_put_cstring(b, chost)) != 0 ||
2224 (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) {
2225 error_fr(r, "buffer error")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2225, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "buffer error")
;
2226 goto out;
2227 }
2228
2229#ifdef DEBUG_PK
2230 sshbuf_dump(b, stderr(&__sF[2]));
2231#endif
2232 if ((r = ssh_keysign(ssh, private, &sig, &siglen,
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'
2233 sshbuf_ptr(b), sshbuf_len(b))) != 0) {
2234 error("sign using hostkey %s %s failed",sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2235, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "sign using hostkey %s %s failed"
, sshkey_ssh_name(private), fp)
2235 sshkey_ssh_name(private), fp)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2235, 0, SYSLOG_LEVEL_ERROR, ((void*)0), "sign using hostkey %s %s failed"
, sshkey_ssh_name(private), fp)
;
2236 goto out;
2237 }
2238 if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST50)) != 0 ||
2239 (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
2240 (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
2241 (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
2242 (r = sshpkt_put_cstring(ssh, authctxt->active_ktype)) != 0 ||
2243 (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 ||
2244 (r = sshpkt_put_cstring(ssh, chost)) != 0 ||
2245 (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 ||
2246 (r = sshpkt_put_string(ssh, sig, siglen)) != 0 ||
2247 (r = sshpkt_send(ssh)) != 0) {
2248 error_fr(r, "packet error")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2248, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "packet error")
;
2249 goto out;
2250 }
2251 success = 1;
2252
2253 out:
2254 if (sig != NULL((void*)0))
2255 freezero(sig, siglen);
2256 free(keyblob);
2257 free(lname);
2258 free(fp);
2259 free(chost);
2260 sshkey_free(private);
2261 sshbuf_free(b);
2262
2263 return success;
2264}
2265
2266/* find auth method */
2267
2268/*
2269 * given auth method name, if configurable options permit this method fill
2270 * in auth_ident field and return true, otherwise return false.
2271 */
2272static int
2273authmethod_is_enabled(Authmethod *method)
2274{
2275 if (method == NULL((void*)0))
2276 return 0;
2277 /* return false if options indicate this method is disabled */
2278 if (method->enabled == NULL((void*)0) || *method->enabled == 0)
2279 return 0;
2280 /* return false if batch mode is enabled but method needs interactive mode */
2281 if (method->batch_flag != NULL((void*)0) && *method->batch_flag != 0)
2282 return 0;
2283 return 1;
2284}
2285
2286static Authmethod *
2287authmethod_lookup(const char *name)
2288{
2289 Authmethod *method = NULL((void*)0);
2290 if (name != NULL((void*)0))
2291 for (method = authmethods; method->name != NULL((void*)0); method++)
2292 if (strcmp(name, method->name) == 0)
2293 return method;
2294 debug2("Unrecognized authentication method name: %s", name ? name : "NULL")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2294, 0, SYSLOG_LEVEL_DEBUG2, ((void*)0), "Unrecognized authentication method name: %s"
, name ? name : "NULL")
;
2295 return NULL((void*)0);
2296}
2297
2298/* XXX internal state */
2299static Authmethod *current = NULL((void*)0);
2300static char *supported = NULL((void*)0);
2301static char *preferred = NULL((void*)0);
2302
2303/*
2304 * Given the authentication method list sent by the server, return the
2305 * next method we should try. If the server initially sends a nil list,
2306 * use a built-in default list.
2307 */
2308static Authmethod *
2309authmethod_get(char *authlist)
2310{
2311 char *name = NULL((void*)0);
2312 u_int next;
2313
2314 /* Use a suitable default if we're passed a nil list. */
2315 if (authlist == NULL((void*)0) || strlen(authlist) == 0)
2316 authlist = options.preferred_authentications;
2317
2318 if (supported == NULL((void*)0) || strcmp(authlist, supported) != 0) {
2319 debug3("start over, passed a different list %s", authlist)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2319, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "start over, passed a different list %s"
, authlist)
;
2320 free(supported);
2321 supported = xstrdup(authlist);
2322 preferred = options.preferred_authentications;
2323 debug3("preferred %s", preferred)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2323, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "preferred %s", preferred
)
;
2324 current = NULL((void*)0);
2325 } else if (current != NULL((void*)0) && authmethod_is_enabled(current))
2326 return current;
2327
2328 for (;;) {
2329 if ((name = match_list(preferred, supported, &next)) == NULL((void*)0)) {
2330 debug("No more authentication methods to try.")sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2330, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "No more authentication methods to try."
)
;
2331 current = NULL((void*)0);
2332 return NULL((void*)0);
2333 }
2334 preferred += next;
2335 debug3("authmethod_lookup %s", name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2335, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "authmethod_lookup %s"
, name)
;
2336 debug3("remaining preferred: %s", preferred)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2336, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "remaining preferred: %s"
, preferred)
;
2337 if ((current = authmethod_lookup(name)) != NULL((void*)0) &&
2338 authmethod_is_enabled(current)) {
2339 debug3("authmethod_is_enabled %s", name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2339, 0, SYSLOG_LEVEL_DEBUG3, ((void*)0), "authmethod_is_enabled %s"
, name)
;
2340 debug("Next authentication method: %s", name)sshlog("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__,
2340, 0, SYSLOG_LEVEL_DEBUG1, ((void*)0), "Next authentication method: %s"
, name)
;
2341 free(name);
2342 return current;
2343 }
2344 free(name);
2345 }
2346}
2347
2348static char *
2349authmethods_get(void)
2350{
2351 Authmethod *method = NULL((void*)0);
2352 struct sshbuf *b;
2353 char *list;
2354 int r;
2355
2356 if ((b = sshbuf_new()) == NULL((void*)0))
2357 fatal_f("sshbuf_new failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2357, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_new failed"
)
;
2358 for (method = authmethods; method->name != NULL((void*)0); method++) {
2359 if (authmethod_is_enabled(method)) {
2360 if ((r = sshbuf_putf(b, "%s%s",
2361 sshbuf_len(b) ? "," : "", method->name)) != 0)
2362 fatal_fr(r, "buffer error")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2362, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "buffer error")
;
2363 }
2364 }
2365 if ((list = sshbuf_dup_string(b)) == NULL((void*)0))
2366 fatal_f("sshbuf_dup_string failed")sshfatal("/usr/src/usr.bin/ssh/ssh/../sshconnect2.c", __func__
, 2366, 1, SYSLOG_LEVEL_FATAL, ((void*)0), "sshbuf_dup_string failed"
)
;
2367 sshbuf_free(b);
2368 return list;
2369}