]> andersk Git - openssh.git/blob - auth1.c
- (djm) Big OpenBSD sync:
[openssh.git] / auth1.c
1 /*
2  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3  *                    All rights reserved
4  *
5  * As far as I am concerned, the code I have written for this software
6  * can be used freely for any purpose.  Any derived versions of this
7  * software must be clearly marked as such, and if the derived work is
8  * incompatible with the protocol description in the RFC file, it must be
9  * called by a name other than "ssh" or "Secure Shell".
10  */
11
12 #include "includes.h"
13 RCSID("$OpenBSD: auth1.c,v 1.6 2000/10/11 20:27:23 markus Exp $");
14
15 #ifdef HAVE_OSF_SIA
16 # include <sia.h>
17 # include <siad.h>
18 #endif
19
20 #include "xmalloc.h"
21 #include "rsa.h"
22 #include "ssh.h"
23 #include "packet.h"
24 #include "buffer.h"
25 #include "mpaux.h"
26 #include "servconf.h"
27 #include "compat.h"
28 #include "auth.h"
29 #include "session.h"
30
31 /* import */
32 extern ServerOptions options;
33 extern char *forced_command;
34
35 #ifdef WITH_AIXAUTHENTICATE
36 extern char *aixloginmsg;
37 #endif /* WITH_AIXAUTHENTICATE */
38 #ifdef HAVE_OSF_SIA
39 extern int saved_argc;
40 extern char **saved_argv;
41 #endif /* HAVE_OSF_SIA */
42
43 /*
44  * convert ssh auth msg type into description
45  */
46 char *
47 get_authname(int type)
48 {
49         static char buf[1024];
50         switch (type) {
51         case SSH_CMSG_AUTH_PASSWORD:
52                 return "password";
53         case SSH_CMSG_AUTH_RSA:
54                 return "rsa";
55         case SSH_CMSG_AUTH_RHOSTS_RSA:
56                 return "rhosts-rsa";
57         case SSH_CMSG_AUTH_RHOSTS:
58                 return "rhosts";
59 #ifdef KRB4
60         case SSH_CMSG_AUTH_KERBEROS:
61                 return "kerberos";
62 #endif
63 #ifdef SKEY
64         case SSH_CMSG_AUTH_TIS_RESPONSE:
65                 return "s/key";
66 #endif
67         }
68         snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
69         return buf;
70 }
71
72 /*
73  * read packets and try to authenticate local user 'luser'.
74  * return if authentication is successfull. not that pw == NULL
75  * if the user does not exists or is not allowed to login.
76  * each auth method has to 'fake' authentication for nonexisting
77  * users.
78  */
79 void
80 do_authloop(struct passwd * pw, char *luser)
81 {
82         int authenticated = 0;
83         int attempt = 0;
84         unsigned int bits;
85         RSA *client_host_key;
86         BIGNUM *n;
87         char *client_user, *password;
88         char user[1024];
89         unsigned int dlen;
90         int plen, nlen, elen;
91         unsigned int ulen;
92         int type = 0;
93         void (*authlog) (const char *fmt,...) = verbose;
94
95         /* Indicate that authentication is needed. */
96         packet_start(SSH_SMSG_FAILURE);
97         packet_send();
98         packet_write_wait();
99
100         client_user = NULL;
101
102         for (attempt = 1;; attempt++) {
103                 /* default to fail */
104                 authenticated = 0;
105
106                 strlcpy(user, "", sizeof user);
107
108                 /* Get a packet from the client. */
109                 type = packet_read(&plen);
110
111                 /* Process the packet. */
112                 switch (type) {
113 #ifdef AFS
114                 case SSH_CMSG_HAVE_KERBEROS_TGT:
115                         if (!options.kerberos_tgt_passing) {
116                                 verbose("Kerberos tgt passing disabled.");
117                                 break;
118                         } else {
119                                 /* Accept Kerberos tgt. */
120                                 char *tgt = packet_get_string(&dlen);
121                                 packet_integrity_check(plen, 4 + dlen, type);
122                                 if (!auth_kerberos_tgt(pw, tgt))
123                                         verbose("Kerberos tgt REFUSED for %.100s", luser);
124                                 xfree(tgt);
125                         }
126                         continue;
127
128                 case SSH_CMSG_HAVE_AFS_TOKEN:
129                         if (!options.afs_token_passing || !k_hasafs()) {
130                                 verbose("AFS token passing disabled.");
131                                 break;
132                         } else {
133                                 /* Accept AFS token. */
134                                 char *token_string = packet_get_string(&dlen);
135                                 packet_integrity_check(plen, 4 + dlen, type);
136                                 if (!auth_afs_token(pw, token_string))
137                                         verbose("AFS token REFUSED for %.100s", luser);
138                                 xfree(token_string);
139                         }
140                         continue;
141 #endif /* AFS */
142 #ifdef KRB4
143                 case SSH_CMSG_AUTH_KERBEROS:
144                         if (!options.kerberos_authentication) {
145                                 /* packet_get_all(); */
146                                 verbose("Kerberos authentication disabled.");
147                                 break;
148                         } else {
149                                 /* Try Kerberos v4 authentication. */
150                                 KTEXT_ST auth;
151                                 char *tkt_user = NULL;
152                                 char *kdata = packet_get_string((unsigned int *) &auth.length);
153                                 packet_integrity_check(plen, 4 + auth.length, type);
154
155                                 if (auth.length < MAX_KTXT_LEN)
156                                         memcpy(auth.dat, kdata, auth.length);
157                                 xfree(kdata);
158
159                                 if (pw != NULL) {
160                                         authenticated = auth_krb4(pw->pw_name, &auth, &tkt_user);
161                                         if (authenticated) {
162                                                 snprintf(user, sizeof user, " tktuser %s", tkt_user);
163                                                 xfree(tkt_user);
164                                         }
165                                 }
166                         }
167                         break;
168 #endif /* KRB4 */
169
170                 case SSH_CMSG_AUTH_RHOSTS:
171                         if (!options.rhosts_authentication) {
172                                 verbose("Rhosts authentication disabled.");
173                                 break;
174                         }
175                         /*
176                          * Get client user name.  Note that we just have to
177                          * trust the client; this is one reason why rhosts
178                          * authentication is insecure. (Another is
179                          * IP-spoofing on a local network.)
180                          */
181                         client_user = packet_get_string(&ulen);
182                         packet_integrity_check(plen, 4 + ulen, type);
183
184                         /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
185                         authenticated = auth_rhosts(pw, client_user);
186
187                         snprintf(user, sizeof user, " ruser %s", client_user);
188                         break;
189
190                 case SSH_CMSG_AUTH_RHOSTS_RSA:
191                         if (!options.rhosts_rsa_authentication) {
192                                 verbose("Rhosts with RSA authentication disabled.");
193                                 break;
194                         }
195                         /*
196                          * Get client user name.  Note that we just have to
197                          * trust the client; root on the client machine can
198                          * claim to be any user.
199                          */
200                         client_user = packet_get_string(&ulen);
201
202                         /* Get the client host key. */
203                         client_host_key = RSA_new();
204                         if (client_host_key == NULL)
205                                 fatal("RSA_new failed");
206                         client_host_key->e = BN_new();
207                         client_host_key->n = BN_new();
208                         if (client_host_key->e == NULL || client_host_key->n == NULL)
209                                 fatal("BN_new failed");
210                         bits = packet_get_int();
211                         packet_get_bignum(client_host_key->e, &elen);
212                         packet_get_bignum(client_host_key->n, &nlen);
213
214                         if (bits != BN_num_bits(client_host_key->n))
215                                 verbose("Warning: keysize mismatch for client_host_key: "
216                                     "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
217                         packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
218
219                         authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
220                         RSA_free(client_host_key);
221
222                         snprintf(user, sizeof user, " ruser %s", client_user);
223                         break;
224
225                 case SSH_CMSG_AUTH_RSA:
226                         if (!options.rsa_authentication) {
227                                 verbose("RSA authentication disabled.");
228                                 break;
229                         }
230                         /* RSA authentication requested. */
231                         n = BN_new();
232                         packet_get_bignum(n, &nlen);
233                         packet_integrity_check(plen, nlen, type);
234                         authenticated = auth_rsa(pw, n);
235                         BN_clear_free(n);
236                         break;
237
238                 case SSH_CMSG_AUTH_PASSWORD:
239                         if (!options.password_authentication) {
240                                 verbose("Password authentication disabled.");
241                                 break;
242                         }
243                         /*
244                          * Read user password.  It is in plain text, but was
245                          * transmitted over the encrypted channel so it is
246                          * not visible to an outside observer.
247                          */
248                         password = packet_get_string(&dlen);
249                         packet_integrity_check(plen, 4 + dlen, type);
250
251 #ifdef USE_PAM
252                         /* Do PAM auth with password */
253                         authenticated = auth_pam_password(pw, password);
254 #elif defined(HAVE_OSF_SIA)
255                         /* Do SIA auth with password */
256                         if (sia_validate_user(NULL, saved_argc, saved_argv, 
257                                 get_canonical_hostname(), pw->pw_name, NULL, 0, 
258                                 NULL, password) == SIASUCCESS) {
259                                 authenticated = 1;
260                         }
261 #else /* !USE_PAM && !HAVE_OSF_SIA */
262                         /* Try authentication with the password. */
263                         authenticated = auth_password(pw, password);
264 #endif /* USE_PAM */
265
266                         memset(password, 0, strlen(password));
267                         xfree(password);
268                         break;
269
270 #ifdef SKEY
271                 case SSH_CMSG_AUTH_TIS:
272                         debug("rcvd SSH_CMSG_AUTH_TIS");
273                         if (options.skey_authentication == 1) {
274                                 char *skeyinfo = NULL;
275                                 if (pw != NULL)
276                                         skey_keyinfo(pw->pw_name);
277                                 if (skeyinfo == NULL) {
278                                         debug("generating fake skeyinfo for %.100s.", luser);
279                                         skeyinfo = skey_fake_keyinfo(luser);
280                                 }
281                                 if (skeyinfo != NULL) {
282                                         /* we send our s/key- in tis-challenge messages */
283                                         debug("sending challenge '%s'", skeyinfo);
284                                         packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
285                                         packet_put_cstring(skeyinfo);
286                                         packet_send();
287                                         packet_write_wait();
288                                         continue;
289                                 }
290                         }
291                         break;
292                 case SSH_CMSG_AUTH_TIS_RESPONSE:
293                         debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
294                         if (options.skey_authentication == 1) {
295                                 char *response = packet_get_string(&dlen);
296                                 debug("skey response == '%s'", response);
297                                 packet_integrity_check(plen, 4 + dlen, type);
298                                 authenticated = (pw != NULL &&
299                                     skey_haskey(pw->pw_name) == 0 &&
300                                     skey_passcheck(pw->pw_name, response) != -1);
301                                 xfree(response);
302                         }
303                         break;
304 #else
305                 case SSH_CMSG_AUTH_TIS:
306                         /* TIS Authentication is unsupported */
307                         log("TIS authentication unsupported.");
308                         break;
309 #endif
310
311                 default:
312                         /*
313                          * Any unknown messages will be ignored (and failure
314                          * returned) during authentication.
315                          */
316                         log("Unknown message during authentication: type %d", type);
317                         break;
318                 }
319                 if (authenticated && pw == NULL)
320                         fatal("internal error: authenticated for pw == NULL");
321
322 #ifdef HAVE_CYGWIN
323                 if (authenticated && 
324                     !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
325                         packet_disconnect("Authentication rejected for uid %d.",
326                         (int)pw->pw_uid);
327                         authenticated = 0;
328                 }
329 #endif
330
331                 /*
332                  * Check if the user is logging in as root and root logins
333                  * are disallowed.
334                  * Note that root login is allowed for forced commands.
335                  */
336                 if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) {
337                         if (forced_command) {
338                                 log("Root login accepted for forced command.");
339                         } else {
340                                 authenticated = 0;
341                                 log("ROOT LOGIN REFUSED FROM %.200s",
342                                     get_canonical_hostname());
343                         }
344                 }
345
346                 /* Raise logging level */
347                 if (authenticated ||
348                     attempt == AUTH_FAIL_LOG ||
349                     type == SSH_CMSG_AUTH_PASSWORD)
350                         authlog = log;
351
352                 authlog("%s %s for %s%.100s from %.200s port %d%s",
353                         authenticated ? "Accepted" : "Failed",
354                         get_authname(type),
355                         pw ? "" : "illegal user ",
356                         pw && pw->pw_uid == 0 ? "ROOT" : luser,
357                         get_remote_ipaddr(),
358                         get_remote_port(),
359                         user);
360
361 #ifdef USE_PAM
362                 if (authenticated && !do_pam_account(pw->pw_name, client_user))
363                         authenticated = 0;
364 #endif
365
366                 if (client_user != NULL) {
367                         xfree(client_user);
368                         client_user = NULL;
369                 }
370
371                 if (authenticated)
372                         return;
373
374                 if (attempt > AUTH_FAIL_MAX) {
375 #ifdef WITH_AIXAUTHENTICATE 
376                         loginfailed(user,get_canonical_hostname(),"ssh");
377 #endif /* WITH_AIXAUTHENTICATE */
378                         packet_disconnect(AUTH_FAIL_MSG, luser);
379                 }
380
381                 /* Send a message indicating that the authentication attempt failed. */
382                 packet_start(SSH_SMSG_FAILURE);
383                 packet_send();
384                 packet_write_wait();
385         }
386 }
387
388 /*
389  * Performs authentication of an incoming connection.  Session key has already
390  * been exchanged and encryption is enabled.
391  */
392 void
393 do_authentication()
394 {
395         struct passwd *pw, pwcopy;
396         int plen;
397         unsigned int ulen;
398         char *user;
399
400         /* Get the name of the user that we wish to log in as. */
401         packet_read_expect(&plen, SSH_CMSG_USER);
402
403         /* Get the user name. */
404         user = packet_get_string(&ulen);
405         packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
406
407         setproctitle("%s", user);
408
409 #ifdef AFS
410         /* If machine has AFS, set process authentication group. */
411         if (k_hasafs()) {
412                 k_setpag();
413                 k_unlog();
414         }
415 #endif /* AFS */
416
417         /* Verify that the user is a valid user. */
418         pw = getpwnam(user);
419         if (pw && allowed_user(pw)) {
420                 /* Take a copy of the returned structure. */
421                 memset(&pwcopy, 0, sizeof(pwcopy));
422                 pwcopy.pw_name = xstrdup(pw->pw_name);
423                 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
424                 pwcopy.pw_uid = pw->pw_uid;
425                 pwcopy.pw_gid = pw->pw_gid;
426 #ifdef HAVE_PW_CLASS_IN_PASSWD
427                 pwcopy.pw_class = xstrdup(pw->pw_class);
428 #endif
429                 pwcopy.pw_dir = xstrdup(pw->pw_dir);
430                 pwcopy.pw_shell = xstrdup(pw->pw_shell);
431                 pw = &pwcopy;
432         } else {
433                 pw = NULL;
434         }
435
436 #ifdef USE_PAM
437         if (pw)
438                 start_pam(pw);
439 #endif
440
441         /*
442          * If we are not running as root, the user must have the same uid as
443          * the server. (Unless you are running Windows)
444          */
445 #ifndef HAVE_CYGWIN
446         if (getuid() != 0 && pw && pw->pw_uid != getuid())
447                 packet_disconnect("Cannot change user when server not running as root.");
448 #endif
449
450         debug("Attempting authentication for %s%.100s.", pw ? "" : "illegal user ", user);
451
452         /* If the user has no password, accept authentication immediately. */
453         if (options.password_authentication &&
454 #ifdef KRB4
455             (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
456 #endif /* KRB4 */
457 #ifdef USE_PAM
458             auth_pam_password(pw, "")) {
459 #elif defined(HAVE_OSF_SIA)
460             (sia_validate_user(NULL, saved_argc, saved_argv, 
461             get_canonical_hostname(), pw->pw_name, NULL, 0, 
462                  NULL, "") == SIASUCCESS)) {
463 #else /* !HAVE_OSF_SIA && !USE_PAM */
464             auth_password(pw, "")) {
465 #endif /* USE_PAM */
466                 /* Authentication with empty password succeeded. */
467                 log("Login for user %s from %.100s, accepted without authentication.",
468                     user, get_remote_ipaddr());
469         } else {
470                 /* Loop until the user has been authenticated or the
471                    connection is closed, do_authloop() returns only if
472                    authentication is successfull */
473                 do_authloop(pw, user);
474         }
475         if (pw == NULL)
476                 fatal("internal error, authentication successfull for user '%.100s'", user);
477
478         /* The user has been authenticated and accepted. */
479         packet_start(SSH_SMSG_SUCCESS);
480         packet_send();
481         packet_write_wait();
482
483 #ifdef WITH_AIXAUTHENTICATE
484         /* We don't have a pty yet, so just label the line as "ssh" */
485         if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
486                 aixloginmsg = NULL;
487 #endif /* WITH_AIXAUTHENTICATE */
488
489         /* Perform session preparation. */
490         do_authenticated(pw);
491 }
This page took 0.175822 seconds and 5 git commands to generate.