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