+/* $OpenBSD: auth2.c,v 1.114 2007/03/01 10:28:02 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $");
-#include "ssh2.h"
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <string.h>
+
#include "xmalloc.h"
+#include "ssh2.h"
#include "packet.h"
#include "log.h"
+#include "buffer.h"
#include "servconf.h"
#include "compat.h"
+#include "key.h"
+#include "hostfile.h"
#include "auth.h"
#include "dispatch.h"
#include "pathnames.h"
-#include "monitor_wrap.h"
#include "buffer.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
+#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
extern Authmethod method_hostbased;
#ifdef GSSAPI
extern Authmethod method_external;
+extern Authmethod method_gsskeyex;
extern Authmethod method_gssapi;
extern Authmethod method_gssapi_compat;
#endif
&method_none,
&method_pubkey,
#ifdef GSSAPI
+ &method_gsskeyex,
&method_external,
&method_gssapi,
&method_gssapi_compat,
void
do_authentication2(Authctxt *authctxt)
{
- /* challenge-response is implemented via keyboard interactive */
- if (options.challenge_response_authentication)
- options.kbd_interactive_authentication = 1;
-
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
}
+/*ARGSUSED*/
static void
input_service_request(int type, u_int32_t seq, void *ctxt)
{
xfree(service);
}
+/*ARGSUSED*/
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
#ifdef GSSAPI
if (user[0] == '\0') {
debug("received empty username for %s", method);
- if (strcmp(method, "external-keyx") == 0) {
+ if (strcmp(method, "external-keyx") == 0 ||
+ strcmp(method, "gssapi-keyex") == 0) {
char *lname = NULL;
PRIVSEP(ssh_gssapi_localname(&lname));
if (lname && lname[0] != '\0') {
debug("set username to %s from gssapi context", user);
} else {
debug("failed to set username from gssapi context");
+ packet_send_debug("failed to set username from gssapi context");
}
}
}
if ((style = strchr(user, ':')) != NULL)
*style++ = 0;
- /* If first time or username changed or implicit username,
+ /* If first time or username changed or empty username,
setup/reset authentication context. */
if ((authctxt->attempt++ == 0) ||
(strcmp(user, authctxt->user) != 0) ||
authctxt->user = NULL;
}
authctxt->valid = 0;
+ authctxt->user = xstrdup(user);
+ if (strcmp(service, "ssh-connection") != 0) {
+ packet_disconnect("Unsupported service %s", service);
+ }
#ifdef GSSAPI
/* If we're going to set the username based on the
GSSAPI context later, then wait until then to
((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) {
+ if (authctxt->pw) {
authctxt->valid = 1;
debug2("input_userauth_request: setting up authctxt for %s", user);
-#ifdef USE_PAM
- if (options.use_pam)
- PRIVSEP(start_pam(authctxt));
-#endif
} else {
logit("input_userauth_request: invalid user %s", user);
authctxt->pw = fakepw();
-#ifdef USE_PAM
- if (options.use_pam)
- PRIVSEP(start_pam(authctxt));
-#endif
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_INVALID_USER));
#endif
}
#ifdef GSSAPI
} /* endif for setting username based on GSSAPI context */
+#endif
+#ifdef USE_PAM
+ if (options.use_pam)
+ PRIVSEP(start_pam(authctxt));
#endif
setproctitle("%s%s", authctxt->valid ? user : "unknown",
use_privsep ? " [net]" : "");
-#ifdef GSSAPI
if (authctxt->attempt == 1) {
-#endif
- authctxt->service = xstrdup(service);
- authctxt->style = style ? xstrdup(style) : NULL;
- if (use_privsep)
- mm_inform_authserv(service, style);
-#ifdef GSSAPI
- } /* if (authctxt->attempt == 1) */
-#endif
+ authctxt->service = xstrdup(service);
+ authctxt->style = style ? xstrdup(style) : NULL;
+ if (use_privsep)
+ mm_inform_authserv(service, style);
+ }
}
if (strcmp(service, authctxt->service) != 0) {
packet_disconnect("Change of service not allowed: "
#endif
authctxt->postponed = 0;
+ authctxt->server_caused_failure = 0;
/* try to authenticate user */
m = authmethod_lookup(method);
packet_write_wait();
}
fatal("Access denied for user %s by PAM account "
- "configuration", authctxt->user);
+ "configuration", authctxt->user);
}
}
#endif
/* now we can break out */
authctxt->success = 1;
} else {
- if (authctxt->failures++ > options.max_authtries) {
+ /* Dont count server configuration issues against the client */
+ if (!authctxt->server_caused_failure &&
+ authctxt->failures++ > options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
#endif