X-Git-Url: http://andersk.mit.edu/gitweb/gssapi-openssh.git/blobdiff_plain/e74dc197654953e9349758a030551867db56d36b..22ce3a3becb01f9487f7fa12b859100c162e231c:/openssh/auth2.c diff --git a/openssh/auth2.c b/openssh/auth2.c index 9043b2c..f4ab7f4 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.116 2007/09/29 00:25:51 dtucker Exp $ */ +/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -26,11 +26,16 @@ #include "includes.h" #include +#include +#include +#include #include #include #include +#include +#include "atomicio.h" #include "xmalloc.h" #include "ssh2.h" #include "packet.h" @@ -65,10 +70,11 @@ extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; #ifdef GSSAPI -extern Authmethod method_external; extern Authmethod method_gsskeyex; extern Authmethod method_gssapi; -extern Authmethod method_gssapi_compat; +#endif +#ifdef JPAKE +extern Authmethod method_jpake; #endif static int log_flag = 0; @@ -79,9 +85,10 @@ Authmethod *authmethods[] = { &method_pubkey, #ifdef GSSAPI &method_gsskeyex, - &method_external, &method_gssapi, - &method_gssapi_compat, +#endif +#ifdef JPAKE + &method_jpake, #endif &method_passwd, &method_kbdint, @@ -98,10 +105,74 @@ static void input_userauth_request(int, u_int32_t, void *); static Authmethod *authmethod_lookup(const char *); static char *authmethods_get(void); +char * +auth2_read_banner(void) +{ + struct stat st; + char *banner = NULL; + size_t len, n; + int fd; + + if ((fd = open(options.banner, O_RDONLY)) == -1) + return (NULL); + if (fstat(fd, &st) == -1) { + close(fd); + return (NULL); + } + if (st.st_size > 1*1024*1024) { + close(fd); + return (NULL); + } + + len = (size_t)st.st_size; /* truncate */ + banner = xmalloc(len + 1); + n = atomicio(read, fd, banner, len); + close(fd); + + if (n != len) { + xfree(banner); + return (NULL); + } + banner[n] = '\0'; + + return (banner); +} + +void +userauth_send_banner(const char *msg) +{ + if (datafellows & SSH_BUG_BANNER) + return; + + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(msg); + packet_put_cstring(""); /* language, unused */ + packet_send(); + debug("%s: sent", __func__); +} + +static void +userauth_banner(void) +{ + char *banner = NULL; + + if (options.banner == NULL || + strcasecmp(options.banner, "none") == 0 || + (datafellows & SSH_BUG_BANNER) != 0) + return; + + if ((banner = PRIVSEP(auth2_read_banner())) == NULL) + goto done; + userauth_send_banner(banner); + +done: + if (banner) + xfree(banner); +} + /* * loop until authctxt->success == TRUE */ - void do_authentication2(Authctxt *authctxt) { @@ -163,8 +234,7 @@ 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 || - strcmp(method, "gssapi-keyex") == 0) { + if (strcmp(method, "gssapi-keyex") == 0) { char *lname = NULL; PRIVSEP(ssh_gssapi_localname(&lname)); if (lname && lname[0] != '\0') { @@ -183,7 +253,8 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) user[0] ? user : "", service, method); if (!log_flag) { logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", - get_remote_ipaddr(), get_remote_port(), user); + get_remote_ipaddr(), get_remote_port(), + user[0] ? user : ""); log_flag = 1; } debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); @@ -240,6 +311,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->style = style ? xstrdup(style) : NULL; if (use_privsep) mm_inform_authserv(service, style); + userauth_banner(); } } if (strcmp(service, authctxt->service) != 0) { @@ -249,8 +321,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } /* reset state */ auth2_challenge_stop(authctxt); +#ifdef JPAKE + auth2_jpake_stop(authctxt); +#endif #ifdef GSSAPI + /* XXX move to auth2_gssapi_stop() */ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); #endif @@ -260,7 +336,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) /* try to authenticate user */ m = authmethod_lookup(method); - if (m != NULL) { + if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); } @@ -328,8 +404,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authctxt->success = 1; } else { /* Dont count server configuration issues against the client */ - if (!authctxt->server_caused_failure && - authctxt->failures++ > options.max_authtries) { + /* Allow initial try of "none" auth without failure penalty */ + if (!authctxt->server_caused_failure && + (authctxt->attempt > 1 || strcmp(method, "none") != 0)) + authctxt->failures++; + if (authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif @@ -385,3 +464,4 @@ authmethod_lookup(const char *name) name ? name : "NULL"); return NULL; } +