/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <strings.h>
#include <stdlib.h>
/*
* smb_auth_qnd_unicode
*
* Quick and dirty unicode conversion!
* Returns the length of dst in bytes.
*/
int
{
int i;
unsigned int count;
for (i = 0; i < length; ++i) {
}
dst[i] = 0;
}
return (count * sizeof (smb_wchar_t));
}
/*
* smb_auth_lmupr
*
* Converts the given LM password to all uppercase.
* The standard strupr cannot
* be used here because lm_pwd doesn't have to be
* nul terminated.
*/
static void
{
unsigned char *p = lm_pwd;
int i;
for (i = 0; (*p) && (i < SMBAUTH_LM_PWD_SZ); i++) {
if (smb_isascii(*p)) {
*p = smb_toupper(*p);
p++;
}
}
}
/*
* smb_auth_lm_hash
*
* Source: Implementing CIFS (Chris Hertel)
*
* 1. The password, as entered by user, is either padded with nulls
* or trimmed to 14 bytes.
* . Note that the 14-byte result string is not handled as a
* nul-terminated string.
* . The given password is OEM not Unicode
*
* 2. The 14-byte password is converted to all uppercase
*
* 3. The result is used as key to encrypt the KGS magic string to
* make a 16-byte hash.
*/
int
{
SMBAUTH_LM_PWD_SZ, (unsigned char *)SMBAUTH_LM_MAGIC_STR,
sizeof (SMBAUTH_LM_MAGIC_STR)));
}
/*
* smb_auth_lm_response
*
* Create a LM response from the given LM hash and challenge.
*
* Returns SMBAUTH_FAILURE if any problems occur, SMBAUTH_SUCCESS if
* all goes well.
*/
static int
unsigned char *lm_rsp)
{
int rc;
/*
* 14-byte LM Hash should be padded with 5 nul bytes to create
* a 21-byte string to be used in producing LM response
*/
/* padded LM Hash -> LM Response */
return (rc);
}
/*
* smb_auth_ntlm_hash
*
* Make NTLM Hash (using MD4) from the given password.
* The result will contain a 16-byte NTLM hash.
*/
int
{
int length;
int rc;
return (SMBAUTH_FAILURE);
unicode_password = (smb_wchar_t *)
if (unicode_password == NULL)
return (SMBAUTH_FAILURE);
return (rc);
}
/*
* smb_auth_ntlm_response
*
* challenge.
*/
static int
unsigned char *ntlm_rsp)
{
return (0);
return (SMBAUTH_RESP_SZ);
}
/*
* smb_auth_ntlm2_session_hash
*
* data = concat(challenge, client_nonce); [ntlm2 session nonce]
* hash = MD5(data);
* NTLM2 session hash = head(hash, 8);
*
* Returns SMBAUTH_SUCCESS if cryptology framework use was successful,
* Otherwise, returns SMBAUTH_FAILURE.
*/
int
{
return (SMBAUTH_FAILURE);
return (SMBAUTH_SUCCESS);
}
/*
* ntlm2_sess_rsp = DES(data=ntlm2_sess_hash, key=ntlm_hash)
* On success, returns SMBAUTH_SUCCESS. Otherwise, returns SMBAUTH_FAILURE.
*/
int
int rlen)
{
return (SMBAUTH_FAILURE);
}
/*
* smb_auth_gen_data_blob
*
* Fill the NTLMv2 data blob structure with information as described in
* "Implementing CIFS, The Common Internet File System". (pg. 282)
*/
static void
{
(void) gettimeofday(&now, 0);
}
/*
* smb_auth_memcpy
*
* It increments the pointer to the destination buffer for the easy of
* concatenation.
*/
static void
unsigned char *srcbuf,
int srcbuf_len)
{
*dstbuf += srcbuf_len;
}
/*
* smb_auth_blob_to_string
*
* Prepare the data blob string which will be used in NTLMv2 response
* generation.
*
* Assumption: Caller must allocate big enough buffer to prevent buffer
* overrun.
*
* Returns the len of the data blob string.
*/
static int
{
sizeof (blob->ndb_signature));
sizeof (blob->ndb_reserved));
sizeof (blob->ndb_timestamp));
/*LINTED E_PTRDIFF_OVERFLOW*/
}
/*
* smb_auth_ntlmv2_hash
*
* The NTLM v2 hash will be created from the given NTLM hash, username,
* and the NETBIOS name of the domain.
*
* The NTLMv2 hash will be returned via the ntlmv2_hash parameter which
* will be used in the calculation of the NTLMv2 and LMv2 responses.
*/
int
char *username,
char *ntdomain,
unsigned char *ntlmv2_hash)
{
int data_len;
unsigned char *buf;
int rc;
return (SMBAUTH_FAILURE);
(void) smb_strupr(username);
return (SMBAUTH_FAILURE);
return (SMBAUTH_FAILURE);
}
return (rc);
}
/*
* smb_auth_v2_response
*
* Caculates either the LMv2 or NTLMv2 response.
*
* Same algorithm is used for calculating both LMv2 or NTLMv2 responses.
* This routine will return NTLMv2 response if the data blob information
* is passed in as the clnt_data. Otherwise, it will return LMv2 response
* with the 8-byte client challenge(a.k.a blip) as the clnt_data.
*
* (server challenge + NTLMv2 data blob or LMv2 client challenge)
* using the NTLMv2 hash as the key.
*
* Returns the size of the corresponding v2 response upon success.
* Otherwise, returns -1 on error.
*/
static int
unsigned char *hash,
unsigned char *srv_challenge, int slen,
unsigned char *v2_rsp)
{
unsigned char *hmac_data;
if (!hmac_data) {
return (-1);
}
return (-1);
return (SMBAUTH_HASH_SZ + clen);
}
/*
* smb_auth_set_info
*
* Fill the smb_auth_info instance with either NTLM or NTLMv2 related
* authentication information based on the LMCompatibilityLevel.
*
* If the LMCompatibilityLevel equals 2, the SMB Redirector will perform
* NTLM response.
*
* If the LMCompatibilityLevel is 3 or above, the SMB Redirector will
* NTLM hash, NTLMv2 hash, NTLMv2 response and LMv2 response.
*
* Returns -1 on error. Otherwise, returns 0 upon success.
*/
int
char *password,
unsigned char *ntlm_hash,
char *domain,
unsigned char *srv_challenge_key,
int srv_challenge_len,
int lmcomp_lvl,
{
unsigned short blob_len;
int rc;
char *uppercase_dom;
if (lmcomp_lvl == 2) {
if (!ntlm_hash) {
return (-1);
} else {
}
} else {
if (!ntlm_hash) {
return (-1);
} else {
}
if (!domain)
return (-1);
return (-1);
(void) smb_strupr(uppercase_dom);
return (-1);
}
/* generate data blob */
/* generate NTLMv2 response */
if (rc < 0)
return (-1);
/* generate LMv2 response */
if (rc < 0)
return (-1);
}
return (0);
}
/*
* smb_auth_gen_session_key
*
* Generate the NTLM user session key if LMCompatibilityLevel is 2 or
* NTLMv2 user session key if LMCompatibilityLevel is 3 or above.
*
* NTLM_Session_Key = MD4(NTLM_Hash);
*
* NTLMv2_Session_Key = HMAC_MD5(NTLMv2Hash, 16, NTLMv2_HMAC, 16)
*
* Prior to calling this function, the auth instance should be set
* via smb_auth_set_info().
*
* Returns the appropriate session key.
*/
int
{
int rc;
else
return (rc);
}
/* 100's of ns between 1/1/1970 and 1/1/1601 */
static uint64_t
{
return (nt_time + NT_TIME_BIAS);
}
/*
* Local Authentication
*/
static boolean_t
unsigned char *challenge,
unsigned char *lm_hash,
unsigned char *passwd)
{
int rc;
if (rc != SMBAUTH_SUCCESS)
return (B_FALSE);
}
static boolean_t
unsigned char *challenge,
unsigned char *ntlm_hash,
unsigned char *passwd,
unsigned char *session_key)
{
int rc;
if (rc != SMBAUTH_RESP_SZ)
return (B_FALSE);
if (ok && (session_key)) {
if (rc != SMBAUTH_SUCCESS)
}
return (ok);
}
static boolean_t
unsigned char *challenge,
unsigned char *ntlm_hash,
unsigned char *passwd,
int pwdlen,
char *domain,
char *username,
{
unsigned char *clnt_blob;
int clnt_blob_len;
unsigned char *ntlmv2_resp;
int i;
int rc;
return (B_FALSE);
/*
* 15.5.2 The NTLMv2 Password Hash, pg. 279, of the "Implementing CIFS"
*
* The NTLMv2 Hash is created from:
* - NTLM hash
* - user's username, and
* - the name of the logon destination(i.e. the NetBIOS name of either
* the SMB server or NT Domain against which the user is trying to
* authenticate.
*
* Experiments show this is not exactly the case.
* For Windows Server 2003, the domain name needs to be included and
* converted to uppercase. For Vista, the domain name needs to be
* included also, but leave the case alone. And in some cases it needs
* to be empty. All three variants are tried here.
*/
if (ntlmv2_resp == NULL) {
return (B_FALSE);
}
for (i = 0; i < (sizeof (dest) / sizeof (char *)); i++) {
break;
break;
if (ok && session_key) {
if (rc != SMBAUTH_SUCCESS) {
}
break;
}
}
return (ok);
}
/*
* NTLM2 Session Response User Session Key
*
* Used when NTLMv1 authentication is employed with NTLM2 session security.
* This key is derived from the NTLM2 session response information as follows:
* The HMAC-MD5 algorithm is applied to the session nonce, using the NTLM
* User Session Key as the key. The resulting 16-byte value is the NTLM2
* Session Response User Session Key.
*/
int
const unsigned char *ntlm_hash, const unsigned char *sess_nonce,
unsigned char *result)
{
!= SMBAUTH_SUCCESS)
return (SMBAUTH_FAILURE);
}
static boolean_t
unsigned char *challenge,
unsigned char *ntlm_hash,
unsigned char *passwd,
int pwdlen,
unsigned char *nonce,
int nlen,
{
return (B_FALSE);
return (B_FALSE);
}
static boolean_t
unsigned char *challenge,
unsigned char *ntlm_hash,
unsigned char *passwd,
char *domain,
char *username)
{
unsigned char *clnt_challenge;
int i;
return (B_FALSE);
/*
* 15.5.2 The NTLMv2 Password Hash, pg. 279, of the "Implementing CIFS"
*
* The NTLMv2 Hash is created from:
* - NTLM hash
* - user's username, and
* - the name of the logon destination(i.e. the NetBIOS name of either
* the SMB server or NT Domain against which the suer is trying to
* authenticate.
*
* Experiments show this is not exactly the case.
* For Windows Server 2003, the domain name needs to be included and
* converted to uppercase. For Vista, the domain name needs to be
* included also, but leave the case alone. And in some cases it needs
* to be empty. All three variants are tried here.
*/
for (i = 0; i < (sizeof (dest) / sizeof (char *)); i++) {
break;
lmv2_resp) < 0)
break;
if (ok)
break;
}
return (ok);
}
/*
* smb_auth_validate_lm
*
* stored user's password, passed in smbpw
*
* If LM level <=3 server accepts LM responses, otherwise LMv2
*/
unsigned char *challenge,
unsigned char *passwd,
int pwdlen,
char *domain,
char *username)
{
if (pwdlen != SMBAUTH_RESP_SZ)
return (B_FALSE);
return (B_FALSE);
if (lmlevel <= 3) {
passwd);
}
if (!ok)
return (ok);
}
/*
* smb_auth_validate_nt
*
* passed in passwd arg, against stored user's password, passed in smbpw
*
*/
unsigned char *challenge,
unsigned char *passwd,
int pwdlen,
char *domain,
char *username,
unsigned char *nonce,
int nlen,
{
return (B_FALSE);
return (B_FALSE);
if (pwdlen > SMBAUTH_RESP_SZ)
else
return (ok);
}