version 1.27, 2001/01/13 18:56:48 |
version 1.28, 2001/01/18 17:00:00 |
|
|
void input_userauth_request(int type, int plen, void *ctxt); |
void input_userauth_request(int type, int plen, void *ctxt); |
void protocol_error(int type, int plen, void *ctxt); |
void protocol_error(int type, int plen, void *ctxt); |
|
|
|
|
/* helper */ |
/* helper */ |
Authmethod *authmethod_lookup(const char *name); |
Authmethod *authmethod_lookup(const char *name); |
struct passwd *pwcopy(struct passwd *pw); |
struct passwd *pwcopy(struct passwd *pw); |
|
|
void |
void |
do_authentication2() |
do_authentication2() |
{ |
{ |
Authctxt *authctxt = xmalloc(sizeof(*authctxt)); |
Authctxt *authctxt = authctxt_new(); |
memset(authctxt, 'a', sizeof(*authctxt)); |
|
authctxt->valid = 0; |
|
authctxt->attempt = 0; |
|
authctxt->failures = 0; |
|
authctxt->success = 0; |
|
x_authctxt = authctxt; /*XXX*/ |
x_authctxt = authctxt; /*XXX*/ |
|
|
#ifdef AFS |
#ifdef AFS |
|
|
dispatch_init(&protocol_error); |
dispatch_init(&protocol_error); |
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); |
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); |
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); |
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); |
do_authenticated2(); |
do_authenticated2(authctxt); |
} |
} |
|
|
void |
void |
|
|
{ |
{ |
Authctxt *authctxt = ctxt; |
Authctxt *authctxt = ctxt; |
Authmethod *m = NULL; |
Authmethod *m = NULL; |
char *user, *service, *method; |
char *user, *service, *method, *style = NULL; |
int authenticated = 0; |
int authenticated = 0; |
|
|
if (authctxt == NULL) |
if (authctxt == NULL) |
|
|
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); |
|
|
|
if ((style = strchr(user, ':')) != NULL) |
|
*style++ = 0; |
|
|
if (authctxt->attempt++ == 0) { |
if (authctxt->attempt++ == 0) { |
/* setup auth context */ |
/* setup auth context */ |
struct passwd *pw = NULL; |
struct passwd *pw = NULL; |
|
|
} |
} |
authctxt->user = xstrdup(user); |
authctxt->user = xstrdup(user); |
authctxt->service = xstrdup(service); |
authctxt->service = xstrdup(service); |
|
authctxt->style = style ? xstrdup(style) : NULL; /* currently unused */ |
} else if (authctxt->valid) { |
} else if (authctxt->valid) { |
if (strcmp(user, authctxt->user) != 0 || |
if (strcmp(user, authctxt->user) != 0 || |
strcmp(service, authctxt->service) != 0) { |
strcmp(service, authctxt->service) != 0) { |
|
|
authctxt->valid = 0; |
authctxt->valid = 0; |
} |
} |
} |
} |
|
/* reset state */ |
|
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error); |
|
authctxt->postponed = 0; |
|
|
|
/* try to authenticate user */ |
m = authmethod_lookup(method); |
m = authmethod_lookup(method); |
if (m != NULL) { |
if (m != NULL) { |
debug2("input_userauth_request: try method %s", method); |
debug2("input_userauth_request: try method %s", method); |
authenticated = m->userauth(authctxt); |
authenticated = m->userauth(authctxt); |
} else { |
|
debug2("input_userauth_request: unsupported method %s", method); |
|
} |
} |
if (!authctxt->valid && authenticated == 1) { |
if (!authctxt->valid && authenticated) |
log("input_userauth_request: INTERNAL ERROR: authenticated invalid user %s service %s", user, method); |
fatal("INTERNAL ERROR: authenticated invalid user %s", |
authenticated = 0; |
authctxt->user); |
} |
|
|
|
/* Special handling for root */ |
/* Special handling for root */ |
if (authenticated == 1 && |
if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed()) |
authctxt->valid && authctxt->pw->pw_uid == 0 && !options.permit_root_login) { |
|
authenticated = 0; |
authenticated = 0; |
log("ROOT LOGIN REFUSED FROM %.200s", get_canonical_hostname()); |
|
} |
|
|
|
/* Log before sending the reply */ |
/* Log before sending the reply */ |
userauth_log(authctxt, authenticated, method); |
auth_log(authctxt, authenticated, method, " ssh2"); |
userauth_reply(authctxt, authenticated); |
|
|
|
|
if (!authctxt->postponed) |
|
userauth_reply(authctxt, authenticated); |
|
|
xfree(service); |
xfree(service); |
xfree(user); |
xfree(user); |
xfree(method); |
xfree(method); |
|
|
return; |
return; |
} |
} |
|
|
void |
|
userauth_log(Authctxt *authctxt, int authenticated, char *method) |
|
{ |
|
void (*authlog) (const char *fmt,...) = verbose; |
|
char *user = NULL, *authmsg = NULL; |
|
|
|
/* Raise logging level */ |
|
if (authenticated == 1 || |
|
!authctxt->valid || |
|
authctxt->failures >= AUTH_FAIL_LOG || |
|
strcmp(method, "password") == 0) |
|
authlog = log; |
|
|
|
if (authenticated == 1) { |
|
authmsg = "Accepted"; |
|
} else if (authenticated == 0) { |
|
authmsg = "Failed"; |
|
} else { |
|
authmsg = "Postponed"; |
|
} |
|
|
|
if (authctxt->valid) { |
|
user = authctxt->pw->pw_uid == 0 ? "ROOT" : authctxt->user; |
|
} else { |
|
user = authctxt->user ? authctxt->user : "NOUSER"; |
|
} |
|
|
|
authlog("%s %s for %.200s from %.200s port %d ssh2", |
|
authmsg, |
|
method, |
|
user, |
|
get_remote_ipaddr(), |
|
get_remote_port()); |
|
} |
|
|
|
void |
void |
userauth_reply(Authctxt *authctxt, int authenticated) |
userauth_reply(Authctxt *authctxt, int authenticated) |
{ |
{ |
char *methods; |
char *methods; |
|
|
/* XXX todo: check if multiple auth methods are needed */ |
/* XXX todo: check if multiple auth methods are needed */ |
if (authenticated == 1) { |
if (authenticated) { |
/* turn off userauth */ |
/* turn off userauth */ |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); |
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error); |
packet_start(SSH2_MSG_USERAUTH_SUCCESS); |
packet_start(SSH2_MSG_USERAUTH_SUCCESS); |
|
|
packet_write_wait(); |
packet_write_wait(); |
/* now we can break out */ |
/* now we can break out */ |
authctxt->success = 1; |
authctxt->success = 1; |
} else if (authenticated == 0) { |
} else { |
if (authctxt->failures++ >= AUTH_FAIL_MAX) |
if (authctxt->failures++ > AUTH_FAIL_MAX) |
packet_disconnect("too many failed userauth_requests"); |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
methods = authmethods_get(); |
methods = authmethods_get(); |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
packet_start(SSH2_MSG_USERAUTH_FAILURE); |
packet_put_cstring(methods); |
packet_put_cstring(methods); |
|
|
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
xfree(methods); |
xfree(methods); |
} else { |
|
/* do nothing, we did already send a reply */ |
|
} |
} |
} |
} |
|
|
|
|
packet_done(); |
packet_done(); |
|
|
debug("keyboard-interactive language %s devs %s", lang, devs); |
debug("keyboard-interactive language %s devs %s", lang, devs); |
#ifdef SKEY |
|
/* XXX hardcoded, we should look at devs */ |
authenticated = auth2_challenge(authctxt, devs); |
if (options.skey_authentication != 0) |
|
authenticated = auth2_skey(authctxt); |
|
#endif |
|
xfree(lang); |
xfree(lang); |
xfree(devs); |
xfree(devs); |
return authenticated; |
return authenticated; |
|
|
fclose(f); |
fclose(f); |
key_free(found); |
key_free(found); |
return found_key; |
return found_key; |
} |
|
|
|
struct passwd * |
|
pwcopy(struct passwd *pw) |
|
{ |
|
struct passwd *copy = xmalloc(sizeof(*copy)); |
|
memset(copy, 0, sizeof(*copy)); |
|
copy->pw_name = xstrdup(pw->pw_name); |
|
copy->pw_passwd = xstrdup(pw->pw_passwd); |
|
copy->pw_uid = pw->pw_uid; |
|
copy->pw_gid = pw->pw_gid; |
|
copy->pw_class = xstrdup(pw->pw_class); |
|
copy->pw_dir = xstrdup(pw->pw_dir); |
|
copy->pw_shell = xstrdup(pw->pw_shell); |
|
return copy; |
|
} |
} |