mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-28 08:14:24 +02:00
- markus@cvs.openbsd.org 2001/03/08 21:42:33
[compat.c compat.h readconf.h ssh.c sshconnect1.c sshconnect2.c] implement client side of SSH2_MSG_USERAUTH_PK_OK (test public key -> no need to do enter passphrase or do expensive sign operations if the server does not accept key).
This commit is contained in:
parent
283cb821cd
commit
266dfdfd62
@ -6,6 +6,11 @@
|
|||||||
- stevesk@cvs.openbsd.org 2001/03/08 20:44:48
|
- stevesk@cvs.openbsd.org 2001/03/08 20:44:48
|
||||||
[sftp.1]
|
[sftp.1]
|
||||||
spelling, cleanup; ok deraadt@
|
spelling, cleanup; ok deraadt@
|
||||||
|
- markus@cvs.openbsd.org 2001/03/08 21:42:33
|
||||||
|
[compat.c compat.h readconf.h ssh.c sshconnect1.c sshconnect2.c]
|
||||||
|
implement client side of SSH2_MSG_USERAUTH_PK_OK (test public key ->
|
||||||
|
no need to do enter passphrase or do expensive sign operations if the
|
||||||
|
server does not accept key).
|
||||||
|
|
||||||
20010308
|
20010308
|
||||||
- OpenBSD CVS Sync
|
- OpenBSD CVS Sync
|
||||||
@ -4452,4 +4457,4 @@
|
|||||||
- Wrote replacements for strlcpy and mkdtemp
|
- Wrote replacements for strlcpy and mkdtemp
|
||||||
- Released 1.0pre1
|
- Released 1.0pre1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.929 2001/03/09 00:09:02 mouring Exp $
|
$Id: ChangeLog,v 1.930 2001/03/09 00:12:22 mouring Exp $
|
||||||
|
7
compat.c
7
compat.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: compat.c,v 1.36 2001/02/27 11:00:11 markus Exp $");
|
RCSID("$OpenBSD: compat.c,v 1.37 2001/03/08 21:42:31 markus Exp $");
|
||||||
|
|
||||||
#ifdef HAVE_LIBPCRE
|
#ifdef HAVE_LIBPCRE
|
||||||
# include <pcreposix.h>
|
# include <pcreposix.h>
|
||||||
@ -78,11 +78,12 @@ compat_datafellows(const char *version)
|
|||||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG },
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG },
|
||||||
{ "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
{ "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD },
|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||||
|
SSH_BUG_PKOK },
|
||||||
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
{ "^2\\.0\\.", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||||
SSH_BUG_PKAUTH },
|
SSH_BUG_PKAUTH|SSH_BUG_PKOK },
|
||||||
{ "^2\\.[23]\\.0", SSH_BUG_HMAC},
|
{ "^2\\.[23]\\.0", SSH_BUG_HMAC},
|
||||||
{ "^2\\.[2-9]\\.", 0 },
|
{ "^2\\.[2-9]\\.", 0 },
|
||||||
{ "^2\\.4$", SSH_OLD_SESSIONID}, /* Van Dyke */
|
{ "^2\\.4$", SSH_OLD_SESSIONID}, /* Van Dyke */
|
||||||
|
3
compat.h
3
compat.h
@ -21,7 +21,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* RCSID("$OpenBSD: compat.h,v 1.15 2001/02/19 09:53:31 markus Exp $"); */
|
/* RCSID("$OpenBSD: compat.h,v 1.16 2001/03/08 21:42:32 markus Exp $"); */
|
||||||
|
|
||||||
#ifndef COMPAT_H
|
#ifndef COMPAT_H
|
||||||
#define COMPAT_H
|
#define COMPAT_H
|
||||||
@ -40,6 +40,7 @@
|
|||||||
#define SSH_BUG_DEBUG 0x0040
|
#define SSH_BUG_DEBUG 0x0040
|
||||||
#define SSH_BUG_BANNER 0x0080
|
#define SSH_BUG_BANNER 0x0080
|
||||||
#define SSH_BUG_IGNOREMSG 0x0100
|
#define SSH_BUG_IGNOREMSG 0x0100
|
||||||
|
#define SSH_BUG_PKOK 0x0200
|
||||||
|
|
||||||
void enable_compat13(void);
|
void enable_compat13(void);
|
||||||
void enable_compat20(void);
|
void enable_compat20(void);
|
||||||
|
@ -11,11 +11,13 @@
|
|||||||
* called by a name other than "ssh" or "Secure Shell".
|
* called by a name other than "ssh" or "Secure Shell".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* RCSID("$OpenBSD: readconf.h,v 1.26 2001/02/11 12:59:25 markus Exp $"); */
|
/* RCSID("$OpenBSD: readconf.h,v 1.27 2001/03/08 21:42:32 markus Exp $"); */
|
||||||
|
|
||||||
#ifndef READCONF_H
|
#ifndef READCONF_H
|
||||||
#define READCONF_H
|
#define READCONF_H
|
||||||
|
|
||||||
|
#include "key.h"
|
||||||
|
|
||||||
/* Data structure for representing a forwarding request. */
|
/* Data structure for representing a forwarding request. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -83,7 +85,7 @@ typedef struct {
|
|||||||
|
|
||||||
int num_identity_files; /* Number of files for RSA/DSA identities. */
|
int num_identity_files; /* Number of files for RSA/DSA identities. */
|
||||||
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
char *identity_files[SSH_MAX_IDENTITY_FILES];
|
||||||
int identity_files_type[SSH_MAX_IDENTITY_FILES];
|
Key *identity_keys[SSH_MAX_IDENTITY_FILES];
|
||||||
|
|
||||||
/* Local TCP/IP forward requests. */
|
/* Local TCP/IP forward requests. */
|
||||||
int num_local_forwards;
|
int num_local_forwards;
|
||||||
|
46
ssh.c
46
ssh.c
@ -39,7 +39,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: ssh.c,v 1.103 2001/03/04 17:42:28 millert Exp $");
|
RCSID("$OpenBSD: ssh.c,v 1.104 2001/03/08 21:42:32 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@ -233,7 +233,7 @@ rsh_connect(char *host, char *user, Buffer * command)
|
|||||||
|
|
||||||
int ssh_session(void);
|
int ssh_session(void);
|
||||||
int ssh_session2(void);
|
int ssh_session2(void);
|
||||||
int guess_identity_file_type(const char *filename);
|
void load_public_identity_files(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main program for the ssh client.
|
* Main program for the ssh client.
|
||||||
@ -678,15 +678,11 @@ main(int ac, char **av)
|
|||||||
}
|
}
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* Expand ~ in options.identity_files, known host file names. */
|
/* load options.identity_files */
|
||||||
/* XXX mem-leaks */
|
load_public_identity_files();
|
||||||
for (i = 0; i < options.num_identity_files; i++) {
|
|
||||||
options.identity_files[i] =
|
/* Expand ~ in known host file names. */
|
||||||
tilde_expand_filename(options.identity_files[i], original_real_uid);
|
/* XXX mem-leaks: */
|
||||||
options.identity_files_type[i] = guess_identity_file_type(options.identity_files[i]);
|
|
||||||
debug("identity file %s type %d", options.identity_files[i],
|
|
||||||
options.identity_files_type[i]);
|
|
||||||
}
|
|
||||||
options.system_hostfile =
|
options.system_hostfile =
|
||||||
tilde_expand_filename(options.system_hostfile, original_real_uid);
|
tilde_expand_filename(options.system_hostfile, original_real_uid);
|
||||||
options.user_hostfile =
|
options.user_hostfile =
|
||||||
@ -1095,3 +1091,31 @@ guess_identity_file_type(const char *filename)
|
|||||||
key_free(public);
|
key_free(public);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
load_public_identity_files(void)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
Key *public;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < options.num_identity_files; i++) {
|
||||||
|
filename = tilde_expand_filename(options.identity_files[i],
|
||||||
|
original_real_uid);
|
||||||
|
public = key_new(KEY_RSA1);
|
||||||
|
if (!load_public_key(filename, public, NULL)) {
|
||||||
|
key_free(public);
|
||||||
|
public = key_new(KEY_UNSPEC);
|
||||||
|
if (!try_load_public_key(filename, public, NULL)) {
|
||||||
|
debug("unknown identity file %s", filename);
|
||||||
|
key_free(public);
|
||||||
|
public = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug("identity file %s type %d", filename,
|
||||||
|
public ? public->type : -1);
|
||||||
|
xfree(options.identity_files[i]);
|
||||||
|
options.identity_files[i] = filename;
|
||||||
|
options.identity_keys[i] = public;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect1.c,v 1.27 2001/02/15 23:19:59 markus Exp $");
|
RCSID("$OpenBSD: sshconnect1.c,v 1.28 2001/03/08 21:42:33 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
@ -1017,7 +1017,8 @@ ssh_userauth(
|
|||||||
|
|
||||||
/* Try RSA authentication for each identity. */
|
/* Try RSA authentication for each identity. */
|
||||||
for (i = 0; i < options.num_identity_files; i++)
|
for (i = 0; i < options.num_identity_files; i++)
|
||||||
if (options.identity_files_type[i] == KEY_RSA1 &&
|
if (options.identity_keys[i] != NULL &&
|
||||||
|
options.identity_keys[i]->type == KEY_RSA1 &&
|
||||||
try_rsa_authentication(options.identity_files[i]))
|
try_rsa_authentication(options.identity_files[i]))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
274
sshconnect2.c
274
sshconnect2.c
@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
RCSID("$OpenBSD: sshconnect2.c,v 1.50 2001/03/05 17:17:21 markus Exp $");
|
RCSID("$OpenBSD: sshconnect2.c,v 1.51 2001/03/08 21:42:33 markus Exp $");
|
||||||
|
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/md5.h>
|
#include <openssl/md5.h>
|
||||||
@ -467,6 +467,10 @@ struct Authctxt {
|
|||||||
AuthenticationConnection *agent;
|
AuthenticationConnection *agent;
|
||||||
Authmethod *method;
|
Authmethod *method;
|
||||||
int success;
|
int success;
|
||||||
|
char *authlist;
|
||||||
|
Key *last_key;
|
||||||
|
sign_cb_fn *last_key_sign;
|
||||||
|
int last_key_hint;
|
||||||
};
|
};
|
||||||
struct Authmethod {
|
struct Authmethod {
|
||||||
char *name; /* string to compare against server's list */
|
char *name; /* string to compare against server's list */
|
||||||
@ -480,12 +484,20 @@ void input_userauth_failure(int type, int plen, void *ctxt);
|
|||||||
void input_userauth_banner(int type, int plen, void *ctxt);
|
void input_userauth_banner(int type, int plen, void *ctxt);
|
||||||
void input_userauth_error(int type, int plen, void *ctxt);
|
void input_userauth_error(int type, int plen, void *ctxt);
|
||||||
void input_userauth_info_req(int type, int plen, void *ctxt);
|
void input_userauth_info_req(int type, int plen, void *ctxt);
|
||||||
|
void input_userauth_pk_ok(int type, int plen, void *ctxt);
|
||||||
|
|
||||||
int userauth_none(Authctxt *authctxt);
|
int userauth_none(Authctxt *authctxt);
|
||||||
int userauth_pubkey(Authctxt *authctxt);
|
int userauth_pubkey(Authctxt *authctxt);
|
||||||
int userauth_passwd(Authctxt *authctxt);
|
int userauth_passwd(Authctxt *authctxt);
|
||||||
int userauth_kbdint(Authctxt *authctxt);
|
int userauth_kbdint(Authctxt *authctxt);
|
||||||
|
|
||||||
|
void userauth(Authctxt *authctxt, char *authlist);
|
||||||
|
|
||||||
|
int
|
||||||
|
sign_and_send_pubkey(Authctxt *authctxt, Key *k,
|
||||||
|
sign_cb_fn *sign_callback);
|
||||||
|
void clear_auth_state(Authctxt *authctxt);
|
||||||
|
|
||||||
void authmethod_clear(void);
|
void authmethod_clear(void);
|
||||||
Authmethod *authmethod_get(char *authlist);
|
Authmethod *authmethod_get(char *authlist);
|
||||||
Authmethod *authmethod_lookup(const char *name);
|
Authmethod *authmethod_lookup(const char *name);
|
||||||
@ -546,6 +558,7 @@ ssh_userauth2(const char *server_user, char *host)
|
|||||||
authctxt.service = "ssh-connection"; /* service name */
|
authctxt.service = "ssh-connection"; /* service name */
|
||||||
authctxt.success = 0;
|
authctxt.success = 0;
|
||||||
authctxt.method = authmethod_lookup("none");
|
authctxt.method = authmethod_lookup("none");
|
||||||
|
authctxt.authlist = NULL;
|
||||||
if (authctxt.method == NULL)
|
if (authctxt.method == NULL)
|
||||||
fatal("ssh_userauth2: internal error: cannot send userauth none request");
|
fatal("ssh_userauth2: internal error: cannot send userauth none request");
|
||||||
authmethod_clear();
|
authmethod_clear();
|
||||||
@ -565,6 +578,30 @@ ssh_userauth2(const char *server_user, char *host)
|
|||||||
debug("ssh-userauth2 successful: method %s", authctxt.method->name);
|
debug("ssh-userauth2 successful: method %s", authctxt.method->name);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
userauth(Authctxt *authctxt, char *authlist)
|
||||||
|
{
|
||||||
|
if (authlist == NULL) {
|
||||||
|
authlist = authctxt->authlist;
|
||||||
|
} else {
|
||||||
|
if (authctxt->authlist)
|
||||||
|
xfree(authctxt->authlist);
|
||||||
|
authctxt->authlist = authlist;
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
Authmethod *method = authmethod_get(authlist);
|
||||||
|
if (method == NULL)
|
||||||
|
fatal("Permission denied (%s).", authlist);
|
||||||
|
authctxt->method = method;
|
||||||
|
if (method->userauth(authctxt) != 0) {
|
||||||
|
debug2("we sent a %s packet, wait for reply", method->name);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
debug2("we did not send a packet, disable method");
|
||||||
|
method->enabled = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void
|
||||||
input_userauth_error(int type, int plen, void *ctxt)
|
input_userauth_error(int type, int plen, void *ctxt)
|
||||||
{
|
{
|
||||||
fatal("input_userauth_error: bad message during authentication: "
|
fatal("input_userauth_error: bad message during authentication: "
|
||||||
@ -587,12 +624,14 @@ input_userauth_success(int type, int plen, void *ctxt)
|
|||||||
Authctxt *authctxt = ctxt;
|
Authctxt *authctxt = ctxt;
|
||||||
if (authctxt == NULL)
|
if (authctxt == NULL)
|
||||||
fatal("input_userauth_success: no authentication context");
|
fatal("input_userauth_success: no authentication context");
|
||||||
|
if (authctxt->authlist)
|
||||||
|
xfree(authctxt->authlist);
|
||||||
|
clear_auth_state(authctxt);
|
||||||
authctxt->success = 1; /* break out */
|
authctxt->success = 1; /* break out */
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
input_userauth_failure(int type, int plen, void *ctxt)
|
input_userauth_failure(int type, int plen, void *ctxt)
|
||||||
{
|
{
|
||||||
Authmethod *method = NULL;
|
|
||||||
Authctxt *authctxt = ctxt;
|
Authctxt *authctxt = ctxt;
|
||||||
char *authlist = NULL;
|
char *authlist = NULL;
|
||||||
int partial;
|
int partial;
|
||||||
@ -608,20 +647,74 @@ input_userauth_failure(int type, int plen, void *ctxt)
|
|||||||
log("Authenticated with partial success.");
|
log("Authenticated with partial success.");
|
||||||
debug("authentications that can continue: %s", authlist);
|
debug("authentications that can continue: %s", authlist);
|
||||||
|
|
||||||
for (;;) {
|
clear_auth_state(authctxt);
|
||||||
method = authmethod_get(authlist);
|
userauth(authctxt, authlist);
|
||||||
if (method == NULL)
|
}
|
||||||
fatal("Permission denied (%s).", authlist);
|
void
|
||||||
authctxt->method = method;
|
input_userauth_pk_ok(int type, int plen, void *ctxt)
|
||||||
if (method->userauth(authctxt) != 0) {
|
{
|
||||||
debug2("we sent a %s packet, wait for reply", method->name);
|
Authctxt *authctxt = ctxt;
|
||||||
break;
|
Key *key = NULL;
|
||||||
} else {
|
Buffer b;
|
||||||
debug2("we did not send a packet, disable method");
|
int alen, blen, pktype, sent = 0;
|
||||||
method->enabled = NULL;
|
char *pkalg, *pkblob;
|
||||||
}
|
|
||||||
|
if (authctxt == NULL)
|
||||||
|
fatal("input_userauth_pk_ok: no authentication context");
|
||||||
|
if (datafellows & SSH_BUG_PKOK) {
|
||||||
|
/* this is similar to SSH_BUG_PKAUTH */
|
||||||
|
debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
|
||||||
|
pkblob = packet_get_string(&blen);
|
||||||
|
buffer_init(&b);
|
||||||
|
buffer_append(&b, pkblob, blen);
|
||||||
|
pkalg = buffer_get_string(&b, &alen);
|
||||||
|
buffer_free(&b);
|
||||||
|
} else {
|
||||||
|
pkalg = packet_get_string(&alen);
|
||||||
|
pkblob = packet_get_string(&blen);
|
||||||
}
|
}
|
||||||
xfree(authlist);
|
packet_done();
|
||||||
|
|
||||||
|
debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
|
||||||
|
pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (authctxt->last_key == NULL ||
|
||||||
|
authctxt->last_key_sign == NULL) {
|
||||||
|
debug("no last key or no sign cb");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug2("last_key %s", key_fingerprint(authctxt->last_key));
|
||||||
|
if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
|
||||||
|
debug("unknown pkalg %s", pkalg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((key = key_from_blob(pkblob, blen)) == NULL) {
|
||||||
|
debug("no key from blob. pkalg %s", pkalg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug2("input_userauth_pk_ok: fp %s", key_fingerprint(key));
|
||||||
|
if (!key_equal(key, authctxt->last_key)) {
|
||||||
|
debug("key != last_key");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sent = sign_and_send_pubkey(authctxt, key,
|
||||||
|
authctxt->last_key_sign);
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if (key != NULL)
|
||||||
|
key_free(key);
|
||||||
|
xfree(pkalg);
|
||||||
|
xfree(pkblob);
|
||||||
|
|
||||||
|
/* unregister */
|
||||||
|
clear_auth_state(authctxt);
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
|
||||||
|
|
||||||
|
/* try another method if we did not send a packet*/
|
||||||
|
if (sent == 0)
|
||||||
|
userauth(authctxt, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -633,7 +726,6 @@ userauth_none(Authctxt *authctxt)
|
|||||||
packet_put_cstring(authctxt->service);
|
packet_put_cstring(authctxt->service);
|
||||||
packet_put_cstring(authctxt->method->name);
|
packet_put_cstring(authctxt->method->name);
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,10 +755,22 @@ userauth_passwd(Authctxt *authctxt)
|
|||||||
xfree(password);
|
xfree(password);
|
||||||
packet_inject_ignore(64);
|
packet_inject_ignore(64);
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_auth_state(Authctxt *authctxt)
|
||||||
|
{
|
||||||
|
/* XXX clear authentication state */
|
||||||
|
if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
|
||||||
|
debug3("clear_auth_state: key_free %p", authctxt->last_key);
|
||||||
|
key_free(authctxt->last_key);
|
||||||
|
}
|
||||||
|
authctxt->last_key = NULL;
|
||||||
|
authctxt->last_key_hint = -2;
|
||||||
|
authctxt->last_key_sign = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
||||||
{
|
{
|
||||||
@ -678,6 +782,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
|||||||
int have_sig = 1;
|
int have_sig = 1;
|
||||||
|
|
||||||
debug3("sign_and_send_pubkey");
|
debug3("sign_and_send_pubkey");
|
||||||
|
|
||||||
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
||||||
/* we cannot handle this key */
|
/* we cannot handle this key */
|
||||||
debug3("sign_and_send_pubkey: cannot handle key");
|
debug3("sign_and_send_pubkey: cannot handle key");
|
||||||
@ -708,7 +813,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
|||||||
buffer_put_string(&b, blob, bloblen);
|
buffer_put_string(&b, blob, bloblen);
|
||||||
|
|
||||||
/* generate signature */
|
/* generate signature */
|
||||||
ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
|
ret = (*sign_callback)(authctxt, k, &signature, &slen,
|
||||||
|
buffer_ptr(&b), buffer_len(&b));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
xfree(blob);
|
xfree(blob);
|
||||||
buffer_free(&b);
|
buffer_free(&b);
|
||||||
@ -720,6 +826,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
|||||||
if (datafellows & SSH_BUG_PKSERVICE) {
|
if (datafellows & SSH_BUG_PKSERVICE) {
|
||||||
buffer_clear(&b);
|
buffer_clear(&b);
|
||||||
buffer_append(&b, session_id2, session_id2_len);
|
buffer_append(&b, session_id2, session_id2_len);
|
||||||
|
skip = session_id2_len;
|
||||||
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
|
||||||
buffer_put_cstring(&b, authctxt->server_user);
|
buffer_put_cstring(&b, authctxt->server_user);
|
||||||
buffer_put_cstring(&b, authctxt->service);
|
buffer_put_cstring(&b, authctxt->service);
|
||||||
@ -730,6 +837,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
|||||||
buffer_put_string(&b, blob, bloblen);
|
buffer_put_string(&b, blob, bloblen);
|
||||||
}
|
}
|
||||||
xfree(blob);
|
xfree(blob);
|
||||||
|
|
||||||
/* append signature */
|
/* append signature */
|
||||||
buffer_put_string(&b, signature, slen);
|
buffer_put_string(&b, signature, slen);
|
||||||
xfree(signature);
|
xfree(signature);
|
||||||
@ -743,76 +851,113 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
|
|||||||
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
packet_put_raw(buffer_ptr(&b), buffer_len(&b));
|
packet_put_raw(buffer_ptr(&b), buffer_len(&b));
|
||||||
buffer_free(&b);
|
buffer_free(&b);
|
||||||
|
|
||||||
/* send */
|
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sign callback */
|
|
||||||
int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
|
||||||
u_char *data, int datalen)
|
|
||||||
{
|
|
||||||
return key_sign(key, sigp, lenp, data, datalen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
userauth_pubkey_identity(Authctxt *authctxt, char *filename)
|
send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
|
||||||
|
int hint)
|
||||||
{
|
{
|
||||||
Key *k;
|
u_char *blob;
|
||||||
int i, ret, try_next, success = 0;
|
int bloblen, have_sig = 0;
|
||||||
struct stat st;
|
|
||||||
char *passphrase;
|
|
||||||
char prompt[300];
|
|
||||||
|
|
||||||
if (stat(filename, &st) != 0) {
|
debug3("send_pubkey_test");
|
||||||
debug("key does not exist: %s", filename);
|
|
||||||
|
if (key_to_blob(k, &blob, &bloblen) == 0) {
|
||||||
|
/* we cannot handle this key */
|
||||||
|
debug3("send_pubkey_test: cannot handle key");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
debug("try pubkey: %s", filename);
|
/* register callback for USERAUTH_PK_OK message */
|
||||||
|
authctxt->last_key_sign = sign_callback;
|
||||||
|
authctxt->last_key_hint = hint;
|
||||||
|
authctxt->last_key = k;
|
||||||
|
dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
|
||||||
|
|
||||||
k = key_new(KEY_UNSPEC);
|
packet_start(SSH2_MSG_USERAUTH_REQUEST);
|
||||||
if (!load_private_key(filename, "", k, NULL)) {
|
packet_put_cstring(authctxt->server_user);
|
||||||
|
packet_put_cstring(authctxt->service);
|
||||||
|
packet_put_cstring(authctxt->method->name);
|
||||||
|
packet_put_char(have_sig);
|
||||||
|
if (!(datafellows & SSH_BUG_PKAUTH))
|
||||||
|
packet_put_cstring(key_ssh_name(k));
|
||||||
|
packet_put_string(blob, bloblen);
|
||||||
|
xfree(blob);
|
||||||
|
packet_send();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Key *
|
||||||
|
load_identity_file(char *filename)
|
||||||
|
{
|
||||||
|
Key *private;
|
||||||
|
char prompt[300], *passphrase;
|
||||||
|
int success = 0, quit, i;
|
||||||
|
|
||||||
|
private = key_new(KEY_UNSPEC);
|
||||||
|
if (!load_private_key(filename, "", private, NULL)) {
|
||||||
if (options.batch_mode) {
|
if (options.batch_mode) {
|
||||||
key_free(k);
|
key_free(private);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
snprintf(prompt, sizeof prompt,
|
snprintf(prompt, sizeof prompt,
|
||||||
"Enter passphrase for key '%.100s': ", filename);
|
"Enter passphrase for key '%.100s': ", filename);
|
||||||
for (i = 0; i < options.number_of_password_prompts; i++) {
|
for (i = 0; i < options.number_of_password_prompts; i++) {
|
||||||
passphrase = read_passphrase(prompt, 0);
|
passphrase = read_passphrase(prompt, 0);
|
||||||
if (strcmp(passphrase, "") != 0) {
|
if (strcmp(passphrase, "") != 0) {
|
||||||
success = load_private_key(filename, passphrase, k, NULL);
|
success = load_private_key(filename,
|
||||||
try_next = 0;
|
passphrase, private, NULL);
|
||||||
|
quit = 0;
|
||||||
} else {
|
} else {
|
||||||
debug2("no passphrase given, try next key");
|
debug2("no passphrase given, try next key");
|
||||||
try_next = 1;
|
quit = 1;
|
||||||
}
|
}
|
||||||
memset(passphrase, 0, strlen(passphrase));
|
memset(passphrase, 0, strlen(passphrase));
|
||||||
xfree(passphrase);
|
xfree(passphrase);
|
||||||
if (success || try_next)
|
if (success || quit)
|
||||||
break;
|
break;
|
||||||
debug2("bad passphrase given, try again...");
|
debug2("bad passphrase given, try again...");
|
||||||
}
|
}
|
||||||
if (!success) {
|
if (!success) {
|
||||||
key_free(k);
|
key_free(private);
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
|
return private;
|
||||||
key_free(k);
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||||
|
u_char *data, int datalen)
|
||||||
|
{
|
||||||
|
Key *private;
|
||||||
|
int idx, ret;
|
||||||
|
|
||||||
|
idx = authctxt->last_key_hint;
|
||||||
|
if (idx < 0)
|
||||||
|
return -1;
|
||||||
|
private = load_identity_file(options.identity_files[idx]);
|
||||||
|
if (private == NULL)
|
||||||
|
return -1;
|
||||||
|
ret = key_sign(private, sigp, lenp, data, datalen);
|
||||||
|
key_free(private);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sign callback */
|
|
||||||
int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||||
u_char *data, int datalen)
|
u_char *data, int datalen)
|
||||||
{
|
{
|
||||||
return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
|
return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
|
||||||
|
u_char *data, int datalen)
|
||||||
|
{
|
||||||
|
return key_sign(key, sigp, lenp, data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
userauth_pubkey_agent(Authctxt *authctxt)
|
userauth_pubkey_agent(Authctxt *authctxt)
|
||||||
{
|
{
|
||||||
@ -830,10 +975,11 @@ userauth_pubkey_agent(Authctxt *authctxt)
|
|||||||
if (k == NULL) {
|
if (k == NULL) {
|
||||||
debug2("userauth_pubkey_agent: no more keys");
|
debug2("userauth_pubkey_agent: no more keys");
|
||||||
} else {
|
} else {
|
||||||
debug("userauth_pubkey_agent: trying agent key %s", comment);
|
debug("userauth_pubkey_agent: testing agent key %s", comment);
|
||||||
xfree(comment);
|
xfree(comment);
|
||||||
ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
|
ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
|
||||||
key_free(k);
|
if (ret == 0)
|
||||||
|
key_free(k);
|
||||||
}
|
}
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
debug2("userauth_pubkey_agent: no message sent");
|
debug2("userauth_pubkey_agent: no message sent");
|
||||||
@ -845,6 +991,8 @@ userauth_pubkey(Authctxt *authctxt)
|
|||||||
{
|
{
|
||||||
static int idx = 0;
|
static int idx = 0;
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
Key *key;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
if (authctxt->agent != NULL) {
|
if (authctxt->agent != NULL) {
|
||||||
do {
|
do {
|
||||||
@ -852,9 +1000,21 @@ userauth_pubkey(Authctxt *authctxt)
|
|||||||
} while(!sent && authctxt->agent->howmany > 0);
|
} while(!sent && authctxt->agent->howmany > 0);
|
||||||
}
|
}
|
||||||
while (!sent && idx < options.num_identity_files) {
|
while (!sent && idx < options.num_identity_files) {
|
||||||
if (options.identity_files_type[idx] != KEY_RSA1)
|
key = options.identity_keys[idx];
|
||||||
sent = userauth_pubkey_identity(authctxt,
|
filename = options.identity_files[idx];
|
||||||
options.identity_files[idx]);
|
if (key == NULL) {
|
||||||
|
debug("try privkey: %s", filename);
|
||||||
|
key = load_identity_file(filename);
|
||||||
|
if (key != NULL) {
|
||||||
|
sent = sign_and_send_pubkey(authctxt, key,
|
||||||
|
key_sign_cb);
|
||||||
|
key_free(key);
|
||||||
|
}
|
||||||
|
} else if (key->type != KEY_RSA1) {
|
||||||
|
debug("try pubkey: %s", filename);
|
||||||
|
sent = send_pubkey_test(authctxt, key,
|
||||||
|
identity_sign_cb, idx);
|
||||||
|
}
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
return sent;
|
return sent;
|
||||||
@ -880,7 +1040,6 @@ userauth_kbdint(Authctxt *authctxt)
|
|||||||
packet_put_cstring(options.kbd_interactive_devices ?
|
packet_put_cstring(options.kbd_interactive_devices ?
|
||||||
options.kbd_interactive_devices : "");
|
options.kbd_interactive_devices : "");
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
|
||||||
|
|
||||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
|
dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
|
||||||
return 1;
|
return 1;
|
||||||
@ -938,7 +1097,6 @@ input_userauth_info_req(int type, int plen, void *ctxt)
|
|||||||
|
|
||||||
packet_inject_ignore(64);
|
packet_inject_ignore(64);
|
||||||
packet_send();
|
packet_send();
|
||||||
packet_write_wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find auth method */
|
/* find auth method */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user