*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.64 2001/06/23 00:20:58 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.82 2002/01/13 17:57:37 markus Exp $");
#include <openssl/evp.h>
#include "misc.h"
#include "hostfile.h"
#include "canohost.h"
-#include "tildexpand.h"
#include "match.h"
/* import */
extern u_char *session_id2;
extern int session_id2_len;
-#ifdef WITH_AIXAUTHENTICATE
-extern char *aixloginmsg;
-#endif
-
static Authctxt *x_authctxt = NULL;
static int one = 1;
/* protocol */
-void input_service_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);
+static void input_service_request(int, u_int32_t, void *);
+static void input_userauth_request(int, u_int32_t, void *);
/* helper */
-Authmethod *authmethod_lookup(const char *name);
-char *authmethods_get(void);
-int user_key_allowed(struct passwd *pw, Key *key);
-int
-hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
- Key *key);
+static Authmethod *authmethod_lookup(const char *);
+static char *authmethods_get(void);
+static int user_key_allowed(struct passwd *, Key *);
+static int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
/* auth */
-void userauth_banner(void);
-int userauth_none(Authctxt *authctxt);
-int userauth_passwd(Authctxt *authctxt);
-int userauth_pubkey(Authctxt *authctxt);
-int userauth_hostbased(Authctxt *authctxt);
-int userauth_kbdint(Authctxt *authctxt);
+static void userauth_banner(void);
+static int userauth_none(Authctxt *);
+static int userauth_passwd(Authctxt *);
+static int userauth_pubkey(Authctxt *);
+static int userauth_hostbased(Authctxt *);
+static int userauth_kbdint(Authctxt *);
Authmethod authmethods[] = {
{"none",
*/
void
-do_authentication2()
+do_authentication2(void)
{
Authctxt *authctxt = authctxt_new();
x_authctxt = authctxt; /*XXX*/
- /* challenge-reponse is implemented via keyboard interactive */
+ /* 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;
- dispatch_init(&protocol_error);
+ dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
do_authenticated(authctxt);
}
-void
-protocol_error(int type, int plen, void *ctxt)
-{
- log("auth: protocol error: type %d plen %d", type, plen);
- packet_start(SSH2_MSG_UNIMPLEMENTED);
- packet_put_int(0);
- packet_send();
- packet_write_wait();
-}
-
-void
-input_service_request(int type, int plen, void *ctxt)
+static void
+input_service_request(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
u_int len;
int accept = 0;
char *service = packet_get_string(&len);
- packet_done();
+ packet_check_eom();
if (authctxt == NULL)
fatal("input_service_request: no authctxt");
xfree(service);
}
-void
-input_userauth_request(int type, int plen, void *ctxt)
+static void
+input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
Authmethod *m = NULL;
authctxt->user, authctxt->service, user, service);
}
/* reset state */
- dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error);
+ auth2_challenge_stop(authctxt);
authctxt->postponed = 0;
-#ifdef BSD_AUTH
- if (authctxt->as) {
- auth_close(authctxt->as);
- authctxt->as = NULL;
- }
-#endif
/* try to authenticate user */
m = authmethod_lookup(method);
/* XXX todo: check if multiple auth methods are needed */
if (authenticated == 1) {
/* turn off userauth */
- dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
+ dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
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)
+ if (authctxt->failures++ > AUTH_FAIL_MAX) {
+#ifdef WITH_AIXAUTHENTICATE
+ loginfailed(authctxt->user,
+ get_canonical_hostname(options.reverse_mapping_check),
+ "ssh");
+#endif /* WITH_AIXAUTHENTICATE */
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+ }
methods = authmethods_get();
packet_start(SSH2_MSG_USERAUTH_FAILURE);
packet_put_cstring(methods);
}
}
-void
+static void
userauth_banner(void)
{
struct stat st;
return;
}
-int
+static int
userauth_none(Authctxt *authctxt)
{
/* disable method "none", only allowed one time */
Authmethod *m = authmethod_lookup("none");
if (m != NULL)
m->enabled = NULL;
- packet_done();
+ packet_check_eom();
userauth_banner();
if (authctxt->valid == 0)
return(0);
#ifdef HAVE_CYGWIN
- if (check_nt_auth(1, authctxt->pw->pw_uid) == 0)
+ if (check_nt_auth(1, authctxt->pw) == 0)
return(0);
#endif
#ifdef USE_PAM
#endif /* USE_PAM */
}
-int
+static int
userauth_passwd(Authctxt *authctxt)
{
char *password;
if (change)
log("password change not supported");
password = packet_get_string(&len);
- packet_done();
+ packet_check_eom();
if (authctxt->valid &&
#ifdef HAVE_CYGWIN
- check_nt_auth(1, authctxt->pw->pw_uid) &&
+ check_nt_auth(1, authctxt->pw) &&
#endif
#ifdef USE_PAM
auth_pam_password(authctxt->pw, password) == 1)
return authenticated;
}
-int
+static int
userauth_kbdint(Authctxt *authctxt)
{
int authenticated = 0;
lang = packet_get_string(NULL);
devs = packet_get_string(NULL);
- packet_done();
+ packet_check_eom();
debug("keyboard-interactive devs %s", devs);
xfree(devs);
xfree(lang);
#ifdef HAVE_CYGWIN
- if (check_nt_auth(0, authctxt->pw->pw_uid) == 0)
+ if (check_nt_auth(0, authctxt->pw) == 0)
return(0);
#endif
return authenticated;
}
-int
+static int
userauth_pubkey(Authctxt *authctxt)
{
Buffer b;
if (key != NULL) {
if (have_sig) {
sig = packet_get_string(&slen);
- packet_done();
+ packet_check_eom();
buffer_init(&b);
if (datafellows & SSH_OLD_SESSIONID) {
buffer_append(&b, session_id2, session_id2_len);
xfree(sig);
} else {
debug("test whether pkalg/pkblob are acceptable");
- packet_done();
+ packet_check_eom();
/* XXX fake reply and always send PK_OK ? */
/*
xfree(pkalg);
xfree(pkblob);
#ifdef HAVE_CYGWIN
- if (check_nt_auth(0, authctxt->pw->pw_uid) == 0)
+ if (check_nt_auth(0, authctxt->pw) == 0)
return(0);
#endif
return authenticated;
}
-int
+static int
userauth_hostbased(Authctxt *authctxt)
{
Buffer b;
#define DELIM ","
-char *
+static char *
authmethods_get(void)
{
Authmethod *method = NULL;
- u_int size = 0;
+ Buffer b;
char *list;
+ buffer_init(&b);
for (method = authmethods; method->name != NULL; method++) {
if (strcmp(method->name, "none") == 0)
continue;
if (method->enabled != NULL && *(method->enabled) != 0) {
- if (size != 0)
- size += strlen(DELIM);
- size += strlen(method->name);
- }
- }
- size++; /* trailing '\0' */
- list = xmalloc(size);
- list[0] = '\0';
-
- for (method = authmethods; method->name != NULL; method++) {
- if (strcmp(method->name, "none") == 0)
- continue;
- if (method->enabled != NULL && *(method->enabled) != 0) {
- if (list[0] != '\0')
- strlcat(list, DELIM, size);
- strlcat(list, method->name, size);
+ if (buffer_len(&b) > 0)
+ buffer_append(&b, ",", 1);
+ buffer_append(&b, method->name, strlen(method->name));
}
}
+ buffer_append(&b, "\0", 1);
+ list = xstrdup(buffer_ptr(&b));
+ buffer_free(&b);
return list;
}
-Authmethod *
+static Authmethod *
authmethod_lookup(const char *name)
{
Authmethod *method = NULL;
}
/* return 1 if user allows given key */
-int
+static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
char line[8192];
u_long linenum = 0;
struct stat st;
Key *found;
+ char *fp;
if (pw == NULL)
return 0;
return 0;
}
if (options.strict_modes &&
- secure_filename(f, file, pw->pw_uid, line, sizeof(line)) != 0) {
+ secure_filename(f, file, pw, line, sizeof(line)) != 0) {
fclose(f);
log("Authentication refused: %s", line);
restore_uid();
if (!*cp || *cp == '\n' || *cp == '#')
continue;
- if (key_read(found, &cp) == -1) {
+ if (key_read(found, &cp) != 1) {
/* no key? check if there are options for this key */
int quoted = 0;
debug2("user_key_allowed: check options: '%s'", cp);
/* Skip remaining whitespace. */
for (; *cp == ' ' || *cp == '\t'; cp++)
;
- if (key_read(found, &cp) == -1) {
+ if (key_read(found, &cp) != 1) {
debug2("user_key_allowed: advance: '%s'", cp);
/* still no key? advance to next line*/
continue;
if (key_equal(found, key) &&
auth_parse_options(pw, options, file, linenum) == 1) {
found_key = 1;
- debug("matching key found: file %s, line %ld",
+ debug("matching key found: file %s, line %lu",
file, linenum);
+ fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+ verbose("Found matching %s key: %s",
+ key_type(found), fp);
+ xfree(fp);
break;
}
}
}
/* check whether given key is in .ssh/authorized_keys* */
-int
+static int
user_key_allowed(struct passwd *pw, Key *key)
{
int success;
}
/* return 1 if given hostkey is allowed */
-int
+static int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Key *key)
{
const char *resolvedname, *ipaddr, *lookup;
- int host_status, len;
+ HostStatus host_status;
+ int len;
resolvedname = get_canonical_hostname(options.reverse_mapping_check);
ipaddr = get_remote_ipaddr();
host_status = check_key_in_hostfiles(pw, key, lookup,
_PATH_SSH_SYSTEM_HOSTFILE,
- options.ignore_user_known_hosts ? _PATH_SSH_USER_HOSTFILE : NULL);
+ options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
/* backward compat if no key has been found. */
if (host_status == HOST_NEW)
host_status = check_key_in_hostfiles(pw, key, lookup,
_PATH_SSH_SYSTEM_HOSTFILE2,
- options.ignore_user_known_hosts ? _PATH_SSH_USER_HOSTFILE2 :
- NULL);
+ options.ignore_user_known_hosts ? NULL :
+ _PATH_SSH_USER_HOSTFILE2);
return (host_status == HOST_OK);
}