version 1.116, 2007/09/29 00:25:51 |
version 1.117, 2008/07/02 12:36:39 |
|
|
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <sys/stat.h> |
|
#include <sys/uio.h> |
|
|
|
#include <fcntl.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <string.h> |
#include <string.h> |
#include <stdarg.h> |
#include <stdarg.h> |
|
#include <unistd.h> |
|
|
|
#include "atomicio.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "ssh2.h" |
#include "ssh2.h" |
#include "packet.h" |
#include "packet.h" |
|
|
static Authmethod *authmethod_lookup(const char *); |
static Authmethod *authmethod_lookup(const char *); |
static char *authmethods_get(void); |
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); |
|
} |
|
|
|
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; |
|
|
|
packet_start(SSH2_MSG_USERAUTH_BANNER); |
|
packet_put_cstring(banner); |
|
packet_put_cstring(""); /* language, unused */ |
|
packet_send(); |
|
debug("userauth_banner: sent"); |
|
done: |
|
if (banner) |
|
xfree(banner); |
|
} |
|
|
/* |
/* |
* loop until authctxt->success == TRUE |
* loop until authctxt->success == TRUE |
*/ |
*/ |
|
|
void |
void |
do_authentication2(Authctxt *authctxt) |
do_authentication2(Authctxt *authctxt) |
{ |
{ |
|
|
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(); |
} 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: " |
packet_disconnect("Change of username or service not allowed: " |
|
|
|
|
/* try to authenticate user */ |
/* try to authenticate user */ |
m = authmethod_lookup(method); |
m = authmethod_lookup(method); |
if (m != NULL) { |
if (m != NULL && authctxt->failures < options.max_authtries) { |
debug2("input_userauth_request: try method %s", method); |
debug2("input_userauth_request: try method %s", method); |
authenticated = m->userauth(authctxt); |
authenticated = m->userauth(authctxt); |
} |
} |
|
|
/* now we can break out */ |
/* now we can break out */ |
authctxt->success = 1; |
authctxt->success = 1; |
} else { |
} else { |
if (authctxt->failures++ > options.max_authtries) |
if (++authctxt->failures > options.max_authtries) |
packet_disconnect(AUTH_FAIL_MSG, authctxt->user); |
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); |
|
|
name ? name : "NULL"); |
name ? name : "NULL"); |
return NULL; |
return NULL; |
} |
} |
|
|