Main Page | Namespace List | Class List | Directories | File List | Class Members | File Members

auth1.c File Reference

#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 AuthMethod1lookup_authmethod1 (int type)
static charget_authname (int type)
static void do_authloop (Authctxt *authctxt)
void do_authentication (Authctxt *authctxt)

Variables

ServerOptions options
Buffer loginmsg
static charclient_user = NULL
const struct AuthMethod1 auth1_methods []


Function Documentation

static int auth1_process_password Authctxt ,
char ,
size_t 
[static]
 

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 }

static int auth1_process_rhosts_rsa Authctxt ,
char ,
size_t 
[static]
 

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 }

static int auth1_process_rsa Authctxt ,
char ,
size_t 
[static]
 

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 }

static int auth1_process_tis_challenge Authctxt ,
char ,
size_t 
[static]
 

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 }

static int auth1_process_tis_response Authctxt ,
char ,
size_t 
[static]
 

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 }

void do_authentication Authctxt authctxt  ) 
 

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 }

static void do_authloop Authctxt authctxt  )  [static]
 

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 }

static char* get_authname int  type  )  [static]
 

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 }

static const struct AuthMethod1* lookup_authmethod1 int  type  )  [static]
 

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 }

RCSID "$OpenBSD: auth1.  c,
v 1.62 2005/07/16 01:35:24 djm Exp $" 
 


Variable Documentation

const struct AuthMethod1 auth1_methods[]
 

Initial value:

Definition at line 49 of file auth1.c.

char* client_user = NULL [static]
 

Definition at line 40 of file auth1.c.

Referenced by auth1_process_rhosts_rsa(), and do_authloop().

Buffer loginmsg
 

Definition at line 211 of file sshd.c.

ServerOptions options
 

Definition at line 110 of file ssh.c.


© sourcejam.com 2005-2008