version 1.152, 2019/01/19 21:31:32 |
version 1.153, 2019/01/19 21:38:24 |
|
|
#include "ssherr.h" |
#include "ssherr.h" |
#include "digest.h" |
#include "digest.h" |
|
|
#include "opacket.h" /* XXX */ |
|
extern struct ssh *active_state; /* XXX */ |
|
|
|
/* import */ |
/* import */ |
extern ServerOptions options; |
extern ServerOptions options; |
extern u_char *session_id2; |
extern u_char *session_id2; |
|
|
} |
} |
|
|
static void |
static void |
userauth_banner(void) |
userauth_banner(struct ssh *ssh) |
{ |
{ |
char *banner = NULL; |
char *banner = NULL; |
|
int r; |
|
|
if (options.banner == NULL) |
if (options.banner == NULL) |
return; |
return; |
|
|
if ((banner = PRIVSEP(auth2_read_banner())) == NULL) |
if ((banner = PRIVSEP(auth2_read_banner())) == NULL) |
goto done; |
goto done; |
|
|
packet_start(SSH2_MSG_USERAUTH_BANNER); |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 || |
packet_put_cstring(banner); |
(r = sshpkt_put_cstring(ssh, banner)) != 0 || |
packet_put_cstring(""); /* language, unused */ |
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language, unused */ |
packet_send(); |
(r = sshpkt_send(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
debug("userauth_banner: sent"); |
debug("userauth_banner: sent"); |
done: |
done: |
free(banner); |
free(banner); |
|
|
* loop until authctxt->success == TRUE |
* loop until authctxt->success == TRUE |
*/ |
*/ |
void |
void |
do_authentication2(Authctxt *authctxt) |
do_authentication2(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = ssh->authctxt; |
ssh->authctxt = authctxt; /* XXX move to caller */ |
|
ssh_dispatch_init(ssh, &dispatch_protocol_error); |
ssh_dispatch_init(ssh, &dispatch_protocol_error); |
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); |
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_REQUEST, &input_service_request); |
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); |
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt->success); |
|
|
input_service_request(int type, u_int32_t seq, struct ssh *ssh) |
input_service_request(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
u_int len; |
char *service = NULL; |
int acceptit = 0; |
int r, acceptit = 0; |
char *service = packet_get_cstring(&len); |
|
packet_check_eom(); |
|
|
|
|
if ((r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || |
|
(r = sshpkt_get_end(ssh)) != 0) |
|
goto out; |
|
|
if (authctxt == NULL) |
if (authctxt == NULL) |
fatal("input_service_request: no authctxt"); |
fatal("input_service_request: no authctxt"); |
|
|
|
|
if (!authctxt->success) { |
if (!authctxt->success) { |
acceptit = 1; |
acceptit = 1; |
/* now we can handle user-auth requests */ |
/* now we can handle user-auth requests */ |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, |
|
&input_userauth_request); |
} |
} |
} |
} |
/* XXX all other service requests are denied */ |
/* XXX all other service requests are denied */ |
|
|
if (acceptit) { |
if (acceptit) { |
packet_start(SSH2_MSG_SERVICE_ACCEPT); |
if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_ACCEPT)) != 0 || |
packet_put_cstring(service); |
(r = sshpkt_put_cstring(ssh, service)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0 || |
packet_write_wait(); |
(r = ssh_packet_write_wait(ssh)) != 0) |
|
goto out; |
} else { |
} else { |
debug("bad service request %s", service); |
debug("bad service request %s", service); |
packet_disconnect("bad service request %s", service); |
ssh_packet_disconnect(ssh, "bad service request %s", service); |
} |
} |
|
r = 0; |
|
out: |
free(service); |
free(service); |
return 0; |
return 0; |
} |
} |
|
|
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
Authmethod *m = NULL; |
Authmethod *m = NULL; |
char *user, *service, *method, *style = NULL; |
char *user = NULL, *service = NULL, *method = NULL, *style = NULL; |
int authenticated = 0; |
int r, authenticated = 0; |
double tstart = monotime_double(); |
double tstart = monotime_double(); |
|
|
if (authctxt == NULL) |
if (authctxt == NULL) |
fatal("input_userauth_request: no authctxt"); |
fatal("input_userauth_request: no authctxt"); |
|
|
user = packet_get_cstring(NULL); |
if ((r = sshpkt_get_cstring(ssh, &user, NULL)) != 0 || |
service = packet_get_cstring(NULL); |
(r = sshpkt_get_cstring(ssh, &service, NULL)) != 0 || |
method = packet_get_cstring(NULL); |
(r = sshpkt_get_cstring(ssh, &method, NULL)) != 0) |
|
goto out; |
debug("userauth-request for user %s service %s method %s", user, service, method); |
debug("userauth-request for user %s service %s method %s", user, service, method); |
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); |
|
|
|
|
authctxt->style = style ? xstrdup(style) : NULL; |
authctxt->style = style ? xstrdup(style) : NULL; |
if (use_privsep) |
if (use_privsep) |
mm_inform_authserv(service, style); |
mm_inform_authserv(service, style); |
userauth_banner(); |
userauth_banner(ssh); |
if (auth2_setup_methods_lists(authctxt) != 0) |
if (auth2_setup_methods_lists(authctxt) != 0) |
packet_disconnect("no authentication methods enabled"); |
ssh_packet_disconnect(ssh, |
|
"no authentication methods enabled"); |
} else if (strcmp(user, authctxt->user) != 0 || |
} else if (strcmp(user, authctxt->user) != 0 || |
strcmp(service, authctxt->service) != 0) { |
strcmp(service, authctxt->service) != 0) { |
packet_disconnect("Change of username or service not allowed: " |
ssh_packet_disconnect(ssh, "Change of username or service " |
"(%s,%s) -> (%s,%s)", |
"not allowed: (%s,%s) -> (%s,%s)", |
authctxt->user, authctxt->service, user, service); |
authctxt->user, authctxt->service, user, service); |
} |
} |
/* reset state */ |
/* reset state */ |
|
|
ensure_minimum_time_since(tstart, |
ensure_minimum_time_since(tstart, |
user_specific_delay(authctxt->user)); |
user_specific_delay(authctxt->user)); |
userauth_finish(ssh, authenticated, method, NULL); |
userauth_finish(ssh, authenticated, method, NULL); |
|
r = 0; |
|
out: |
free(service); |
free(service); |
free(user); |
free(user); |
free(method); |
free(method); |
return 0; |
return r; |
} |
} |
|
|
void |
void |
|
|
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
char *methods; |
char *methods; |
int partial = 0; |
int r, partial = 0; |
|
|
if (!authctxt->valid && authenticated) |
if (!authctxt->valid && authenticated) |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
|
|
|
|
if (authenticated == 1) { |
if (authenticated == 1) { |
/* turn off userauth */ |
/* turn off userauth */ |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_REQUEST, |
packet_start(SSH2_MSG_USERAUTH_SUCCESS); |
&dispatch_protocol_ignore); |
packet_send(); |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_SUCCESS)) != 0 || |
packet_write_wait(); |
(r = sshpkt_send(ssh)) != 0 || |
|
(r = ssh_packet_write_wait(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
/* now we can break out */ |
/* now we can break out */ |
authctxt->success = 1; |
authctxt->success = 1; |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); |
|
|
methods = authmethods_get(authctxt); |
methods = authmethods_get(authctxt); |
debug3("%s: failure partial=%d next methods=\"%s\"", __func__, |
debug3("%s: failure partial=%d next methods=\"%s\"", __func__, |
partial, methods); |
partial, methods); |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_FAILURE)) != 0 || |
packet_put_cstring(methods); |
(r = sshpkt_put_cstring(ssh, methods)) != 0 || |
packet_put_char(partial); |
(r = sshpkt_put_u8(ssh, partial)) != 0 || |
packet_send(); |
(r = sshpkt_send(ssh)) != 0 || |
packet_write_wait(); |
(r = ssh_packet_write_wait(ssh)) != 0) |
|
fatal("%s: %s", __func__, ssh_err(r)); |
free(methods); |
free(methods); |
} |
} |
} |
} |