00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "includes.h"
00013 RCSID("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $");
00014
00015 #include "xmalloc.h"
00016 #include "rsa.h"
00017 #include "ssh1.h"
00018 #include "packet.h"
00019 #include "buffer.h"
00020 #include "log.h"
00021 #include "servconf.h"
00022 #include "compat.h"
00023 #include "auth.h"
00024 #include "channels.h"
00025 #include "session.h"
00026 #include "uidswap.h"
00027 #include "monitor_wrap.h"
00028 #include "buffer.h"
00029
00030
00031 extern ServerOptions options;
00032 extern Buffer loginmsg;
00033
00034 static int auth1_process_password(Authctxt *, char *, size_t);
00035 static int auth1_process_rsa(Authctxt *, char *, size_t);
00036 static int auth1_process_rhosts_rsa(Authctxt *, char *, size_t);
00037 static int auth1_process_tis_challenge(Authctxt *, char *, size_t);
00038 static int auth1_process_tis_response(Authctxt *, char *, size_t);
00039
00040 static char *client_user = NULL;
00041
00042 struct AuthMethod1 {
00043 int type;
00044 char *name;
00045 int *enabled;
00046 int (*method)(Authctxt *, char *, size_t);
00047 };
00048
00049 const struct AuthMethod1 auth1_methods[] = {
00050 {
00051 SSH_CMSG_AUTH_PASSWORD, "password",
00052 &options.password_authentication, auth1_process_password
00053 },
00054 {
00055 SSH_CMSG_AUTH_RSA, "rsa",
00056 &options.rsa_authentication, auth1_process_rsa
00057 },
00058 {
00059 SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa",
00060 &options.rhosts_rsa_authentication, auth1_process_rhosts_rsa
00061 },
00062 {
00063 SSH_CMSG_AUTH_TIS, "challenge-response",
00064 &options.challenge_response_authentication,
00065 auth1_process_tis_challenge
00066 },
00067 {
00068 SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response",
00069 &options.challenge_response_authentication,
00070 auth1_process_tis_response
00071 },
00072 { -1, NULL, NULL, NULL}
00073 };
00074
00075 static const struct AuthMethod1
00076 *lookup_authmethod1(int type)
00077 {
00078 int i;
00079
00080 for(i = 0; auth1_methods[i].name != NULL; i++)
00081 if (auth1_methods[i].type == type)
00082 return (&(auth1_methods[i]));
00083
00084 return (NULL);
00085 }
00086
00087 static char *
00088 get_authname(int type)
00089 {
00090 const struct AuthMethod1 *a;
00091 static char buf[64];
00092
00093 if ((a = lookup_authmethod1(type)) != NULL)
00094 return (a->name);
00095 snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type);
00096 return (buf);
00097 }
00098
00099 static int
00100 auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
00101 {
00102 int authenticated = 0;
00103 char *password;
00104 u_int dlen;
00105
00106
00107
00108
00109
00110
00111 password = packet_get_string(&dlen);
00112 packet_check_eom();
00113
00114
00115 authenticated = PRIVSEP(auth_password(authctxt, password));
00116
00117 memset(password, 0, dlen);
00118 xfree(password);
00119
00120 return (authenticated);
00121 }
00122
00123 static int
00124 auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
00125 {
00126 int authenticated = 0;
00127 BIGNUM *n;
00128
00129
00130 if ((n = BN_new()) == NULL)
00131 fatal("do_authloop: BN_new failed");
00132 packet_get_bignum(n);
00133 packet_check_eom();
00134 authenticated = auth_rsa(authctxt, n);
00135 BN_clear_free(n);
00136
00137 return (authenticated);
00138 }
00139
00140 static int
00141 auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
00142 {
00143 int keybits, authenticated = 0;
00144 u_int bits;
00145 Key *client_host_key;
00146 u_int ulen;
00147
00148
00149
00150
00151
00152
00153 client_user = packet_get_string(&ulen);
00154
00155
00156 client_host_key = key_new(KEY_RSA1);
00157 bits = packet_get_int();
00158 packet_get_bignum(client_host_key->rsa->e);
00159 packet_get_bignum(client_host_key->rsa->n);
00160
00161 keybits = BN_num_bits(client_host_key->rsa->n);
00162 if (keybits < 0 || bits != (u_int)keybits) {
00163 verbose("Warning: keysize mismatch for client_host_key: "
00164 "actual %d, announced %d",
00165 BN_num_bits(client_host_key->rsa->n), bits);
00166 }
00167 packet_check_eom();
00168
00169 authenticated = auth_rhosts_rsa(authctxt, client_user,
00170 client_host_key);
00171 key_free(client_host_key);
00172
00173 snprintf(info, infolen, " ruser %.100s", client_user);
00174
00175 return (authenticated);
00176 }
00177
00178 static int
00179 auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
00180 {
00181 char *challenge;
00182
00183 if ((challenge = get_challenge(authctxt)) == NULL)
00184 return (0);
00185
00186 debug("sending challenge '%s'", challenge);
00187 packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
00188 packet_put_cstring(challenge);
00189 xfree(challenge);
00190 packet_send();
00191 packet_write_wait();
00192
00193 return (-1);
00194 }
00195
00196 static int
00197 auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen)
00198 {
00199 int authenticated = 0;
00200 char *response;
00201 u_int dlen;
00202
00203 response = packet_get_string(&dlen);
00204 packet_check_eom();
00205 authenticated = verify_response(authctxt, response);
00206 memset(response, 'r', dlen);
00207 xfree(response);
00208
00209 return (authenticated);
00210 }
00211
00212
00213
00214
00215
00216 static void
00217 do_authloop(Authctxt *authctxt)
00218 {
00219 int authenticated = 0;
00220 char info[1024];
00221 int prev = 0, type = 0;
00222 const struct AuthMethod1 *meth;
00223
00224 debug("Attempting authentication for %s%.100s.",
00225 authctxt->valid ? "" : "invalid user ", authctxt->user);
00226
00227
00228 if (options.password_authentication &&
00229 #ifdef KRB5
00230 (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
00231 #endif
00232 PRIVSEP(auth_password(authctxt, ""))) {
00233 #ifdef USE_PAM
00234 if (options.use_pam && (PRIVSEP(do_pam_account())))
00235 #endif
00236 {
00237 auth_log(authctxt, 1, "without authentication", "");
00238 return;
00239 }
00240 }
00241
00242
00243 packet_start(SSH_SMSG_FAILURE);
00244 packet_send();
00245 packet_write_wait();
00246
00247 for (;;) {
00248
00249 authenticated = 0;
00250
00251 info[0] = '\0';
00252
00253
00254 prev = type;
00255 type = packet_read();
00256
00257
00258
00259
00260
00261
00262
00263
00264 if (prev == SSH_CMSG_AUTH_TIS &&
00265 type != SSH_CMSG_AUTH_TIS_RESPONSE)
00266 abandon_challenge_response(authctxt);
00267
00268 if ((meth = lookup_authmethod1(type)) == NULL) {
00269 logit("Unknown message during authentication: "
00270 "type %d", type);
00271 goto skip;
00272 }
00273
00274 if (!*(meth->enabled)) {
00275 verbose("%s authentication disabled.", meth->name);
00276 goto skip;
00277 }
00278
00279 authenticated = meth->method(authctxt, info, sizeof(info));
00280 if (authenticated == -1)
00281 continue;
00282
00283 #ifdef BSD_AUTH
00284 if (authctxt->as) {
00285 auth_close(authctxt->as);
00286 authctxt->as = NULL;
00287 }
00288 #endif
00289 if (!authctxt->valid && authenticated)
00290 fatal("INTERNAL ERROR: authenticated invalid user %s",
00291 authctxt->user);
00292
00293 #ifdef _UNICOS
00294 if (authenticated && cray_access_denied(authctxt->user)) {
00295 authenticated = 0;
00296 fatal("Access denied for user %s.",authctxt->user);
00297 }
00298 #endif
00299
00300 #ifdef HAVE_CYGWIN
00301 if (authenticated &&
00302 !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,
00303 authctxt->pw)) {
00304 packet_disconnect("Authentication rejected for uid %d.",
00305 authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
00306 authenticated = 0;
00307 }
00308 #else
00309
00310 if (authenticated && authctxt->pw->pw_uid == 0 &&
00311 !auth_root_allowed(meth->name)) {
00312 authenticated = 0;
00313 # ifdef SSH_AUDIT_EVENTS
00314 PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
00315 # endif
00316 }
00317 #endif
00318
00319 #ifdef USE_PAM
00320 if (options.use_pam && authenticated &&
00321 !PRIVSEP(do_pam_account())) {
00322 char *msg;
00323 size_t len;
00324
00325 error("Access denied for user %s by PAM account "
00326 "configuration", authctxt->user);
00327 len = buffer_len(&loginmsg);
00328 buffer_append(&loginmsg, "\0", 1);
00329 msg = buffer_ptr(&loginmsg);
00330
00331 if (len > 0)
00332 while (len > 0 && msg[--len] == '\n')
00333 msg[len] = '\0';
00334 else
00335 msg = "Access denied.";
00336 packet_disconnect(msg);
00337 }
00338 #endif
00339
00340 skip:
00341
00342 auth_log(authctxt, authenticated, get_authname(type), info);
00343
00344 if (client_user != NULL) {
00345 xfree(client_user);
00346 client_user = NULL;
00347 }
00348
00349 if (authenticated)
00350 return;
00351
00352 if (authctxt->failures++ > options.max_authtries) {
00353 #ifdef SSH_AUDIT_EVENTS
00354 PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
00355 #endif
00356 packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
00357 }
00358
00359 packet_start(SSH_SMSG_FAILURE);
00360 packet_send();
00361 packet_write_wait();
00362 }
00363 }
00364
00365
00366
00367
00368
00369 void
00370 do_authentication(Authctxt *authctxt)
00371 {
00372 u_int ulen;
00373 char *user, *style = NULL;
00374
00375
00376 packet_read_expect(SSH_CMSG_USER);
00377
00378
00379 user = packet_get_string(&ulen);
00380 packet_check_eom();
00381
00382 if ((style = strchr(user, ':')) != NULL)
00383 *style++ = '\0';
00384
00385 authctxt->user = user;
00386 authctxt->style = style;
00387
00388
00389 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
00390 authctxt->valid = 1;
00391 else {
00392 debug("do_authentication: invalid user %s", user);
00393 authctxt->pw = fakepw();
00394 }
00395
00396 setproctitle("%s%s", authctxt->valid ? user : "unknown",
00397 use_privsep ? " [net]" : "");
00398
00399 #ifdef USE_PAM
00400 if (options.use_pam)
00401 PRIVSEP(start_pam(authctxt));
00402 #endif
00403
00404
00405
00406
00407
00408 #ifndef HAVE_CYGWIN
00409 if (!use_privsep && getuid() != 0 && authctxt->pw &&
00410 authctxt->pw->pw_uid != getuid())
00411 packet_disconnect("Cannot change user when server not running as root.");
00412 #endif
00413
00414
00415
00416
00417
00418 do_authloop(authctxt);
00419
00420
00421 packet_start(SSH_SMSG_SUCCESS);
00422 packet_send();
00423 packet_write_wait();
00424 }