/*
 *   fs/cifs/sess.c
 *
 *   SMB/CIFS session setup handling routines
 *
 *   Copyright (c) International Business Machines  Corp., 2006
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 *   This library 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 Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
#include "ntlmssp.h"
#include "nterr.h"
#include <linux/utsname.h>

extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
                         unsigned char *p24);

static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
{
	__u32 capabilities = 0;

	/* init fields common to all four types of SessSetup */
	/* note that header is initialized to zero in header_assemble */
	pSMB->req.AndXCommand = 0xFF;
	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);

	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */

	/* BB verify whether signing required on neg or just on auth frame 
	   (and NTLM case) */

	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;

	if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;

	if (ses->capabilities & CAP_UNICODE) {
		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
		capabilities |= CAP_UNICODE;
	}
	if (ses->capabilities & CAP_STATUS32) {
		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
		capabilities |= CAP_STATUS32;
	}
	if (ses->capabilities & CAP_DFS) {
		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
		capabilities |= CAP_DFS;
	}
	if (ses->capabilities & CAP_UNIX) {
		capabilities |= CAP_UNIX;
	}

	/* BB check whether to init vcnum BB */
	return capabilities;
}

static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
			    const struct nls_table * nls_cp)
{
	char * bcc_ptr = *pbcc_area;
	int bytes_ret = 0;

	/* BB FIXME add check that strings total less
	than 335 or will need to send them as arrays */

	/* unicode strings, must be word aligned before the call */
/*	if ((long) bcc_ptr % 2)	{
		*bcc_ptr = 0;
		bcc_ptr++;
	} */
	/* copy user */
	if(ses->userName == NULL) {
		/* BB what about null user mounts - check that we do this BB */
	} else { /* 300 should be long enough for any conceivable user name */
		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
					  300, nls_cp);
	}
	bcc_ptr += 2 * bytes_ret;
	bcc_ptr += 2; /* account for null termination */
	/* copy domain */
	if(ses->domainName == NULL)
		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
					  "CIFS_LINUX_DOM", 32, nls_cp);
	else
		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 
					  256, nls_cp);
	bcc_ptr += 2 * bytes_ret;
	bcc_ptr += 2;  /* account for null terminator */

	/* Copy OS version */
	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
				  nls_cp);
	bcc_ptr += 2 * bytes_ret;
	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
				  32, nls_cp);
	bcc_ptr += 2 * bytes_ret;
	bcc_ptr += 2; /* trailing null */

	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
                                  32, nls_cp);
	bcc_ptr += 2 * bytes_ret;
	bcc_ptr += 2; /* trailing null */

	*pbcc_area = bcc_ptr;
}

static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
			  const struct nls_table * nls_cp)
{
	char * bcc_ptr = *pbcc_area;

	/* copy user */
	/* BB what about null user mounts - check that we do this BB */
        /* copy user */
        if(ses->userName == NULL) {
                /* BB what about null user mounts - check that we do this BB */
        } else { /* 300 should be long enough for any conceivable user name */
                strncpy(bcc_ptr, ses->userName, 300);
        }
	/* BB improve check for overflow */
        bcc_ptr += strnlen(ses->userName, 300);
	*bcc_ptr = 0;
        bcc_ptr++; /* account for null termination */

        /* copy domain */
	
        if(ses->domainName == NULL) {
                strcpy(bcc_ptr, "CIFS_LINUX_DOM");
		bcc_ptr += 14;  /* strlen(CIFS_LINUX_DOM) */
 	} else {
                strncpy(bcc_ptr, ses->domainName, 256); 
		bcc_ptr += strnlen(ses->domainName, 256);
	}
	*bcc_ptr = 0;
	bcc_ptr++;

	/* BB check for overflow here */

	strcpy(bcc_ptr, "Linux version ");
	bcc_ptr += strlen("Linux version ");
	strcpy(bcc_ptr, system_utsname.release);
	bcc_ptr += strlen(system_utsname.release) + 1;

	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;

        *pbcc_area = bcc_ptr;
}

static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
                            const struct nls_table * nls_cp)
{
	int rc = 0;
	int words_left, len;
	char * data = *pbcc_area;



	cFYI(1,("bleft %d",bleft));


	/* word align, if bytes remaining is not even */
	if(bleft % 2) {
		bleft--;
		data++;
	}
	words_left = bleft / 2;

	/* save off server operating system */
	len = UniStrnlen((wchar_t *) data, words_left);

/* We look for obvious messed up bcc or strings in response so we do not go off
   the end since (at least) WIN2K and Windows XP have a major bug in not null
   terminating last Unicode string in response  */
	if(len >= words_left)
		return rc;

	if(ses->serverOS)
		kfree(ses->serverOS);
	/* UTF-8 string will not grow more than four times as big as UCS-16 */
	ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
	if(ses->serverOS != NULL) {
		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
				   nls_cp);
	}
	data += 2 * (len + 1);
	words_left -= len + 1;

	/* save off server network operating system */
	len = UniStrnlen((wchar_t *) data, words_left);

	if(len >= words_left)
		return rc;

	if(ses->serverNOS)
		kfree(ses->serverNOS);
	ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
	if(ses->serverNOS != NULL) {
		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
				   nls_cp);
		if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) {
			cFYI(1,("NT4 server"));
			ses->flags |= CIFS_SES_NT4;
		}
	}
	data += 2 * (len + 1);
	words_left -= len + 1;

        /* save off server domain */
        len = UniStrnlen((wchar_t *) data, words_left);

        if(len > words_left)
                return rc;

        if(ses->serverDomain)
                kfree(ses->serverDomain);
        ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
        if(ses->serverDomain != NULL) {
                cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
                                   nls_cp);
                ses->serverDomain[2*len] = 0;
                ses->serverDomain[(2*len) + 1] = 0;
        }
        data += 2 * (len + 1);
        words_left -= len + 1;
	
	cFYI(1,("words left: %d",words_left));

	return rc;
}

static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
                            const struct nls_table * nls_cp)
{
	int rc = 0;
	int len;
	char * bcc_ptr = *pbcc_area;

	cFYI(1,("decode sessetup ascii. bleft %d", bleft));
	
	len = strnlen(bcc_ptr, bleft);
	if(len >= bleft)
		return rc;
	
	if(ses->serverOS)
		kfree(ses->serverOS);

	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
	if(ses->serverOS)
		strncpy(ses->serverOS, bcc_ptr, len);

	bcc_ptr += len + 1;
	bleft -= len + 1;

	len = strnlen(bcc_ptr, bleft);
	if(len >= bleft)
		return rc;

	if(ses->serverNOS)
		kfree(ses->serverNOS);

	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
	if(ses->serverNOS)
		strncpy(ses->serverNOS, bcc_ptr, len);

	bcc_ptr += len + 1;
	bleft -= len + 1;

        len = strnlen(bcc_ptr, bleft);
        if(len > bleft)
                return rc;

        if(ses->serverDomain)
                kfree(ses->serverDomain);

        ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
        if(ses->serverOS)
                strncpy(ses->serverOS, bcc_ptr, len);

        bcc_ptr += len + 1;
	bleft -= len + 1;

	cFYI(1,("ascii: bytes left %d",bleft));

	return rc;
}

int 
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
		const struct nls_table *nls_cp)
{
	int rc = 0;
	int wct;
	struct smb_hdr *smb_buf;
	char *bcc_ptr;
	char *str_area;
	SESSION_SETUP_ANDX *pSMB;
	__u32 capabilities;
	int count;
	int resp_buf_type = 0;
	struct kvec iov[2];
	enum securityEnum type;
	__u16 action;
	int bytes_remaining;

	if(ses == NULL)
		return -EINVAL;

	type = ses->server->secType;

	cFYI(1,("sess setup type %d",type));
	if(type == LANMAN) {
#ifndef CONFIG_CIFS_WEAK_PW_HASH
		/* LANMAN and plaintext are less secure and off by default.
		So we make this explicitly be turned on in kconfig (in the
		build) and turned on at runtime (changed from the default)
		in proc/fs/cifs or via mount parm.  Unfortunately this is
		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
		return -EOPNOTSUPP;
#endif
		wct = 10; /* lanman 2 style sessionsetup */
	} else if((type == NTLM) || (type == NTLMv2)) { 
		/* For NTLMv2 failures eventually may need to retry NTLM */
		wct = 13; /* old style NTLM sessionsetup */
	} else /* same size for negotiate or auth, NTLMSSP or extended security */
		wct = 12;

	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
			    (void **)&smb_buf);
	if(rc)
		return rc;

	pSMB = (SESSION_SETUP_ANDX *)smb_buf;

	capabilities = cifs_ssetup_hdr(ses, pSMB);

	/* we will send the SMB in two pieces,
	a fixed length beginning part, and a
	second part which will include the strings
	and rest of bcc area, in order to avoid having
	to do a large buffer 17K allocation */
        iov[0].iov_base = (char *)pSMB;
        iov[0].iov_len = smb_buf->smb_buf_length + 4;

	/* 2000 big enough to fit max user, domain, NOS name etc. */
	str_area = kmalloc(2000, GFP_KERNEL);
	bcc_ptr = str_area;

	if(type == LANMAN) {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
		char lnm_session_key[CIFS_SESS_KEY_SIZE];

		/* no capabilities flags in old lanman negotiation */

		pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; 
		/* BB calculate hash with password */
		/* and copy into bcc */

		calc_lanman_hash(ses, lnm_session_key);

/* #ifdef CONFIG_CIFS_DEBUG2
		cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
			CIFS_SESS_KEY_SIZE);
#endif */
		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
		bcc_ptr += CIFS_SESS_KEY_SIZE;

		/* can not sign if LANMAN negotiated so no need
		to calculate signing key? but what if server
		changed to do higher than lanman dialect and
		we reconnected would we ever calc signing_key? */

		cFYI(1,("Negotiating LANMAN setting up strings"));
		/* Unicode not allowed for LANMAN dialects */
		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
#endif    
	} else if (type == NTLM) {
		char ntlm_session_key[CIFS_SESS_KEY_SIZE];

		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
		pSMB->req_no_secext.CaseInsensitivePasswordLength =
			cpu_to_le16(CIFS_SESS_KEY_SIZE);
		pSMB->req_no_secext.CaseSensitivePasswordLength =
			cpu_to_le16(CIFS_SESS_KEY_SIZE);
	
		/* calculate session key */
		SMBNTencrypt(ses->password, ses->server->cryptKey,
			     ntlm_session_key);

		if(first_time) /* should this be moved into common code 
				  with similar ntlmv2 path? */
			cifs_calculate_mac_key(ses->server->mac_signing_key,
				ntlm_session_key, ses->password);
		/* copy session key */

		memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
		bcc_ptr += CIFS_SESS_KEY_SIZE;
		memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
		bcc_ptr += CIFS_SESS_KEY_SIZE;
		if(ses->capabilities & CAP_UNICODE) {
			/* unicode strings must be word aligned */
			if (iov[0].iov_len % 2) {
				*bcc_ptr = 0;
				bcc_ptr++;		
			}	
			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
		} else
			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
	} else if (type == NTLMv2) {
		char * v2_sess_key = 
			kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);

		/* BB FIXME change all users of v2_sess_key to
		   struct ntlmv2_resp */

		if(v2_sess_key == NULL) {
			cifs_small_buf_release(smb_buf);
			return -ENOMEM;
		}

		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);

		/* LM2 password would be here if we supported it */
		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
		/*	cpu_to_le16(LM2_SESS_KEY_SIZE); */

		pSMB->req_no_secext.CaseSensitivePasswordLength =
			cpu_to_le16(sizeof(struct ntlmv2_resp));

		/* calculate session key */
		setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
		if(first_time) /* should this be moved into common code
			          with similar ntlmv2 path? */
		/*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
				response BB FIXME, v2_sess_key); */

		/* copy session key */

	/*	memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
		bcc_ptr += LM2_SESS_KEY_SIZE; */
		memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
		bcc_ptr += sizeof(struct ntlmv2_resp);
		kfree(v2_sess_key);
		if(ses->capabilities & CAP_UNICODE) {
			if(iov[0].iov_len % 2) {
				*bcc_ptr = 0;
			}	bcc_ptr++;
			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
		} else
			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
	} else /* NTLMSSP or SPNEGO */ {
		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
		capabilities |= CAP_EXTENDED_SECURITY;
		pSMB->req.Capabilities = cpu_to_le32(capabilities);
		/* BB set password lengths */
	}

	count = (long) bcc_ptr - (long) str_area;
	smb_buf->smb_buf_length += count;

	BCC_LE(smb_buf) = cpu_to_le16(count);

	iov[1].iov_base = str_area;
	iov[1].iov_len = count; 
	rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
	/* SMB request buf freed in SendReceive2 */

	cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
	if(rc)
		goto ssetup_exit;

	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
	smb_buf = (struct smb_hdr *)iov[0].iov_base;

	if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
		rc = -EIO;
		cERROR(1,("bad word count %d", smb_buf->WordCount));
		goto ssetup_exit;
	}
	action = le16_to_cpu(pSMB->resp.Action);
	if (action & GUEST_LOGIN)
		cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
	cFYI(1, ("UID = %d ", ses->Suid));
	/* response can have either 3 or 4 word count - Samba sends 3 */
	/* and lanman response is 3 */
	bytes_remaining = BCC(smb_buf);
	bcc_ptr = pByteArea(smb_buf);

	if(smb_buf->WordCount == 4) {
		__u16 blob_len;
		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
		bcc_ptr += blob_len;
		if(blob_len > bytes_remaining) {
			cERROR(1,("bad security blob length %d", blob_len));
			rc = -EINVAL;
			goto ssetup_exit;
		}
		bytes_remaining -= blob_len;
	}	

	/* BB check if Unicode and decode strings */
	if(smb_buf->Flags2 & SMBFLG2_UNICODE)
		rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
						   ses, nls_cp);
	else
		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
	
ssetup_exit:
	kfree(str_area);
	if(resp_buf_type == CIFS_SMALL_BUFFER) {
		cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
		cifs_small_buf_release(iov[0].iov_base);
	} else if(resp_buf_type == CIFS_LARGE_BUFFER)
		cifs_buf_release(iov[0].iov_base);

	return rc;
}
