diff --git a/ChangeLog b/ChangeLog index ff710913b..8ed0d7377 100644 --- a/ChangeLog +++ b/ChangeLog @@ -16,6 +16,11 @@ - deraadt@cvs.openbsd.org 2002/05/22 23:18:25 [ssh.c sshd.c] spelling; abishoff@arc.nasa.gov + - markus@cvs.openbsd.org 2002/05/23 19:24:30 + [authfile.c authfile.h pathnames.h ssh.c sshconnect.c sshconnect.h + sshconnect1.c sshconnect2.c ssh-keysign.8 ssh-keysign.c Makefile.in] + add /usr/libexec/ssh-keysign: a setuid helper program for hostbased + authentication in protocol v2 (needs to access the hostkeys). 20020604 - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed @@ -700,4 +705,4 @@ - (stevesk) entropy.c: typo in debug message - (djm) ssh-keygen -i needs seeded RNG; report from markus@ -$Id: ChangeLog,v 1.2148 2002/06/06 19:51:58 mouring Exp $ +$Id: ChangeLog,v 1.2149 2002/06/06 19:57:33 mouring Exp $ diff --git a/Makefile.in b/Makefile.in index e3b145150..ec235f827 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.208 2002/05/13 04:12:05 djm Exp $ +# $Id: Makefile.in,v 1.209 2002/06/06 19:57:33 mouring Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -125,6 +125,9 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o + $(LD) -o $@ ssh-keysign.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) diff --git a/authfile.c b/authfile.c index de8b1022e..6d936de56 100644 --- a/authfile.c +++ b/authfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfile.c,v 1.48 2002/02/28 15:46:33 markus Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.49 2002/05/23 19:24:30 markus Exp $"); #include #include @@ -421,7 +421,7 @@ fail: return NULL; } -static Key * +Key * key_load_private_pem(int fd, int type, const char *passphrase, char **commentp) { diff --git a/authfile.h b/authfile.h index c614ca12c..7f92701ec 100644 --- a/authfile.h +++ b/authfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $ */ +/* $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $ */ /* * Author: Tatu Ylonen @@ -20,5 +20,6 @@ Key *key_load_public(const char *, char **); Key *key_load_public_type(int, const char *, char **); Key *key_load_private(const char *, const char *, char **); Key *key_load_private_type(int, const char *, const char *, char **); +Key *key_load_private_pem(int, int, const char *, char **); #endif diff --git a/pathnames.h b/pathnames.h index 691293c33..89e22c77a 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.12 2002/03/19 03:03:43 stevesk Exp $ */ +/* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */ /* * Author: Tatu Ylonen @@ -120,6 +120,11 @@ #define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" #endif +/* Location of ssh-keysign for hostbased authentication */ +#ifndef _PATH_SSH_KEY_SIGN +#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" +#endif + /* xauth for X11 forwarding */ #ifndef _PATH_XAUTH #define _PATH_XAUTH "/usr/X11R6/bin/xauth" diff --git a/ssh-keysign.8 b/ssh-keysign.8 new file mode 100644 index 000000000..fccbd7c27 --- /dev/null +++ b/ssh-keysign.8 @@ -0,0 +1,58 @@ +.\" $OpenBSD: ssh-keysign.8,v 1.1 2002/05/25 08:16:59 markus Exp $ +.\" +.\" Copyright (c) 2002 Markus Friedl. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (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 May 24, 2002 +.Dt SSH-KEYSIGN 8 +.Os +.Sh NAME +.Nm ssh-keysign +.Nd ssh helper program for hostbased authentication +.Sh SYNOPSIS +.Nm ssh-keysign +.Sh DESCRIPTION +.Nm +is used by +.Xr ssh 1 +to access the local host keys during hostbased authentication with +SSH protocol version 2. +Since the host keys are readable only by root +.Nm +must be setuid root. +.Nm +is not intended to be invoked by the user, but from +.Xr ssh 1 . +See +.Xr ssh 1 +and +.Xr sshd 8 +for more information about hostbased authentication. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr sshd 8 +.Sh AUTHORS +Markus Friedl +.Sh HISTORY +.Nm +first appeared in +.Ox 3.2 . diff --git a/ssh-keysign.c b/ssh-keysign.c new file mode 100644 index 000000000..da630708d --- /dev/null +++ b/ssh-keysign.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2002 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "includes.h" +RCSID("$OpenBSD: ssh-keysign.c,v 1.2 2002/05/31 10:30:33 markus Exp $"); + +#include + +#include "log.h" +#include "key.h" +#include "ssh2.h" +#include "misc.h" +#include "xmalloc.h" +#include "buffer.h" +#include "bufaux.h" +#include "authfile.h" +#include "msg.h" +#include "canohost.h" +#include "pathnames.h" + +static int +valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, + u_int datalen) +{ + Buffer b; + Key *key; + u_char *pkblob; + u_int blen, len; + char *pkalg, *p; + int pktype, fail; + + fail = 0; + + buffer_init(&b); + buffer_append(&b, data, datalen); + + /* session id */ + buffer_skip_string(&b); + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + + /* server user */ + buffer_skip_string(&b); + + /* service */ + p = buffer_get_string(&b, NULL); + if (strcmp("ssh-connection", p) != 0) + fail++; + xfree(p); + + /* method */ + p = buffer_get_string(&b, NULL); + if (strcmp("hostbased", p) != 0) + fail++; + xfree(p); + + /* pubkey */ + pkalg = buffer_get_string(&b, NULL); + pkblob = buffer_get_string(&b, &blen); + + pktype = key_type_from_name(pkalg); + if (pktype == KEY_UNSPEC) + fail++; + else if ((key = key_from_blob(pkblob, blen)) == NULL) + fail++; + else if (key->type != pktype) + fail++; + xfree(pkalg); + xfree(pkblob); + + /* client host name, handle trailing dot */ + p = buffer_get_string(&b, &len); + debug2("valid_request: check expect chost %s got %s", host, p); + if (strlen(host) != len - 1) + fail++; + else if (p[len - 1] != '.') + fail++; + else if (strncasecmp(host, p, len - 1) != 0) + fail++; + xfree(p); + + /* local user */ + p = buffer_get_string(&b, NULL); + + if (strcmp(pw->pw_name, p) != 0) + fail++; + xfree(p); + + /* end of message */ + if (buffer_len(&b) != 0) + fail++; + + debug3("valid_request: fail %d", fail); + + if (fail && key != NULL) + key_free(key); + else + *ret = key; + + return (fail ? -1 : 0); +} + +int +main(int argc, char **argv) +{ + Buffer b; + Key *keys[2], *key; + struct passwd *pw; + int key_fd[2], i, found, version = 2, fd; + u_char *signature, *data; + char *host; + u_int slen, dlen; + + key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); + key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); + + seteuid(getuid()); + setuid(getuid()); + +#ifdef DEBUG_SSH_KEYSIGN + log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); +#endif + + if (key_fd[0] == -1 && key_fd[1] == -1) + fatal("could not open any host key"); + + if ((pw = getpwuid(getuid())) == NULL) + fatal("getpwuid failed"); + pw = pwcopy(pw); + + SSLeay_add_all_algorithms(); + + found = 0; + for (i = 0; i < 2; i++) { + keys[i] = NULL; + if (key_fd[i] == -1) + continue; + keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, + NULL, NULL); + close(key_fd[i]); + if (keys[i] != NULL) + found = 1; + } + if (!found) + fatal("no hostkey found"); + + buffer_init(&b); + if (msg_recv(STDIN_FILENO, &b) < 0) + fatal("msg_recv failed"); + if (buffer_get_char(&b) != version) + fatal("bad version"); + fd = buffer_get_int(&b); + if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) + fatal("bad fd"); + if ((host = get_local_name(fd)) == NULL) + fatal("cannot get sockname for fd"); + + data = buffer_get_string(&b, &dlen); + if (valid_request(pw, host, &key, data, dlen) < 0) + fatal("not a valid request"); + xfree(data); + xfree(host); + + found = 0; + for (i = 0; i < 2; i++) { + if (keys[i] != NULL && + key_equal(key, keys[i])) { + found = 1; + break; + } + } + if (!found) + fatal("no matching hostkey found"); + + if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) + fatal("key_sign failed"); + + /* send reply */ + buffer_clear(&b); + buffer_put_string(&b, signature, slen); + msg_send(STDOUT_FILENO, version, &b); + + return (0); +} diff --git a/ssh.c b/ssh.c index 4b82d1e7e..2e479d521 100644 --- a/ssh.c +++ b/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.172 2002/05/22 23:18:25 deraadt Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.173 2002/05/23 19:24:30 markus Exp $"); #include #include @@ -132,10 +132,7 @@ char *host; struct sockaddr_storage hostaddr; /* Private host keys. */ -struct { - Key **keys; - int nkeys; -} sensitive_data; +Sensitive sensitive_data; /* Original real UID. */ uid_t original_real_uid; @@ -689,6 +686,7 @@ again: */ sensitive_data.nkeys = 0; sensitive_data.keys = NULL; + sensitive_data.external_keysign = 0; if (!cerr && (options.rhosts_rsa_authentication || options.hostbased_authentication)) { sensitive_data.nkeys = 3; @@ -699,6 +697,16 @@ again: _PATH_HOST_DSA_KEY_FILE, "", NULL); sensitive_data.keys[2] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); + + if (sensitive_data.keys[0] == NULL && + sensitive_data.keys[1] == NULL && + sensitive_data.keys[2] == NULL) { + sensitive_data.keys[1] = key_load_public( + _PATH_HOST_DSA_KEY_FILE, NULL); + sensitive_data.keys[2] = key_load_public( + _PATH_HOST_RSA_KEY_FILE, NULL); + sensitive_data.external_keysign = 1; + } } /* * Get rid of any extra privileges that we may have. We will no @@ -758,8 +766,7 @@ again: signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ /* Log into the remote system. This never returns if the login fails. */ - ssh_login(sensitive_data.keys, sensitive_data.nkeys, - host, (struct sockaddr *)&hostaddr, pw); + ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { diff --git a/sshconnect.c b/sshconnect.c index 5bb50e0e9..7af0b9a80 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.119 2002/01/21 15:13:51 markus Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.120 2002/05/23 19:24:30 markus Exp $"); #include @@ -844,7 +844,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) * This function does not require super-user privileges. */ void -ssh_login(Key **keys, int nkeys, const char *orighost, +ssh_login(Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr, struct passwd *pw) { char *host, *cp; @@ -869,10 +869,10 @@ ssh_login(Key **keys, int nkeys, const char *orighost, /* authenticate user */ if (compat20) { ssh_kex2(host, hostaddr); - ssh_userauth2(local_user, server_user, host, keys, nkeys); + ssh_userauth2(local_user, server_user, host, sensitive); } else { ssh_kex(host, hostaddr); - ssh_userauth1(local_user, server_user, host, keys, nkeys); + ssh_userauth1(local_user, server_user, host, sensitive); } } diff --git a/sshconnect.h b/sshconnect.h index b475adde0..ad34ee64a 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.13 2001/10/08 19:05:05 markus Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.14 2002/05/23 19:24:30 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -26,20 +26,27 @@ #ifndef SSHCONNECT_H #define SSHCONNECT_H +typedef struct Sensitive Sensitive; +struct Sensitive { + Key **keys; + int nkeys; + int external_keysign; +}; + int ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, int, struct passwd *, const char *); void -ssh_login(Key **, int, const char *, struct sockaddr *, struct passwd *); +ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *); int verify_host_key(char *, struct sockaddr *, Key *); void ssh_kex(char *, struct sockaddr *); void ssh_kex2(char *, struct sockaddr *); -void ssh_userauth1(const char *, const char *, char *, Key **, int); -void ssh_userauth2(const char *, const char *, char *, Key **, int); +void ssh_userauth1(const char *, const char *, char *, Sensitive *); +void ssh_userauth2(const char *, const char *, char *, Sensitive *); void ssh_put_password(char *); diff --git a/sshconnect1.c b/sshconnect1.c index d2024a2b7..e28b7fc72 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.50 2002/04/21 16:25:06 stevesk Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.51 2002/05/23 19:24:30 markus Exp $"); #include #include @@ -1138,7 +1138,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) */ void ssh_userauth1(const char *local_user, const char *server_user, char *host, - Key **keys, int nkeys) + Sensitive *sensitive) { #ifdef KRB5 krb5_context context = NULL; @@ -1224,9 +1224,11 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, */ if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && options.rhosts_rsa_authentication) { - for (i = 0; i < nkeys; i++) { - if (keys[i] != NULL && keys[i]->type == KEY_RSA1 && - try_rhosts_rsa_authentication(local_user, keys[i])) + for (i = 0; i < sensitive->nkeys; i++) { + if (sensitive->keys[i] != NULL && + sensitive->keys[i]->type == KEY_RSA1 && + try_rhosts_rsa_authentication(local_user, + sensitive->keys[i])) goto success; } } diff --git a/sshconnect2.c b/sshconnect2.c index 1ee92ab0d..2736856fa 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.99 2002/03/26 15:58:46 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.100 2002/05/23 19:24:30 markus Exp $"); #include "ssh.h" #include "ssh2.h" @@ -45,6 +45,8 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.99 2002/03/26 15:58:46 markus Exp $"); #include "match.h" #include "dispatch.h" #include "canohost.h" +#include "msg.h" +#include "pathnames.h" /* import */ extern char *client_version_string; @@ -154,8 +156,7 @@ struct Authctxt { int last_key_hint; AuthenticationConnection *agent; /* hostbased */ - Key **keys; - int nkeys; + Sensitive *sensitive; /* kbd-interactive */ int info_req_seen; }; @@ -215,7 +216,7 @@ Authmethod authmethods[] = { void ssh_userauth2(const char *local_user, const char *server_user, char *host, - Key **keys, int nkeys) + Sensitive *sensitive) { Authctxt authctxt; int type; @@ -255,8 +256,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, authctxt.success = 0; authctxt.method = authmethod_lookup("none"); authctxt.authlist = NULL; - authctxt.keys = keys; - authctxt.nkeys = nkeys; + authctxt.sensitive = sensitive; authctxt.info_req_seen = 0; if (authctxt.method == NULL) fatal("ssh_userauth2: internal error: cannot send userauth none request"); @@ -893,6 +893,75 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) packet_send(); } +static int +ssh_keysign( + Key *key, + u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) +{ + Buffer b; + pid_t pid; + int to[2], from[2], status, version = 1; + + debug("ssh_keysign called"); + + if (fflush(stdout) != 0) + error("ssh_keysign: fflush: %s", strerror(errno)); + if (pipe(to) < 0) { + error("ssh_keysign: pipe: %s", strerror(errno)); + return -1; + } + if (pipe(from) < 0) { + error("ssh_keysign: pipe: %s", strerror(errno)); + return -1; + } + if ((pid = fork()) < 0) { + error("ssh_keysign: fork: %s", strerror(errno)); + return -1; + } + if (pid == 0) { + seteuid(getuid()); + setuid(getuid()); + close(from[0]); + if (dup2(from[1], STDOUT_FILENO) < 0) + fatal("ssh_keysign: dup2: %s", strerror(errno)); + close(to[1]); + if (dup2(to[0], STDIN_FILENO) < 0) + fatal("ssh_keysign: dup2: %s", strerror(errno)); + execlp(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); + fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, + strerror(errno)); + } + close(from[1]); + close(to[0]); + + buffer_init(&b); + buffer_put_string(&b, data, datalen); + msg_send(to[1], version, &b); + + if (msg_recv(from[0], &b) < 0) { + debug("ssh_keysign: no reply"); + buffer_clear(&b); + return -1; + } + if (buffer_get_char(&b) != version) { + debug("ssh_keysign: bad version"); + buffer_clear(&b); + return -1; + } + *sigp = buffer_get_string(&b, lenp); + buffer_clear(&b); + + close(from[0]); + close(to[1]); + + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + break; + + return 0; +} + /* * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign * will be setuid-root and the sbit can be removed from /usr/bin/ssh. @@ -901,6 +970,7 @@ int userauth_hostbased(Authctxt *authctxt) { Key *private = NULL; + Sensitive *sensitive = authctxt->sensitive; Buffer b; u_char *signature, *blob; char *chost, *pkalg, *p; @@ -909,12 +979,12 @@ userauth_hostbased(Authctxt *authctxt) int ok, i, len, found = 0; /* check for a useful key */ - for (i = 0; i < authctxt->nkeys; i++) { - private = authctxt->keys[i]; + for (i = 0; i < sensitive->nkeys; i++) { + private = sensitive->keys[i]; if (private && private->type != KEY_RSA1) { found = 1; /* we take and free the key */ - authctxt->keys[i] = NULL; + sensitive->keys[i] = NULL; break; } } @@ -956,7 +1026,12 @@ userauth_hostbased(Authctxt *authctxt) #ifdef DEBUG_PK buffer_dump(&b); #endif - ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); + 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) {