*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.93 2002/05/31 11:35:15 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.104 2003/11/04 08:54:09 djm Exp $");
#include "ssh2.h"
-#include "ssh1.h"
#include "xmalloc.h"
#include "packet.h"
#include "log.h"
#include "dispatch.h"
#include "pathnames.h"
#include "monitor_wrap.h"
-#include "misc.h"
#ifdef GSSAPI
#include "ssh-gss.h"
-#ifdef GSI
-#include "globus_gss_assist.h"
-char* olduser;
-int changeuser = 0;
-#endif
#endif
/* import */
extern ServerOptions options;
extern u_char *session_id2;
-extern int session_id2_len;
-
-Authctxt *x_authctxt = NULL;
+extern u_int session_id2_len;
/* methods */
extern Authmethod method_none;
-#ifdef GSSAPI
-extern Authmethod method_external;
-extern Authmethod method_gssapi;
-#endif
extern Authmethod method_pubkey;
extern Authmethod method_passwd;
extern Authmethod method_kbdint;
extern Authmethod method_hostbased;
+#ifdef GSSAPI
+extern Authmethod method_external;
+extern Authmethod method_gssapi;
+extern Authmethod method_gssapi_compat;
+#endif
Authmethod *authmethods[] = {
&method_none,
+ &method_pubkey,
#ifdef GSSAPI
&method_external,
&method_gssapi,
+ &method_gssapi_compat,
#endif
- &method_pubkey,
&method_passwd,
&method_kbdint,
&method_hostbased,
static Authmethod *authmethod_lookup(const char *);
static char *authmethods_get(void);
int user_key_allowed(struct passwd *, Key *);
-int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
/*
* loop until authctxt->success == TRUE
*/
-Authctxt *
-do_authentication2(void)
+void
+do_authentication2(Authctxt *authctxt)
{
- Authctxt *authctxt = authctxt_new();
-
- x_authctxt = authctxt; /*XXX*/
-
/* challenge-response is implemented via keyboard interactive */
if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
- if (options.pam_authentication_via_kbd_int)
- options.kbd_interactive_authentication = 1;
- if (use_privsep)
- options.pam_authentication_via_kbd_int = 0;
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
-
- return (authctxt);
}
static void
{
Authctxt *authctxt = ctxt;
u_int len;
- int accept = 0;
+ int acceptit = 0;
char *service = packet_get_string(&len);
packet_check_eom();
if (strcmp(service, "ssh-userauth") == 0) {
if (!authctxt->success) {
- accept = 1;
+ acceptit = 1;
/* now we can handle user-auth requests */
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
}
}
/* XXX all other service requests are denied */
- if (accept) {
+ if (acceptit) {
packet_start(SSH2_MSG_SERVICE_ACCEPT);
packet_put_cstring(service);
packet_send();
method = packet_get_string(NULL);
#ifdef GSSAPI
-#ifdef GSI
- if(changeuser == 0 && (strcmp(method,"external-keyx") == 0 || strcmp(method,"gssapi") ==0) && strcmp(user,"") == 0) {
- char *gridmapped_name = NULL;
- struct passwd *pw = NULL;
- if(globus_gss_assist_gridmap(gssapi_client_name.value,
- &gridmapped_name) == 0) {
- user = gridmapped_name;
- debug("I gridmapped and got %s", user);
- pw = getpwnam(user);
- if (pw && allowed_user(pw)) {
- olduser = authctxt->user;
- authctxt->user = xstrdup(user);
- authctxt->pw = pwcopy(pw);
- authctxt->valid = 1;
- changeuser = 1;
- }
-
- } else {
- debug("I gridmapped and got null, reverting to %s",
- authctxt->user);
+ if (user[0] == '\0') {
+ debug("received empty username for %s", method);
+ if (strcmp(method, "external-keyx") == 0) {
+ char *lname = NULL;
+ PRIVSEP(ssh_gssapi_localname(&lname));
+ if (lname && lname[0] != '\0') {
xfree(user);
- user = xstrdup(authctxt->user);
- }
- }
- else if(changeuser) {
- struct passwd *pw = NULL;
- pw = getpwnam(user);
- if (pw && allowed_user(pw)) {
- xfree(authctxt->user);
- authctxt->user = olduser;
- authctxt->pw = pwcopy(pw);
- authctxt->valid = 1;
- changeuser = 0;
- }
- }
-
-#endif /* GSI */
-#endif /* GSSAPI */
-
- debug("userauth-request for user %s service %s method %s", user, service, method);
+ user = lname;
+ debug("set username to %s from gssapi context", user);
+ } else {
+ debug("failed to set username from gssapi context");
+ }
+ }
+ }
+#endif
+
+ debug("userauth-request for user %s service %s method %s",
+ user[0] ? user : "<implicit>", service, method);
debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
if ((style = strchr(user, ':')) != NULL)
*style++ = 0;
- if (authctxt->attempt++ == 0) {
- /* setup auth context */
+ /* If first time or username changed or implicit username,
+ setup/reset authentication context. */
+ if ((authctxt->attempt++ == 0) ||
+ (strcmp(user, authctxt->user) != 0) ||
+ (strcmp(user, "") == 0)) {
+ if (authctxt->user) {
+ xfree(authctxt->user);
+ authctxt->user = NULL;
+ }
+ if (authctxt->service) {
+ xfree(authctxt->service);
+ authctxt->service = NULL;
+ }
+ if (authctxt->style) {
+ xfree(authctxt->style);
+ authctxt->style = NULL;
+ }
+ authctxt->valid = 0;
+#ifdef GSSAPI
+ /* If we're going to set the username based on the
+ GSSAPI context later, then wait until then to
+ verify it. Just put in placeholders for now. */
+ if ((strcmp(user, "") == 0) &&
+ ((strcmp(method, "gssapi") == 0) ||
+ (strcmp(method, "gssapi-with-mic") == 0))) {
+ authctxt->pw = fakepw();
+ authctxt->user = xstrdup(user);
+ } else {
+#endif
authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->user = xstrdup(user);
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
authctxt->valid = 1;
debug2("input_userauth_request: setting up authctxt for %s", user);
#ifdef USE_PAM
- PRIVSEP(start_pam(authctxt->pw->pw_name));
+ if (options.use_pam)
+ PRIVSEP(start_pam(authctxt));
#endif
} else {
- log("input_userauth_request: illegal user %s", user);
+ logit("input_userauth_request: illegal user %s", user);
+ authctxt->pw = fakepw();
#ifdef USE_PAM
- PRIVSEP(start_pam("NOUSER"));
+ if (options.use_pam)
+ PRIVSEP(start_pam(authctxt));
#endif
}
+#ifdef GSSAPI
+ } /* endif for setting username based on GSSAPI context */
+#endif
setproctitle("%s%s", authctxt->pw ? user : "unknown",
use_privsep ? " [net]" : "");
- authctxt->user = xstrdup(user);
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
- if (use_privsep)
+ if (use_privsep && (authctxt->attempt == 1))
mm_inform_authserv(service, style);
- } else if (strcmp(user, authctxt->user) != 0 ||
- strcmp(service, authctxt->service) != 0) {
- packet_disconnect("Change of username or service not allowed: "
+ } else if (strcmp(service, authctxt->service) != 0) {
+ packet_disconnect("Change of service not allowed: "
"(%s,%s) -> (%s,%s)",
authctxt->user, authctxt->service, user, service);
}
authenticated = 0;
#ifdef USE_PAM
- if (!use_privsep && authenticated && authctxt->user &&
- !do_pam_account(authctxt->user, NULL))
+ if (options.use_pam && authenticated && !PRIVSEP(do_pam_account()))
authenticated = 0;
-#endif /* USE_PAM */
+#endif
+
+#ifdef _UNICOS
+ if (authenticated && cray_access_denied(authctxt->user)) {
+ authenticated = 0;
+ fatal("Access denied for user %s.",authctxt->user);
+ }
+#endif /* _UNICOS */
/* Log before sending the reply */
- if (!compat20)
- auth_log(authctxt, authenticated, method, " ssh1");
- else
auth_log(authctxt, authenticated, method, " ssh2");
if (authctxt->postponed)
if (authenticated == 1) {
/* turn off userauth */
dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
- if (!compat20)
- packet_start(SSH_SMSG_SUCCESS);
- else
packet_start(SSH2_MSG_USERAUTH_SUCCESS);
packet_send();
packet_write_wait();
/* now we can break out */
authctxt->success = 1;
} else {
- if (authctxt->failures++ > AUTH_FAIL_MAX) {
-#ifdef WITH_AIXAUTHENTICATE
- /* XXX: privsep */
- loginfailed(authctxt->user,
- get_canonical_hostname(options.verify_reverse_mapping),
- "ssh");
-#endif /* WITH_AIXAUTHENTICATE */
+ if (authctxt->failures++ > AUTH_FAIL_MAX)
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
- }
- if (!compat20) {
- /*
- * Break out of the dispatch loop now and go back to
- * SSH1 code. We need to set the 'success' flag to
- * break out of the loop. Set the 'postponed' flag to
- * tell the SSH1 code that authentication failed. The
- * SSH1 code will handle sending SSH_SMSG_FAILURE.
- */
- authctxt->success = authctxt->postponed = 1;
- } else {
methods = authmethods_get();
packet_start(SSH2_MSG_USERAUTH_FAILURE);
packet_put_cstring(methods);
packet_send();
packet_write_wait();
xfree(methods);
- }
}
}
-/* get current user */
-
-struct passwd*
-auth_get_user(void)
-{
- return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
-}
-
#define DELIM ","
static char *