version 1.179, 2018/02/05 05:37:46 |
version 1.180, 2018/03/03 03:15:51 |
|
|
extern Buffer auth_debug; |
extern Buffer auth_debug; |
extern int auth_debug_init; |
extern int auth_debug_init; |
extern Buffer loginmsg; |
extern Buffer loginmsg; |
|
extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ |
|
|
/* State exported from the child */ |
/* State exported from the child */ |
static struct sshbuf *child_state; |
static struct sshbuf *child_state; |
|
|
static u_char *key_blob = NULL; |
static u_char *key_blob = NULL; |
static u_int key_bloblen = 0; |
static u_int key_bloblen = 0; |
static int key_blobtype = MM_NOKEY; |
static int key_blobtype = MM_NOKEY; |
|
static struct sshauthopt *key_opts = NULL; |
static char *hostbased_cuser = NULL; |
static char *hostbased_cuser = NULL; |
static char *hostbased_chost = NULL; |
static char *hostbased_chost = NULL; |
static char *auth_method = "unknown"; |
static char *auth_method = "unknown"; |
|
|
struct mon_table *mon_dispatch; |
struct mon_table *mon_dispatch; |
|
|
/* Specifies if a certain message is allowed at the moment */ |
/* Specifies if a certain message is allowed at the moment */ |
|
|
static void |
static void |
monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) |
monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) |
{ |
{ |
|
|
|
|
authctxt = _authctxt; |
authctxt = _authctxt; |
memset(authctxt, 0, sizeof(*authctxt)); |
memset(authctxt, 0, sizeof(*authctxt)); |
|
ssh->authctxt = authctxt; |
|
|
mon_dispatch = mon_dispatch_proto20; |
mon_dispatch = mon_dispatch_proto20; |
/* Permit requests for moduli and signatures */ |
/* Permit requests for moduli and signatures */ |
|
|
fatal("%s: unexpected authentication from %d", |
fatal("%s: unexpected authentication from %d", |
__func__, ent->type); |
__func__, ent->type); |
if (authctxt->pw->pw_uid == 0 && |
if (authctxt->pw->pw_uid == 0 && |
!auth_root_allowed(auth_method)) |
!auth_root_allowed(ssh, auth_method)) |
authenticated = 0; |
authenticated = 0; |
} |
} |
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { |
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) { |
|
|
|
|
debug("%s: %s has been authenticated by privileged process", |
debug("%s: %s has been authenticated by privileged process", |
__func__, authctxt->user); |
__func__, authctxt->user); |
|
ssh->authctxt = NULL; |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
|
|
mm_get_keystate(pmonitor); |
mm_get_keystate(pmonitor); |
|
|
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); |
|
|
if (!no_pty_flag) { |
if (auth_opts->permit_pty_flag) { |
monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); |
monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); |
} |
} |
|
|
free(key_blob); |
free(key_blob); |
free(hostbased_cuser); |
free(hostbased_cuser); |
free(hostbased_chost); |
free(hostbased_chost); |
|
sshauthopt_free(key_opts); |
key_blob = NULL; |
key_blob = NULL; |
key_bloblen = 0; |
key_bloblen = 0; |
key_blobtype = MM_NOKEY; |
key_blobtype = MM_NOKEY; |
|
key_opts = NULL; |
hostbased_cuser = NULL; |
hostbased_cuser = NULL; |
hostbased_chost = NULL; |
hostbased_chost = NULL; |
} |
} |
|
|
int |
int |
mm_answer_authpassword(int sock, Buffer *m) |
mm_answer_authpassword(int sock, Buffer *m) |
{ |
{ |
|
struct ssh *ssh = active_state; /* XXX */ |
static int call_count; |
static int call_count; |
char *passwd; |
char *passwd; |
int authenticated; |
int authenticated; |
|
|
passwd = buffer_get_string(m, &plen); |
passwd = buffer_get_string(m, &plen); |
/* Only authenticate if the context is valid */ |
/* Only authenticate if the context is valid */ |
authenticated = options.password_authentication && |
authenticated = options.password_authentication && |
auth_password(authctxt, passwd); |
auth_password(ssh, passwd); |
explicit_bzero(passwd, strlen(passwd)); |
explicit_bzero(passwd, strlen(passwd)); |
free(passwd); |
free(passwd); |
|
|
|
|
int |
int |
mm_answer_keyallowed(int sock, Buffer *m) |
mm_answer_keyallowed(int sock, Buffer *m) |
{ |
{ |
|
struct ssh *ssh = active_state; /* XXX */ |
struct sshkey *key; |
struct sshkey *key; |
char *cuser, *chost; |
char *cuser, *chost; |
u_char *blob; |
u_char *blob; |
u_int bloblen, pubkey_auth_attempt; |
u_int bloblen, pubkey_auth_attempt; |
enum mm_keytype type = 0; |
enum mm_keytype type = 0; |
int allowed = 0; |
int r, allowed = 0; |
|
struct sshauthopt *opts = NULL; |
|
|
debug3("%s entering", __func__); |
debug3("%s entering", __func__); |
|
|
type = buffer_get_int(m); |
type = buffer_get_int(m); |
cuser = buffer_get_string(m, NULL); |
cuser = buffer_get_string(m, NULL); |
chost = buffer_get_string(m, NULL); |
chost = buffer_get_string(m, NULL); |
|
|
|
|
switch (type) { |
switch (type) { |
case MM_USERKEY: |
case MM_USERKEY: |
allowed = options.pubkey_authentication && |
|
!auth2_key_already_used(authctxt, key) && |
|
match_pattern_list(sshkey_ssh_name(key), |
|
options.pubkey_key_types, 0) == 1 && |
|
user_key_allowed(authctxt->pw, key, |
|
pubkey_auth_attempt); |
|
auth_method = "publickey"; |
auth_method = "publickey"; |
if (options.pubkey_authentication && |
if (!options.pubkey_authentication) |
(!pubkey_auth_attempt || allowed != 1)) |
break; |
auth_clear_options(); |
if (auth2_key_already_used(authctxt, key)) |
|
break; |
|
if (match_pattern_list(sshkey_ssh_name(key), |
|
options.pubkey_key_types, 0) != 1) |
|
break; |
|
allowed = user_key_allowed(ssh, authctxt->pw, key, |
|
pubkey_auth_attempt, &opts); |
break; |
break; |
case MM_HOSTKEY: |
case MM_HOSTKEY: |
allowed = options.hostbased_authentication && |
auth_method = "hostbased"; |
!auth2_key_already_used(authctxt, key) && |
if (!options.hostbased_authentication) |
match_pattern_list(sshkey_ssh_name(key), |
break; |
options.hostbased_key_types, 0) == 1 && |
if (auth2_key_already_used(authctxt, key)) |
hostbased_key_allowed(authctxt->pw, |
break; |
|
if (match_pattern_list(sshkey_ssh_name(key), |
|
options.hostbased_key_types, 0) != 1) |
|
break; |
|
allowed = hostbased_key_allowed(authctxt->pw, |
cuser, chost, key); |
cuser, chost, key); |
auth2_record_info(authctxt, |
auth2_record_info(authctxt, |
"client user \"%.100s\", client host \"%.100s\"", |
"client user \"%.100s\", client host \"%.100s\"", |
cuser, chost); |
cuser, chost); |
auth_method = "hostbased"; |
|
break; |
break; |
default: |
default: |
fatal("%s: unknown key type %d", __func__, type); |
fatal("%s: unknown key type %d", __func__, type); |
|
|
} |
} |
} |
} |
|
|
debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed"); |
debug3("%s: %s authentication%s: %s key is %s", __func__, |
|
auth_method, pubkey_auth_attempt ? "" : " test", |
|
(key == NULL || !authctxt->valid) ? "invalid" : sshkey_type(key), |
|
allowed ? "allowed" : "not allowed"); |
|
|
auth2_record_key(authctxt, 0, key); |
auth2_record_key(authctxt, 0, key); |
sshkey_free(key); |
sshkey_free(key); |
|
|
key_blob = blob; |
key_blob = blob; |
key_bloblen = bloblen; |
key_bloblen = bloblen; |
key_blobtype = type; |
key_blobtype = type; |
|
key_opts = opts; |
hostbased_cuser = cuser; |
hostbased_cuser = cuser; |
hostbased_chost = chost; |
hostbased_chost = chost; |
} else { |
} else { |
|
|
|
|
buffer_clear(m); |
buffer_clear(m); |
buffer_put_int(m, allowed); |
buffer_put_int(m, allowed); |
buffer_put_int(m, forced_command != NULL); |
if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) |
|
fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); |
mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
|
|
|
if (!allowed) |
|
sshauthopt_free(opts); |
|
|
return (0); |
return (0); |
} |
} |
|
|
|
|
int |
int |
mm_answer_keyverify(int sock, struct sshbuf *m) |
mm_answer_keyverify(int sock, struct sshbuf *m) |
{ |
{ |
|
struct ssh *ssh = active_state; /* XXX */ |
struct sshkey *key; |
struct sshkey *key; |
u_char *signature, *data, *blob; |
u_char *signature, *data, *blob; |
char *sigalg; |
char *sigalg; |
|
|
free(data); |
free(data); |
free(sigalg); |
free(sigalg); |
|
|
|
if (key_blobtype == MM_USERKEY) |
|
auth_activate_options(ssh, key_opts); |
monitor_reset_key_state(); |
monitor_reset_key_state(); |
|
|
sshkey_free(key); |
sshkey_free(key); |