/* Unix SMB/Netbios implementation. Version 1.9. Password cacheing. obfuscation is planned Copyright (C) Luke Kenneth Casson Leighton 1996-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" extern int DEBUGLEVEL; /**************************************************************************** initialises a password structure ****************************************************************************/ void pwd_init(struct pwd_info *pwd) { bzero(pwd->password , sizeof(pwd->password )); bzero(pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); bzero(pwd->sess_key , sizeof(pwd->sess_key )); pwd->nt_owf_len = 0; pwd->null_pwd = True; /* safest option... */ pwd->cleartext = False; pwd->crypted = False; } /**************************************************************************** de-obfuscates a password ****************************************************************************/ static void pwd_deobfuscate(struct pwd_info *pwd) { } /**************************************************************************** obfuscates a password ****************************************************************************/ static void pwd_obfuscate(struct pwd_info *pwd) { } /**************************************************************************** sets the obfuscation key info ****************************************************************************/ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) { } /**************************************************************************** reads a password ****************************************************************************/ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) { /* grab a password */ char *user_pass; pwd_init(pwd); user_pass = (char*)getpass(passwd_report); if (user_pass == NULL || user_pass[0] == 0) { pwd_set_nullpwd(pwd); } else if (do_encrypt) { pwd_make_lm_nt_16(pwd, user_pass); } else { pwd_set_cleartext(pwd, user_pass); } } /**************************************************************************** stores a cleartext password ****************************************************************************/ void pwd_set_nullpwd(struct pwd_info *pwd) { pwd_init(pwd); pwd->cleartext = False; pwd->null_pwd = True; pwd->crypted = False; } /**************************************************************************** stores a cleartext password ****************************************************************************/ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) { pwd_init(pwd); fstrcpy(pwd->password, clr); pwd->cleartext = True; pwd->null_pwd = False; pwd->crypted = False; pwd_obfuscate(pwd); } /**************************************************************************** gets a cleartext password ****************************************************************************/ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) { pwd_deobfuscate(pwd); if (pwd->cleartext) { fstrcpy(clr, pwd->password); } else { clr[0] = 0; } pwd_obfuscate(pwd); } /**************************************************************************** stores lm and nt hashed passwords ****************************************************************************/ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_init(pwd); if (lm_pwd) { memcpy(pwd->smb_lm_pwd, lm_pwd, 16); } else { bzero(pwd->smb_lm_pwd, 16); } if (nt_pwd) { memcpy(pwd->smb_nt_pwd, nt_pwd, 16); } else { bzero(pwd->smb_nt_pwd, 16); } pwd->null_pwd = False; pwd->cleartext = False; pwd->crypted = False; pwd_obfuscate(pwd); } /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); if (lm_pwd != NULL) { memcpy(lm_pwd, pwd->smb_lm_pwd, 16); } if (nt_pwd != NULL) { memcpy(nt_pwd, pwd->smb_nt_pwd, 16); } pwd_obfuscate(pwd); } /**************************************************************************** makes lm and nt hashed passwords ****************************************************************************/ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { pwd_init(pwd); nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); pwd->null_pwd = False; pwd->cleartext = False; pwd->crypted = False; pwd_obfuscate(pwd); } /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], const char *user, const char *server, const char *domain) { uchar kr[16]; DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n", user, server, domain)); pwd_deobfuscate(pwd); SMBgenclientchals(pwd->lm_cli_chal, pwd->nt_cli_chal, &pwd->nt_cli_chal_len, server, domain); ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr); /* lm # */ SMBOWFencrypt_ntv2(kr, srv_key, 8, pwd->lm_cli_chal, 8, pwd->smb_lm_owf); memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8); /* nt # */ SMBOWFencrypt_ntv2(kr, srv_key, 8, pwd->nt_cli_chal, pwd->nt_cli_chal_len, pwd->smb_nt_owf); memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len); pwd->nt_owf_len = pwd->nt_cli_chal_len + 16; SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key); #if DEBUG_PASSWORD #endif #ifdef DEBUG_PASSWORD DEBUG(100,("server cryptkey: ")); dump_data(100, srv_key, 8); DEBUG(100,("client lmv2 cryptkey: ")); dump_data(100, pwd->lm_cli_chal, 8); DEBUG(100,("client ntv2 cryptkey: ")); dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len); DEBUG(100,("ntv2_owf_passwd: ")); dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); DEBUG(100,("nt_sess_pwd: ")); dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); DEBUG(100,("lmv2_owf_passwd: ")); dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); DEBUG(100,("session key:\n")); dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); #endif pwd->crypted = True; pwd_obfuscate(pwd); } /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { if (pwd->null_pwd) { #ifdef DEBUG_PASSWORD DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n")); #endif pwd->nt_owf_len = 0; return; } pwd_deobfuscate(pwd); /* generate 24-byte hashes */ SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); pwd->nt_owf_len = 24; SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key); #ifdef DEBUG_PASSWORD DEBUG(100,("client cryptkey: ")); dump_data(100, cryptkey, 8); DEBUG(100,("nt_owf_passwd: ")); dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); DEBUG(100,("nt_sess_pwd: ")); dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); DEBUG(100,("lm_owf_passwd: ")); dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); DEBUG(100,("session key:\n")); dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); #endif pwd->crypted = True; pwd_obfuscate(pwd); } /**************************************************************************** gets lm and nt crypts ****************************************************************************/ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar *nt_owf, size_t *nt_owf_len, uchar *sess_key) { if (pwd->null_pwd) { #ifdef DEBUG_PASSWORD DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n")); #endif if (nt_owf_len != NULL) { *nt_owf_len = 0; } return; } pwd_deobfuscate(pwd); if (lm_owf != NULL) { memcpy(lm_owf, pwd->smb_lm_owf, 24); } if (nt_owf != NULL) { memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len); } if (sess_key != NULL) { memcpy(sess_key, pwd->sess_key, 16); } if (nt_owf_len != NULL) { *nt_owf_len = pwd->nt_owf_len; } pwd_obfuscate(pwd); }