#include "includes.h"#include "xmalloc.h"#include "rsa.h"#include "ssh1.h"#include "packet.h"#include "buffer.h"#include "log.h"#include "servconf.h"#include "compat.h"#include "auth.h"#include "channels.h"#include "session.h"#include "uidswap.h"#include "monitor_wrap.h"Go to the source code of this file.
Classes | |
| struct | AuthMethod1 |
Functions | |
| RCSID ("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $") | |
| static int | auth1_process_password (Authctxt *, char *, size_t) |
| static int | auth1_process_rsa (Authctxt *, char *, size_t) |
| static int | auth1_process_rhosts_rsa (Authctxt *, char *, size_t) |
| static int | auth1_process_tis_challenge (Authctxt *, char *, size_t) |
| static int | auth1_process_tis_response (Authctxt *, char *, size_t) |
| static const struct AuthMethod1 * | lookup_authmethod1 (int type) |
| static char * | get_authname (int type) |
| static void | do_authloop (Authctxt *authctxt) |
| void | do_authentication (Authctxt *authctxt) |
Variables | |
| ServerOptions | options |
| Buffer | loginmsg |
| static char * | client_user = NULL |
| const struct AuthMethod1 | auth1_methods [] |
|
||||||||||||||||
|
Definition at line 100 of file auth1.c. References auth_password(), packet_check_eom, packet_get_string(), PRIVSEP, and xfree(). 00101 { 00102 int authenticated = 0; 00103 char *password; 00104 u_int dlen; 00105 00106 /* 00107 * Read user password. It is in plain text, but was 00108 * transmitted over the encrypted channel so it is 00109 * not visible to an outside observer. 00110 */ 00111 password = packet_get_string(&dlen); 00112 packet_check_eom(); 00113 00114 /* Try authentication with the password. */ 00115 authenticated = PRIVSEP(auth_password(authctxt, password)); 00116 00117 memset(password, 0, dlen); 00118 xfree(password); 00119 00120 return (authenticated); 00121 }
|
|
||||||||||||||||
|
Definition at line 141 of file auth1.c. References auth_rhosts_rsa(), bits, client_user, key_free(), key_new(), KEY_RSA1, packet_check_eom, packet_get_bignum(), packet_get_int(), packet_get_string(), Key::rsa, snprintf(), and verbose(). 00142 { 00143 int keybits, authenticated = 0; 00144 u_int bits; 00145 Key *client_host_key; 00146 u_int ulen; 00147 00148 /* 00149 * Get client user name. Note that we just have to 00150 * trust the client; root on the client machine can 00151 * claim to be any user. 00152 */ 00153 client_user = packet_get_string(&ulen); 00154 00155 /* Get the client host key. */ 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 }
|
|
||||||||||||||||
|
Definition at line 124 of file auth1.c. References auth_rsa(), fatal(), packet_check_eom, and packet_get_bignum(). 00125 { 00126 int authenticated = 0; 00127 BIGNUM *n; 00128 00129 /* RSA authentication requested. */ 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 }
|
|
||||||||||||||||
|
Definition at line 179 of file auth1.c. References debug(), get_challenge(), packet_put_cstring(), packet_send(), packet_start(), packet_write_wait(), SSH_SMSG_AUTH_TIS_CHALLENGE, and xfree(). 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 }
|
|
||||||||||||||||
|
Definition at line 197 of file auth1.c. References packet_check_eom, packet_get_string(), response(), verify_response(), and xfree(). 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 }
|
|
|
Definition at line 370 of file auth1.c. References debug(), do_authloop(), fakepw(), getpwnamallow(), packet_check_eom, packet_disconnect(), packet_get_string(), packet_read_expect(), packet_send(), packet_start(), packet_write_wait(), PRIVSEP, Authctxt::pw, setproctitle(), SSH_CMSG_USER, SSH_SMSG_SUCCESS, Authctxt::style, ServerOptions::use_pam, use_privsep, Authctxt::user, and Authctxt::valid. Referenced by main(). 00371 { 00372 u_int ulen; 00373 char *user, *style = NULL; 00374 00375 /* Get the name of the user that we wish to log in as. */ 00376 packet_read_expect(SSH_CMSG_USER); 00377 00378 /* Get the user name. */ 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 /* Verify that the user is a valid user. */ 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 * If we are not running as root, the user must have the same uid as 00406 * the server. 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 * Loop until the user has been authenticated or the connection is 00416 * closed, do_authloop() returns only if authentication is successful 00417 */ 00418 do_authloop(authctxt); 00419 00420 /* The user has been authenticated and accepted. */ 00421 packet_start(SSH_SMSG_SUCCESS); 00422 packet_send(); 00423 packet_write_wait(); 00424 }
|
|
|
Definition at line 217 of file auth1.c. References abandon_challenge_response(), AUTH_FAIL_MSG, auth_log(), auth_password(), auth_root_allowed(), buffer_append(), buffer_len(), buffer_ptr(), client_user, debug(), AuthMethod1::enabled, error(), fatal(), get_authname(), ServerOptions::kerberos_authentication, ServerOptions::kerberos_or_local_passwd, logit(), lookup_authmethod1(), ServerOptions::max_authtries, AuthMethod1::method, AuthMethod1::name, packet_disconnect(), packet_read(), packet_send(), packet_start(), packet_write_wait(), ServerOptions::password_authentication, PRIVSEP, SSH_CMSG_AUTH_PASSWORD, SSH_CMSG_AUTH_TIS, SSH_CMSG_AUTH_TIS_RESPONSE, SSH_SMSG_FAILURE, AuthMethod1::type, ServerOptions::use_pam, Authctxt::user, Authctxt::valid, verbose(), and xfree(). Referenced by do_authentication(). 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 /* If the user has no password, accept authentication immediately. */ 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 /* Indicate that authentication is needed. */ 00243 packet_start(SSH_SMSG_FAILURE); 00244 packet_send(); 00245 packet_write_wait(); 00246 00247 for (;;) { 00248 /* default to fail */ 00249 authenticated = 0; 00250 00251 info[0] = '\0'; 00252 00253 /* Get a packet from the client. */ 00254 prev = type; 00255 type = packet_read(); 00256 00257 /* 00258 * If we started challenge-response authentication but the 00259 * next packet is not a response to our challenge, release 00260 * the resources allocated by get_challenge() (which would 00261 * normally have been released by verify_response() had we 00262 * received such a response) 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; /* "postponed" */ 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 /* _UNICOS */ 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 /* Special handling for root */ 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 /* strip trailing newlines */ 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 /* Log before sending the reply */ 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 }
|
|
|
Definition at line 88 of file auth1.c. References lookup_authmethod1(), AuthMethod1::name, and snprintf(). Referenced by do_authloop(). 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 }
|
|
|
Definition at line 76 of file auth1.c. References AuthMethod1::name. Referenced by do_authloop(), and get_authname(). 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 }
|
|
||||||||||||
|
|
|
|
Initial value: {
{
SSH_CMSG_AUTH_PASSWORD, "password",
&options.password_authentication, auth1_process_password
},
{
SSH_CMSG_AUTH_RSA, "rsa",
&options.rsa_authentication, auth1_process_rsa
},
{
SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa",
&options.rhosts_rsa_authentication, auth1_process_rhosts_rsa
},
{
SSH_CMSG_AUTH_TIS, "challenge-response",
&options.challenge_response_authentication,
auth1_process_tis_challenge
},
{
SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response",
&options.challenge_response_authentication,
auth1_process_tis_response
},
{ -1, NULL, NULL, NULL}
}
|
|
|
Definition at line 40 of file auth1.c. Referenced by auth1_process_rhosts_rsa(), and do_authloop(). |
|
|
|
|
|
|