From 66d5d73a5d75e88a77970f7b27687b8354ab2e80 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 25 Sep 1998 21:01:52 +0000 Subject: added rpcclient program (This used to be commit aa38f39d67fade4dfd7badb7a9b39c833a1dd1ca) --- source3/libsmb/clientgen.c | 173 +++++++++++++++++++++++++++++--- source3/libsmb/pwd_cache.c | 236 ++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbencrypt.c | 35 +++++++ 3 files changed, 432 insertions(+), 12 deletions(-) create mode 100644 source3/libsmb/pwd_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c85de92989..89caad419f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1604,31 +1604,26 @@ BOOL cli_negprot(struct cli_state *cli) /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + memcpy(&(cli->calling), calling, sizeof(*calling)); + memcpy(&(cli->called ), called , sizeof(*called )); - p = strchr(dest,'.'); - if (p) *p = 0; - - fstrcpy(cli->desthost, dest); - /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length */ @@ -1754,3 +1749,157 @@ int cli_setpid(struct cli_state *cli, int pid) cli->pid = pid; return ret; } + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_reestablish_connection(struct cli_state *cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + struct in_addr dest_ip; + fstring share; + fstring dev; + BOOL do_tcon = False; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG(3,("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy(share, cli->share); + fstrcpy(dev , cli->dev); + do_tcon = True; + } + + memcpy(&called , &(cli->called ), sizeof(called )); + memcpy(&calling, &(cli->calling), sizeof(calling)); + fstrcpy(dest_host, cli->full_dest_host_name); + dest_ip = cli->dest_ip; + + DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + namestr(&calling), namestr(&called), inet_ntoa(dest_ip), + cli->user_name, cli->domain)); + + return cli_establish_connection(cli, + dest_host, &dest_ip, + &calling, &called, + share, dev, False, do_tcon); +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + namestr(calling), namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect(cli, dest_host, dest_ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + namestr(calling), inet_ntoa(*dest_ip))); + return False; + } + } + + if (!cli_session_request(cli, calling, called)) + { + DEBUG(1,("failed session request\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + /* attempt clear-text session */ + + fstring passwd; + + pwd_get_cleartext(&(cli->pwd), passwd); + + /* attempt clear-text session */ + if (!cli_session_setup(cli, cli->user_name, + passwd, strlen(passwd), + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)passwd, strlen(passwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + else + { + /* attempt encrypted session */ + uchar nt_sess_pwd[24]; + uchar lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + + if (do_shutdown) cli_shutdown(cli); + + return True; +} diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c new file mode 100644 index 0000000000..e799a5458c --- /dev/null +++ b/source3/libsmb/pwd_cache.c @@ -0,0 +1,236 @@ +/* + 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)); + + 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, char lm_pwd[16], char 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, char lm_pwd[16], char nt_pwd[16]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_pwd, pwd->smb_lm_pwd, 16); + 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_owf(struct pwd_info *pwd, char cryptkey[8]) +{ + pwd_deobfuscate(pwd); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("client cryptkey: ")); + dump_data(100, cryptkey, 8); +#endif + + SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("nt_sess_pwd: ")); + dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); +#endif + + SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("lm_sess_pwd: ")); + dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); +#endif + + pwd->crypted = True; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets lm and nt crypts + ****************************************************************************/ +void pwd_get_lm_nt_owf(struct pwd_info *pwd, char lm_owf[24], char nt_owf[24]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_owf, pwd->smb_lm_owf, 24); + memcpy(nt_owf, pwd->smb_nt_owf, 24); + pwd_obfuscate(pwd); +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6840f2e2c8..5a946e22c9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -97,6 +97,41 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +{ + char passwd[130]; + StrnCpy(passwd, pwd, sizeof(passwd)-1); + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, (uchar *)p16); + + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + memcpy(p21, passwd, 16); + E_P24(p21, c8, p24); +} + + /* Does the NT MD4 hash then des encryption. */ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) -- cgit