version 1.301, 2019/01/21 10:38:54 |
version 1.302, 2019/02/11 09:44:42 |
|
|
struct cauthmethod *method; |
struct cauthmethod *method; |
sig_atomic_t success; |
sig_atomic_t success; |
char *authlist; |
char *authlist; |
|
#ifdef GSSAPI |
|
/* gssapi */ |
|
gss_OID_set gss_supported_mechs; |
|
u_int mech_tried; |
|
#endif |
/* pubkey */ |
/* pubkey */ |
struct idlist keys; |
struct idlist keys; |
int agent_fd; |
int agent_fd; |
|
|
int *batch_flag; /* flag in option struct that disables method */ |
int *batch_flag; /* flag in option struct that disables method */ |
}; |
}; |
|
|
int input_userauth_service_accept(int, u_int32_t, struct ssh *); |
static int input_userauth_service_accept(int, u_int32_t, struct ssh *); |
int input_userauth_ext_info(int, u_int32_t, struct ssh *); |
static int input_userauth_ext_info(int, u_int32_t, struct ssh *); |
int input_userauth_success(int, u_int32_t, struct ssh *); |
static int input_userauth_success(int, u_int32_t, struct ssh *); |
int input_userauth_success_unexpected(int, u_int32_t, struct ssh *); |
static int input_userauth_failure(int, u_int32_t, struct ssh *); |
int input_userauth_failure(int, u_int32_t, struct ssh *); |
static int input_userauth_banner(int, u_int32_t, struct ssh *); |
int input_userauth_banner(int, u_int32_t, struct ssh *); |
static int input_userauth_error(int, u_int32_t, struct ssh *); |
int input_userauth_error(int, u_int32_t, struct ssh *); |
static int input_userauth_info_req(int, u_int32_t, struct ssh *); |
int input_userauth_info_req(int, u_int32_t, struct ssh *); |
static int input_userauth_pk_ok(int, u_int32_t, struct ssh *); |
int input_userauth_pk_ok(int, u_int32_t, struct ssh *); |
static int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); |
int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); |
|
|
|
int userauth_none(struct ssh *); |
static int userauth_none(struct ssh *); |
int userauth_pubkey(struct ssh *); |
static int userauth_pubkey(struct ssh *); |
int userauth_passwd(struct ssh *); |
static void userauth_pubkey_cleanup(struct ssh *); |
int userauth_kbdint(struct ssh *); |
static int userauth_passwd(struct ssh *); |
int userauth_hostbased(struct ssh *); |
static int userauth_kbdint(struct ssh *); |
|
static int userauth_hostbased(struct ssh *); |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int userauth_gssapi(struct ssh *); |
static int userauth_gssapi(struct ssh *); |
int input_gssapi_response(int type, u_int32_t, struct ssh *); |
static void userauth_gssapi_cleanup(struct ssh *); |
int input_gssapi_token(int type, u_int32_t, struct ssh *); |
static int input_gssapi_response(int type, u_int32_t, struct ssh *); |
int input_gssapi_hash(int type, u_int32_t, struct ssh *); |
static int input_gssapi_token(int type, u_int32_t, struct ssh *); |
int input_gssapi_error(int, u_int32_t, struct ssh *); |
static int input_gssapi_error(int, u_int32_t, struct ssh *); |
int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
static int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
#endif |
#endif |
|
|
void userauth(struct ssh *, char *); |
void userauth(struct ssh *, char *); |
|
|
static int sign_and_send_pubkey(struct ssh *ssh, Identity *); |
static int sign_and_send_pubkey(struct ssh *ssh, Identity *); |
static void pubkey_prepare(Authctxt *); |
static void pubkey_prepare(Authctxt *); |
static void pubkey_cleanup(Authctxt *); |
|
static void pubkey_reset(Authctxt *); |
static void pubkey_reset(Authctxt *); |
static struct sshkey *load_identity_file(Identity *); |
static struct sshkey *load_identity_file(Identity *); |
|
|
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
{"gssapi-with-mic", |
{"gssapi-with-mic", |
userauth_gssapi, |
userauth_gssapi, |
NULL, |
userauth_gssapi_cleanup, |
&options.gss_authentication, |
&options.gss_authentication, |
NULL}, |
NULL}, |
#endif |
#endif |
|
|
NULL}, |
NULL}, |
{"publickey", |
{"publickey", |
userauth_pubkey, |
userauth_pubkey, |
NULL, |
userauth_pubkey_cleanup, |
&options.pubkey_authentication, |
&options.pubkey_authentication, |
NULL}, |
NULL}, |
{"keyboard-interactive", |
{"keyboard-interactive", |
|
|
authctxt.info_req_seen = 0; |
authctxt.info_req_seen = 0; |
authctxt.attempt_kbdint = 0; |
authctxt.attempt_kbdint = 0; |
authctxt.attempt_passwd = 0; |
authctxt.attempt_passwd = 0; |
|
#if GSSAPI |
|
authctxt.gss_supported_mechs = NULL; |
|
authctxt.mech_tried = 0; |
|
#endif |
authctxt.agent_fd = -1; |
authctxt.agent_fd = -1; |
pubkey_prepare(&authctxt); |
pubkey_prepare(&authctxt); |
if (authctxt.method == NULL) { |
if (authctxt.method == NULL) { |
|
|
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */ |
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */ |
ssh->authctxt = NULL; |
ssh->authctxt = NULL; |
|
|
pubkey_cleanup(&authctxt); |
|
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); |
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); |
|
|
if (!authctxt.success) |
if (!authctxt.success) |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
int r; |
int r; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) |
input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh) |
{ |
{ |
return kex_input_ext_info(type, seqnr, ssh); |
return kex_input_ext_info(type, seqnr, ssh); |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
fatal("%s: bad message during authentication: type %d", __func__, type); |
fatal("%s: bad message during authentication: type %d", __func__, type); |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
char *msg = NULL; |
char *msg = NULL; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_success(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
return 0; |
return 0; |
} |
} |
|
|
int |
#if 0 |
|
static int |
input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_success_unexpected(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
authctxt->method->name); |
authctxt->method->name); |
return 0; |
return 0; |
} |
} |
|
#endif |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_failure(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int |
static int |
userauth_gssapi(struct ssh *ssh) |
userauth_gssapi(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Gssctxt *gssctxt = NULL; |
Gssctxt *gssctxt = NULL; |
static gss_OID_set gss_supported = NULL; |
|
static u_int mech = 0; |
|
OM_uint32 min; |
OM_uint32 min; |
int r, ok = 0; |
int r, ok = 0; |
|
gss_OID mech = NULL; |
|
|
/* Try one GSSAPI method at a time, rather than sending them all at |
/* Try one GSSAPI method at a time, rather than sending them all at |
* once. */ |
* once. */ |
|
|
if (gss_supported == NULL) |
if (authctxt->gss_supported_mechs == NULL) |
gss_indicate_mechs(&min, &gss_supported); |
gss_indicate_mechs(&min, &authctxt->gss_supported_mechs); |
|
|
/* Check to see if the mechanism is usable before we offer it */ |
/* Check to see whether the mechanism is usable before we offer it */ |
while (mech < gss_supported->count && !ok) { |
while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && |
|
!ok) { |
|
mech = &authctxt->gss_supported_mechs-> |
|
elements[authctxt->mech_tried]; |
/* My DER encoding requires length<128 */ |
/* My DER encoding requires length<128 */ |
if (gss_supported->elements[mech].length < 128 && |
if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, |
ssh_gssapi_check_mechanism(&gssctxt, |
mech, authctxt->host)) { |
&gss_supported->elements[mech], authctxt->host)) { |
|
ok = 1; /* Mechanism works */ |
ok = 1; /* Mechanism works */ |
} else { |
} else { |
mech++; |
authctxt->mech_tried++; |
} |
} |
} |
} |
|
|
if (!ok) |
if (!ok || mech == NULL) |
return 0; |
return 0; |
|
|
authctxt->methoddata=(void *)gssctxt; |
authctxt->methoddata=(void *)gssctxt; |
|
|
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || |
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
(r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || |
(r = sshpkt_put_u32(ssh, 1)) != 0 || |
(r = sshpkt_put_u32(ssh, 1)) != 0 || |
(r = sshpkt_put_u32(ssh, |
(r = sshpkt_put_u32(ssh, (mech->length) + 2)) != 0 || |
(gss_supported->elements[mech].length) + 2)) != 0 || |
|
(r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || |
(r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 || |
(r = sshpkt_put_u8(ssh, |
(r = sshpkt_put_u8(ssh, mech->length)) != 0 || |
gss_supported->elements[mech].length)) != 0 || |
(r = sshpkt_put(ssh, mech->elements, mech->length)) != 0 || |
(r = sshpkt_put(ssh, |
|
gss_supported->elements[mech].elements, |
|
gss_supported->elements[mech].length)) != 0 || |
|
(r = sshpkt_send(ssh)) != 0) |
(r = sshpkt_send(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal("%s: %s", __func__, ssh_err(r)); |
|
|
|
|
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); |
|
|
mech++; /* Move along to next candidate */ |
authctxt->mech_tried++; /* Move along to next candidate */ |
|
|
return 1; |
return 1; |
} |
} |
|
|
|
static void |
|
userauth_gssapi_cleanup(struct ssh *ssh) |
|
{ |
|
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
Gssctxt *gssctxt = (Gssctxt *)authctxt->methoddata; |
|
|
|
ssh_gssapi_delete_ctx(&gssctxt); |
|
authctxt->methoddata = NULL; |
|
|
|
free(authctxt->gss_supported_mechs); |
|
authctxt->gss_supported_mechs = NULL; |
|
} |
|
|
static OM_uint32 |
static OM_uint32 |
process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) |
process_gssapi_token(struct ssh *ssh, gss_buffer_t recv_tok) |
{ |
{ |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) |
input_gssapi_response(int type, u_int32_t plen, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) |
input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) |
input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) |
input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) |
{ |
{ |
char *msg = NULL; |
char *msg = NULL; |
|
|
} |
} |
#endif /* GSSAPI */ |
#endif /* GSSAPI */ |
|
|
int |
static int |
userauth_none(struct ssh *ssh) |
userauth_none(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
return 1; |
return 1; |
} |
} |
|
|
int |
static int |
userauth_passwd(struct ssh *ssh) |
userauth_passwd(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST |
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST |
*/ |
*/ |
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
static int |
input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) |
input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
} |
} |
|
|
static void |
static void |
pubkey_cleanup(Authctxt *authctxt) |
userauth_pubkey_cleanup(struct ssh *ssh) |
{ |
{ |
|
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
Identity *id; |
Identity *id; |
|
|
if (authctxt->agent_fd != -1) { |
if (authctxt->agent_fd != -1) { |
|
|
return 1; |
return 1; |
} |
} |
|
|
int |
static int |
userauth_pubkey(struct ssh *ssh) |
userauth_pubkey(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
/* |
/* |
* Send userauth request message specifying keyboard-interactive method. |
* Send userauth request message specifying keyboard-interactive method. |
*/ |
*/ |
int |
static int |
userauth_kbdint(struct ssh *ssh) |
userauth_kbdint(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
/* |
/* |
* parse INFO_REQUEST, prompt user and send INFO_RESPONSE |
* parse INFO_REQUEST, prompt user and send INFO_RESPONSE |
*/ |
*/ |
int |
static int |
input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
return 0; |
return 0; |
} |
} |
|
|
int |
static int |
userauth_hostbased(struct ssh *ssh) |
userauth_hostbased(struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |