diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/ssh/readconf.c | 25 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/scp.1 | 5 | ||||
-rw-r--r-- | usr.bin/ssh/sftp.1 | 5 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.1 | 5 | ||||
-rw-r--r-- | usr.bin/ssh/ssh_config.5 | 15 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect2.c | 306 |
7 files changed, 245 insertions, 120 deletions
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 5b330e19f76..45027a3cc60 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.229 2015/01/26 03:04:45 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.230 2015/01/30 11:43:14 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -145,7 +145,7 @@ typedef enum { oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, - oFingerprintHash, oUpdateHostkeys, + oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -263,6 +263,7 @@ static struct { { "revokedhostkeys", oRevokedHostKeys }, { "fingerprinthash", oFingerprintHash }, { "updatehostkeys", oUpdateHostkeys }, + { "hostbasedkeytypes", oHostbasedKeyTypes }, { "ignoreunknown", oIgnoreUnknown }, { NULL, oBadOption } @@ -1469,6 +1470,19 @@ parse_int: intptr = &options->update_hostkeys; goto parse_flag; + case oHostbasedKeyTypes: + charptr = &options->hostbased_key_types; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if (!sshkey_names_valid2(arg, 1)) + fatal("%s line %d: Bad key types '%s'.", + filename, linenum, arg ? arg : "<NONE>"); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1648,6 +1662,7 @@ initialize_options(Options * options) options->revoked_host_keys = NULL; options->fingerprint_hash = -1; options->update_hostkeys = -1; + options->hostbased_key_types = NULL; } /* @@ -1827,6 +1842,8 @@ fill_default_options(Options * options) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; if (options->update_hostkeys == -1) options->update_hostkeys = 1; + if (options->hostbased_key_types == NULL) + options->hostbased_key_types = xstrdup("*"); #define CLEAR_ON_NONE(v) \ do { \ @@ -2267,6 +2284,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oControlPath, o->control_path); dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); dump_cfg_string(oHostKeyAlias, o->host_key_alias); + dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); dump_cfg_string(oLocalCommand, o->local_command); @@ -2275,9 +2293,10 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); dump_cfg_string(oProxyCommand, o->proxy_command); - dump_cfg_string(oXAuthLocation, o->xauth_location); dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); + dump_cfg_string(oXAuthLocation, o->xauth_location); + /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h index 7a8ae17c058..701b9c6965e 100644 --- a/usr.bin/ssh/readconf.h +++ b/usr.bin/ssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.107 2015/01/26 03:04:45 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.108 2015/01/30 11:43:14 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -150,6 +150,8 @@ typedef struct { int update_hostkeys; + char *hostbased_key_types; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; diff --git a/usr.bin/ssh/scp.1 b/usr.bin/ssh/scp.1 index b80ad8bfcfd..0e84780e0e5 100644 --- a/usr.bin/ssh/scp.1 +++ b/usr.bin/ssh/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.65 2015/01/26 13:55:29 jmc Exp $ +.\" $OpenBSD: scp.1,v 1.66 2015/01/30 11:43:14 djm Exp $ .\" -.Dd $Mdocdate: January 26 2015 $ +.Dd $Mdocdate: January 30 2015 $ .Dt SCP 1 .Os .Sh NAME @@ -150,6 +150,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName diff --git a/usr.bin/ssh/sftp.1 b/usr.bin/ssh/sftp.1 index 9eed155f7b7..214f0118c0b 100644 --- a/usr.bin/ssh/sftp.1 +++ b/usr.bin/ssh/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.100 2015/01/26 12:16:36 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.101 2015/01/30 11:43:14 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: January 26 2015 $ +.Dd $Mdocdate: January 30 2015 $ .Dt SFTP 1 .Os .Sh NAME @@ -215,6 +215,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName diff --git a/usr.bin/ssh/ssh.1 b/usr.bin/ssh/ssh.1 index 7e734abf022..56492120193 100644 --- a/usr.bin/ssh/ssh.1 +++ b/usr.bin/ssh/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.354 2015/01/26 12:16:36 djm Exp $ -.Dd $Mdocdate: January 26 2015 $ +.\" $OpenBSD: ssh.1,v 1.355 2015/01/30 11:43:14 djm Exp $ +.Dd $Mdocdate: January 30 2015 $ .Dt SSH 1 .Os .Sh NAME @@ -445,6 +445,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5 index 9c0b357955a..95b7bf6e4f6 100644 --- a/usr.bin/ssh/ssh_config.5 +++ b/usr.bin/ssh/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.201 2015/01/26 12:16:36 djm Exp $ -.Dd $Mdocdate: January 26 2015 $ +.\" $OpenBSD: ssh_config.5,v 1.202 2015/01/30 11:43:14 djm Exp $ +.Dd $Mdocdate: January 30 2015 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -777,6 +777,17 @@ The default is This option applies to protocol version 2 only and is similar to .Cm RhostsRSAAuthentication . +.It Cm HostbasedKeyTypes +Specifies the key types that will be used for hostbased authentication +as a comma-separated pattern list. +The default +.Dq * +will allow all key types. +The +.Fl Q +option of +.Xr ssh 1 +may be used to list supported key types. .It Cm HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c index 12515fdf986..9af29559d9a 100644 --- a/usr.bin/ssh/sshconnect2.c +++ b/usr.bin/ssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.222 2015/01/28 22:36:00 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.223 2015/01/30 11:43:14 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -267,6 +267,8 @@ struct cauthctxt { int agent_fd; /* hostbased */ Sensitive *sensitive; + char *oktypes, *ktypes; + const char *active_ktype; /* kbd-interactive */ int info_req_seen; /* generic */ @@ -395,6 +397,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, authctxt.authlist = NULL; authctxt.methoddata = NULL; authctxt.sensitive = sensitive; + authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL; authctxt.info_req_seen = 0; authctxt.agent_fd = -1; if (authctxt.method == NULL) @@ -1446,78 +1449,116 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) } static int -ssh_keysign(Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) +ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen) { - Buffer b; + struct sshbuf *b; struct stat st; pid_t pid; - int to[2], from[2], status, version = 2; + int i, r, to[2], from[2], status, sock = packet_get_connection_in(); + u_char rversion = 0, version = 2; + void (*osigchld)(int); - debug2("ssh_keysign called"); + *sigp = NULL; + *lenp = 0; if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { - error("ssh_keysign: not installed: %s", strerror(errno)); + error("%s: not installed: %s", __func__, strerror(errno)); + return -1; + } + if (fflush(stdout) != 0) { + error("%s: fflush: %s", __func__, strerror(errno)); return -1; } - if (fflush(stdout) != 0) - error("ssh_keysign: fflush: %s", strerror(errno)); if (pipe(to) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); + error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if (pipe(from) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); + error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if ((pid = fork()) < 0) { - error("ssh_keysign: fork: %s", strerror(errno)); + error("%s: fork: %s", __func__, strerror(errno)); return -1; } + osigchld = signal(SIGCHLD, SIG_DFL); if (pid == 0) { /* keep the socket on exec */ - fcntl(packet_get_connection_in(), F_SETFD, 0); + fcntl(sock, F_SETFD, 0); permanently_drop_suid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); + fatal("%s: dup2: %s", __func__, strerror(errno)); close(to[1]); if (dup2(to[0], STDIN_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); + fatal("%s: dup2: %s", __func__, strerror(errno)); close(from[1]); close(to[0]); + /* Close everything but stdio and the socket */ + for (i = STDERR_FILENO + 1; i < sock; i++) + close(i); + closefrom(sock + 1); + debug3("%s: [child] pid=%ld, exec %s", + __func__, (long)getpid(), _PATH_SSH_KEY_SIGN); execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); - fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, + fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, strerror(errno)); } close(from[1]); close(to[0]); - buffer_init(&b); - buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ - buffer_put_string(&b, data, datalen); - if (ssh_msg_send(to[1], version, &b) == -1) - fatal("ssh_keysign: couldn't send request"); - - if (ssh_msg_recv(from[0], &b) < 0) { - error("ssh_keysign: no reply"); - buffer_free(&b); - return -1; - } + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + /* send # of sock, data to be signed */ + if ((r = sshbuf_put_u32(b, sock) != 0) || + (r = sshbuf_put_string(b, data, datalen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (ssh_msg_send(to[1], version, b) == -1) + fatal("%s: couldn't send request", __func__); + sshbuf_reset(b); + r = ssh_msg_recv(from[0], b); close(from[0]); close(to[1]); + if (r < 0) { + error("%s: no reply", __func__); + goto fail; + } - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - if (buffer_get_char(&b) != version) { - error("ssh_keysign: bad version"); - buffer_free(&b); + errno = 0; + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + error("%s: waitpid %ld: %s", + __func__, (long)pid, strerror(errno)); + goto fail; + } + } + if (!WIFEXITED(status)) { + error("%s: exited abnormally", __func__); + goto fail; + } + if (WEXITSTATUS(status) != 0) { + error("%s: exited with status %d", + __func__, WEXITSTATUS(status)); + goto fail; + } + if ((r = sshbuf_get_u8(b, &rversion)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + goto fail; + } + if (rversion != version) { + error("%s: bad version", __func__); + goto fail; + } + if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + fail: + signal(SIGCHLD, osigchld); + sshbuf_free(b); return -1; } - *sigp = buffer_get_string(&b, lenp); - buffer_free(&b); + signal(SIGCHLD, osigchld); + sshbuf_free(b); return 0; } @@ -1525,100 +1566,149 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, int userauth_hostbased(Authctxt *authctxt) { - Key *private = NULL; - Sensitive *sensitive = authctxt->sensitive; - Buffer b; - u_char *signature, *blob; - char *chost, *pkalg, *p; + struct ssh *ssh = active_state; + struct sshkey *private = NULL; + struct sshbuf *b = NULL; const char *service; - u_int blen, slen; - int ok, i, found = 0; - - /* XXX provide some way to allow user to specify key types attempted */ + u_char *sig = NULL, *keyblob = NULL; + char *fp = NULL, *chost = NULL, *lname = NULL; + size_t siglen = 0, keylen = 0; + int i, r, success = 0; + + if (authctxt->ktypes == NULL) { + authctxt->oktypes = xstrdup(options.hostbased_key_types); + authctxt->ktypes = authctxt->oktypes; + } - /* check for a useful key */ - for (i = 0; i < sensitive->nkeys; i++) { - private = sensitive->keys[i]; - if (private && private->type != KEY_RSA1) { - found = 1; + /* + * Work through each listed type pattern in HostbasedKeyTypes, + * trying each hostkey that matches the type in turn. + */ + for (;;) { + if (authctxt->active_ktype == NULL) + authctxt->active_ktype = strsep(&authctxt->ktypes, ","); + if (authctxt->active_ktype == NULL || + *authctxt->active_ktype == '\0') + break; + debug3("%s: trying key type %s", __func__, + authctxt->active_ktype); + + /* check for a useful key */ + private = NULL; + for (i = 0; i < authctxt->sensitive->nkeys; i++) { + if (authctxt->sensitive->keys[i] == NULL || + authctxt->sensitive->keys[i]->type == KEY_RSA1 || + authctxt->sensitive->keys[i]->type == KEY_UNSPEC) + continue; + if (match_pattern_list( + sshkey_ssh_name(authctxt->sensitive->keys[i]), + authctxt->active_ktype, + strlen(authctxt->active_ktype), 0) != 1) + continue; /* we take and free the key */ - sensitive->keys[i] = NULL; + private = authctxt->sensitive->keys[i]; + authctxt->sensitive->keys[i] = NULL; break; } + /* Found one */ + if (private != NULL) + break; + /* No more keys of this type; advance */ + authctxt->active_ktype = NULL; } - if (!found) { + if (private == NULL) { + free(authctxt->oktypes); + authctxt->oktypes = authctxt->ktypes = NULL; + authctxt->active_ktype = NULL; debug("No more client hostkeys for hostbased authentication."); - return 0; + goto out; } - debug("%s: trying hostkey type %s", __func__, key_type(private)); - - if (key_to_blob(private, &blob, &blen) == 0) { - key_free(private); - return 0; + if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; } + debug("%s: trying hostkey %s %s", + __func__, sshkey_ssh_name(private), fp); /* figure out a name for the client host */ - p = get_local_name(packet_get_connection_in()); - if (p == NULL) { - error("userauth_hostbased: cannot get local ipaddr/name"); - key_free(private); - free(blob); - return 0; + if ((lname = get_local_name(packet_get_connection_in())) == NULL) { + error("%s: cannot get local ipaddr/name", __func__); + goto out; } - xasprintf(&chost, "%s.", p); - debug2("userauth_hostbased: chost %s", chost); - free(p); + + /* XXX sshbuf_put_stringf? */ + xasprintf(&chost, "%s.", lname); + debug2("%s: chost %s", __func__, chost); service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; - pkalg = xstrdup(key_ssh_name(private)); - buffer_init(&b); + /* construct data */ - buffer_put_string(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->server_user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, authctxt->method->name); - buffer_put_cstring(&b, pkalg); - buffer_put_string(&b, blob, blen); - buffer_put_cstring(&b, chost); - buffer_put_cstring(&b, authctxt->local_user); + if ((b = sshbuf_new()) == NULL) { + error("%s: sshbuf_new failed", __func__); + goto out; + } + if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) { + error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); + goto out; + } + if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || + (r = sshbuf_put_cstring(b, service)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || + (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 || + (r = sshbuf_put_string(b, keyblob, keylen)) != 0 || + (r = sshbuf_put_cstring(b, chost)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + goto out; + } + #ifdef DEBUG_PK - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (sensitive->external_keysign) - ok = ssh_keysign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - else - ok = key_sign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - key_free(private); - buffer_free(&b); - if (ok != 0) { - error("key_sign failed"); - free(chost); - free(pkalg); - free(blob); - return 0; + if (authctxt->sensitive->external_keysign) + r = ssh_keysign(private, &sig, &siglen, + sshbuf_ptr(b), sshbuf_len(b)); + else if ((r = sshkey_sign(private, &sig, &siglen, + sshbuf_ptr(b), sshbuf_len(b), datafellows)) != 0) + debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); + if (r != 0) { + error("sign using hostkey %s %s failed", + sshkey_ssh_name(private), fp); + goto out; } - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_cstring(pkalg); - packet_put_string(blob, blen); - packet_put_cstring(chost); - packet_put_cstring(authctxt->local_user); - packet_put_string(signature, slen); - explicit_bzero(signature, slen); - free(signature); + if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 || + (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 || + (r = sshpkt_put_cstring(ssh, chost)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 || + (r = sshpkt_put_string(ssh, sig, siglen)) != 0 || + (r = sshpkt_send(ssh)) != 0) { + error("%s: packet error: %s", __func__, ssh_err(r)); + goto out; + } + success = 1; + + out: + if (sig != NULL) { + explicit_bzero(sig, siglen); + free(sig); + } + free(keyblob); + free(lname); + free(fp); free(chost); - free(pkalg); - free(blob); + sshkey_free(private); + sshbuf_free(b); - packet_send(); - return 1; + return success; } /* find auth method */ |