summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-03-11 01:49:19 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-03-11 01:49:19 +0000
commitb9be60a722a8ae24affe68e07ef8557d00992648 (patch)
treeabbd82106ed9c6278bd49e357f74193036241bdd /sshconnect2.c
parent7f283fcc944a8726ec610d5a11339b28fa75cd94 (diff)
- markus@cvs.openbsd.org 2001/03/10 17:51:04
[kex.c match.c match.h readconf.c readconf.h sshconnect2.c] add PreferredAuthentications
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c132
1 files changed, 55 insertions, 77 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 646bb18f3..19d079bd3 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.53 2001/03/10 17:51:04 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/md5.h> 29#include <openssl/md5.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $");
51#include "log.h" 51#include "log.h"
52#include "readconf.h" 52#include "readconf.h"
53#include "readpass.h" 53#include "readpass.h"
54#include "match.h"
54 55
55void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); 56void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
56void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); 57void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
@@ -498,9 +499,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k,
498 sign_cb_fn *sign_callback); 499 sign_cb_fn *sign_callback);
499void clear_auth_state(Authctxt *authctxt); 500void clear_auth_state(Authctxt *authctxt);
500 501
501void authmethod_clear(void);
502Authmethod *authmethod_get(char *authlist); 502Authmethod *authmethod_get(char *authlist);
503Authmethod *authmethod_lookup(const char *name); 503Authmethod *authmethod_lookup(const char *name);
504char *authmethods_get(void);
504 505
505Authmethod authmethods[] = { 506Authmethod authmethods[] = {
506 {"publickey", 507 {"publickey",
@@ -551,6 +552,9 @@ ssh_userauth2(const char *server_user, char *host)
551 packet_done(); 552 packet_done();
552 debug("got SSH2_MSG_SERVICE_ACCEPT"); 553 debug("got SSH2_MSG_SERVICE_ACCEPT");
553 554
555 if (options.preferred_authentications == NULL)
556 options.preferred_authentications = authmethods_get();
557
554 /* setup authentication context */ 558 /* setup authentication context */
555 authctxt.agent = ssh_get_authentication_connection(); 559 authctxt.agent = ssh_get_authentication_connection();
556 authctxt.server_user = server_user; 560 authctxt.server_user = server_user;
@@ -561,7 +565,6 @@ ssh_userauth2(const char *server_user, char *host)
561 authctxt.authlist = NULL; 565 authctxt.authlist = NULL;
562 if (authctxt.method == NULL) 566 if (authctxt.method == NULL)
563 fatal("ssh_userauth2: internal error: cannot send userauth none request"); 567 fatal("ssh_userauth2: internal error: cannot send userauth none request");
564 authmethod_clear();
565 568
566 /* initial userauth request */ 569 /* initial userauth request */
567 userauth_none(&authctxt); 570 userauth_none(&authctxt);
@@ -1106,39 +1109,6 @@ input_userauth_info_req(int type, int plen, void *ctxt)
1106 1109
1107/* find auth method */ 1110/* find auth method */
1108 1111
1109#define DELIM ","
1110
1111static char *def_authlist = "publickey,password";
1112static char *authlist_current = NULL; /* clean copy used for comparison */
1113static char *authname_current = NULL; /* last used auth method */
1114static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
1115static char *authlist_state = NULL; /* state variable for strtok_r() */
1116
1117/*
1118 * Before starting to use a new authentication method list sent by the
1119 * server, reset internal variables. This should also be called when
1120 * finished processing server list to free resources.
1121 */
1122void
1123authmethod_clear(void)
1124{
1125 if (authlist_current != NULL) {
1126 xfree(authlist_current);
1127 authlist_current = NULL;
1128 }
1129 if (authlist_working != NULL) {
1130 xfree(authlist_working);
1131 authlist_working = NULL;
1132 }
1133 if (authname_current != NULL) {
1134 xfree(authname_current);
1135 authname_current = NULL;
1136 }
1137 if (authlist_state != NULL)
1138 authlist_state = NULL;
1139 return;
1140}
1141
1142/* 1112/*
1143 * given auth method name, if configurable options permit this method fill 1113 * given auth method name, if configurable options permit this method fill
1144 * in auth_ident field and return true, otherwise return false. 1114 * in auth_ident field and return true, otherwise return false.
@@ -1169,62 +1139,70 @@ authmethod_lookup(const char *name)
1169 return NULL; 1139 return NULL;
1170} 1140}
1171 1141
1142/* XXX internal state */
1143static Authmethod *current = NULL;
1144static char *supported = NULL;
1145static char *preferred = NULL;
1172/* 1146/*
1173 * Given the authentication method list sent by the server, return the 1147 * Given the authentication method list sent by the server, return the
1174 * next method we should try. If the server initially sends a nil list, 1148 * next method we should try. If the server initially sends a nil list,
1175 * use a built-in default list. If the server sends a nil list after 1149 * use a built-in default list.
1176 * previously sending a valid list, continue using the list originally
1177 * sent.
1178 */ 1150 */
1179
1180Authmethod * 1151Authmethod *
1181authmethod_get(char *authlist) 1152authmethod_get(char *authlist)
1182{ 1153{
1183 char *name = NULL, *authname_old; 1154
1184 Authmethod *method = NULL; 1155 char *name = NULL;
1156 int next;
1185 1157
1186 /* Use a suitable default if we're passed a nil list. */ 1158 /* Use a suitable default if we're passed a nil list. */
1187 if (authlist == NULL || strlen(authlist) == 0) 1159 if (authlist == NULL || strlen(authlist) == 0)
1188 authlist = def_authlist; 1160 authlist = options.preferred_authentications;
1189 1161
1190 if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) { 1162 if (supported == NULL || strcmp(authlist, supported) != 0) {
1191 /* start over if passed a different list */ 1163 debug3("start over, passed a different list %s", authlist);
1192 debug3("start over, passed a different list"); 1164 if (supported != NULL)
1193 authmethod_clear(); 1165 xfree(supported);
1194 authlist_current = xstrdup(authlist); 1166 supported = xstrdup(authlist);
1195 authlist_working = xstrdup(authlist); 1167 preferred = options.preferred_authentications;
1196 name = strtok_r(authlist_working, DELIM, &authlist_state); 1168 debug3("preferred %s", preferred);
1197 } else { 1169 current = NULL;
1198 /* 1170 } else if (current != NULL && authmethod_is_enabled(current))
1199 * try to use previously used authentication method 1171 return current;
1200 * or continue to use previously passed list
1201 */
1202 name = (authname_current != NULL) ?
1203 authname_current : strtok_r(NULL, DELIM, &authlist_state);
1204 }
1205 1172
1206 while (name != NULL) { 1173 for (;;) {
1174 if ((name = match_list(preferred, supported, &next)) == NULL) {
1175 debug("no more auth methods to try");
1176 current = NULL;
1177 return NULL;
1178 }
1179 preferred += next;
1207 debug3("authmethod_lookup %s", name); 1180 debug3("authmethod_lookup %s", name);
1208 method = authmethod_lookup(name); 1181 debug3("remaining preferred: %s", preferred);
1209 if (method != NULL && authmethod_is_enabled(method)) { 1182 if ((current = authmethod_lookup(name)) != NULL &&
1183 authmethod_is_enabled(current)) {
1210 debug3("authmethod_is_enabled %s", name); 1184 debug3("authmethod_is_enabled %s", name);
1211 break; 1185 debug("next auth method to try is %s", name);
1186 return current;
1212 } 1187 }
1213 name = strtok_r(NULL, DELIM, &authlist_state);
1214 method = NULL;
1215 }
1216
1217 authname_old = authname_current;
1218 if (method != NULL) {
1219 debug("next auth method to try is %s", name);
1220 authname_current = xstrdup(name);
1221 } else {
1222 debug("no more auth methods to try");
1223 authname_current = NULL;
1224 } 1188 }
1189}
1225 1190
1226 if (authname_old != NULL)
1227 xfree(authname_old);
1228 1191
1229 return (method); 1192#define DELIM ","
1193char *
1194authmethods_get(void)
1195{
1196 Authmethod *method = NULL;
1197 char buf[1024];
1198
1199 buf[0] = '\0';
1200 for (method = authmethods; method->name != NULL; method++) {
1201 if (authmethod_is_enabled(method)) {
1202 if (buf[0] != '\0')
1203 strlcat(buf, DELIM, sizeof buf);
1204 strlcat(buf, method->name, sizeof buf);
1205 }
1206 }
1207 return xstrdup(buf);
1230} 1208}