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