Annotation of src/usr.bin/ssh/auth-passwd.c, Revision 1.9
1.1 deraadt 1: /*
2:
3: auth-passwd.c
4:
5: Author: Tatu Ylonen <ylo@cs.hut.fi>
6:
7: Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8: All rights reserved
9:
10: Created: Sat Mar 18 05:11:38 1995 ylo
11:
12: Password authentication. This file contains the functions to check whether
13: the password is valid for the user.
14:
15: */
16:
17: #include "includes.h"
1.9 ! markus 18: RCSID("$Id: auth-passwd.c,v 1.8 1999/10/19 15:56:41 deraadt Exp $");
1.1 deraadt 19:
20: #include "packet.h"
21: #include "ssh.h"
22: #include "servconf.h"
23: #include "xmalloc.h"
24:
25: /* Tries to authenticate the user using password. Returns true if
26: authentication succeeds. */
27:
1.6 markus 28: int auth_password(struct passwd *pw, const char *password)
1.1 deraadt 29: {
30: extern ServerOptions options;
31: char *encrypted_password;
1.7 markus 32:
33: if (pw->pw_uid == 0 && options.permit_root_login == 2)
34: {
1.8 deraadt 35: /*packet_send_debug("Server does not permit root login with password.");*/
1.7 markus 36: return 0;
37: }
1.1 deraadt 38:
39: if (*password == '\0' && options.permit_empty_passwd == 0)
40: {
1.8 deraadt 41: /*packet_send_debug("Server does not permit empty password login.");*/
1.1 deraadt 42: return 0;
43: }
44:
1.6 markus 45: /* deny if no user. */
46: if (pw == NULL)
1.1 deraadt 47: return 0;
48:
1.6 markus 49: #ifdef SKEY
50: if (options.skey_authentication == 1) {
51: if (strncasecmp(password, "s/key", 5) == 0) {
52: char *skeyinfo = skey_keyinfo(pw->pw_name);
53: if(skeyinfo == NULL){
54: debug("generating fake skeyinfo for %.100s.", pw->pw_name);
55: skeyinfo = skey_fake_keyinfo(pw->pw_name);
56: }
57: if(skeyinfo != NULL)
58: packet_send_debug(skeyinfo);
59: /* Try again. */
60: return 0;
61: }
62: else if (skey_haskey(pw->pw_name) == 0 &&
63: skey_passcheck(pw->pw_name, (char *)password) != -1) {
64: /* Authentication succeeded. */
65: return 1;
66: }
67: /* Fall back to ordinary passwd authentication. */
68: }
69: #endif
70:
1.2 dugsong 71: #if defined(KRB4)
72: /* Support for Kerberos v4 authentication - Dug Song <dugsong@UMICH.EDU> */
73: if (options.kerberos_authentication)
74: {
75: AUTH_DAT adata;
76: KTEXT_ST tkt;
77: struct hostent *hp;
78: unsigned long faddr;
1.9 ! markus 79: char localhost[MAXHOSTNAMELEN];
! 80: char phost[INST_SZ];
! 81: char realm[REALM_SZ];
1.2 dugsong 82: int r;
83:
84: /* Try Kerberos password authentication only for non-root
85: users and only if Kerberos is installed. */
86: if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
87:
88: /* Set up our ticket file. */
1.9 ! markus 89: if (!krb4_init(pw->pw_uid)) {
! 90: log("Couldn't initialize Kerberos ticket file for %s!", pw->pw_name);
1.2 dugsong 91: goto kerberos_auth_failure;
92: }
93: /* Try to get TGT using our password. */
1.6 markus 94: r = krb_get_pw_in_tkt((char *)pw->pw_name, "", realm, "krbtgt", realm,
1.2 dugsong 95: DEFAULT_TKT_LIFE, (char *)password);
96: if (r != INTK_OK) {
97: packet_send_debug("Kerberos V4 password authentication for %s "
1.6 markus 98: "failed: %s", pw->pw_name, krb_err_txt[r]);
1.2 dugsong 99: goto kerberos_auth_failure;
100: }
101: /* Successful authentication. */
1.9 ! markus 102: chown(tkt_string(), pw->pw_uid, pw->pw_gid);
1.2 dugsong 103:
1.9 ! markus 104: /* Now that we have a TGT, try to get a local "rcmd" ticket to
! 105: ensure that we are not talking to a bogus Kerberos server. */
1.2 dugsong 106: (void) gethostname(localhost, sizeof(localhost));
1.3 deraadt 107: (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ);
1.2 dugsong 108: r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
109:
110: if (r == KSUCCESS) {
111: if (!(hp = gethostbyname(localhost))) {
112: log("Couldn't get local host address!");
113: goto kerberos_auth_failure;
114: }
115: memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr));
116:
117: /* Verify our "rcmd" ticket. */
118: r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, "");
119: if (r == RD_AP_UNDEC) {
120: /* Probably didn't have a srvtab on localhost. Allow login. */
121: log("Kerberos V4 TGT for %s unverifiable, no srvtab installed? "
1.6 markus 122: "krb_rd_req: %s", pw->pw_name, krb_err_txt[r]);
1.2 dugsong 123: }
124: else if (r != KSUCCESS) {
125: log("Kerberos V4 %s ticket unverifiable: %s",
126: KRB4_SERVICE_NAME, krb_err_txt[r]);
127: goto kerberos_auth_failure;
128: }
129: }
130: else if (r == KDC_PR_UNKNOWN) {
131: /* Allow login if no rcmd service exists, but log the error. */
132: log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
1.6 markus 133: "not registered, or srvtab is wrong?", pw->pw_name,
1.2 dugsong 134: krb_err_txt[r], KRB4_SERVICE_NAME, phost);
135: }
136: else {
137: /* TGT is bad, forget it. Possibly spoofed! */
138: packet_send_debug("WARNING: Kerberos V4 TGT possibly spoofed for"
1.6 markus 139: "%s: %s", pw->pw_name, krb_err_txt[r]);
1.2 dugsong 140: goto kerberos_auth_failure;
141: }
142:
143: /* Authentication succeeded. */
144: return 1;
145:
146: kerberos_auth_failure:
1.9 ! markus 147: krb4_cleanup_proc(NULL);
! 148:
! 149: if (!options.kerberos_or_local_passwd)
! 150: return 0;
1.2 dugsong 151: }
152: else {
153: /* Logging in as root or no local Kerberos realm. */
154: packet_send_debug("Unable to authenticate to Kerberos.");
155: }
156: /* Fall back to ordinary passwd authentication. */
157: }
158: #endif /* KRB4 */
1.6 markus 159:
1.1 deraadt 160: /* Check for users with no password. */
1.6 markus 161: if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
1.1 deraadt 162: {
163: packet_send_debug("Login permitted without a password because the account has no password.");
164: return 1; /* The user has no password and an empty password was tried. */
165: }
166:
167: /* Encrypt the candidate password using the proper salt. */
168: encrypted_password = crypt(password,
1.6 markus 169: (pw->pw_passwd[0] && pw->pw_passwd[1]) ?
170: pw->pw_passwd : "xx");
1.1 deraadt 171:
172: /* Authentication is accepted if the encrypted passwords are identical. */
1.6 markus 173: return (strcmp(encrypted_password, pw->pw_passwd) == 0);
1.1 deraadt 174: }