/*
* 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
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
#include <strings.h>
#include <stdlib.h>
#include <syslog.h>
#include <assert.h>
/*
* Compute the combined (server+client) challenge per. [MS-NLMP 3.3.1]
* MD5(concat(ServerChallenge,ClientChallenge))
*/
void
{
/*
* challenges = ConcatenationOf(ServerChallenge, ClientChallenge)
*/
/*
* digest = MD5(challenges)
*/
/*
* result = digest[0..7]
*/
}
void
const char *clnt_chal, unsigned char *ssn_base_key)
{
/*
* challenges = ConcatenationOf(ServerChallenge, ClientChallenge)
*/
/* HMAC_MD5(SessionBaseKey, concat(...)) */
/* SMBAUTH_HMACT64 args: D, Dsz, K, Ksz, digest */
}
/*
* 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 *challenge, /* NTLM_CHAL_SZ */
unsigned char *lm_rsp)
{
/*
* 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 */
}
/*
* smb_auth_ntlm_hash
*
* Make NTLM Hash (using MD4) from the given password.
* The result will contain a 16-byte NTLM hash.
*/
int
{
int rc;
return (SMBAUTH_FAILURE);
if (unicode_password == NULL)
return (SMBAUTH_FAILURE);
return (rc);
}
/*
* smb_auth_ntlm_response
*
* challenge.
*/
static int
unsigned char *challenge, /* NTLM_CHAL_SZ */
unsigned char *ntlm_rsp)
{
return (0);
return (SMBAUTH_LM_RESP_SZ);
}
/*
* 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, /* NTLM_CHAL_SZ */
unsigned char *v2_rsp)
{
unsigned char *hmac_data;
if (!hmac_data) {
return (-1);
}
return (-1);
return (SMBAUTH_HASH_SZ + clen);
}
static boolean_t
unsigned char *challenge,
unsigned char *lm_hash,
unsigned char *lm_resp)
{
int rc;
if (rc != SMBAUTH_SUCCESS)
return (B_FALSE);
}
static boolean_t
unsigned char *challenge,
unsigned char *ntlm_hash,
unsigned char *nt_resp,
unsigned char *session_key)
{
int rc;
if (rc != SMBAUTH_LM_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);
}
static boolean_t
unsigned char *srv_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
*
* Validates given NTLMv2 (or NTLM, LMv2, LM) client responses against
* the stored user's password, passed in smbpw. Try those in the order
* strongest to weakest, stopping at a point determined by the configured
* lmauth_level (LM Compatibility Level).
*/
char *domain,
char *username,
unsigned char *challenge,
unsigned char *nt_resp,
unsigned char *lm_resp,
{
return (B_FALSE);
if (lmlevel > 5)
return (B_FALSE);
if (clen != NTLM_CHAL_SZ)
return (B_FALSE);
/*
* Accept NTLMv2 at any LM level (0-5).
*/
if (nt_len > SMBAUTH_LM_RESP_SZ) {
if (ok)
return (ok);
}
if (lmlevel == 5)
return (B_FALSE);
/*
* Accept NTLM at levels 0-4
*/
if (nt_len == SMBAUTH_LM_RESP_SZ) {
if (ok)
return (ok);
}
if (lmlevel == 4)
return (B_FALSE);
/*
*/
if (lm_len != SMBAUTH_LM_RESP_SZ)
return (B_FALSE);
if (session_key)
if (ok)
return (ok);
if (ok)
return (ok);
return (B_FALSE);
}
/*
* smb_gen_random_passwd(buf, len)
* Generate a random password of length len-1, and store it in buf,
* null terminated. This is used as a machine account password,
* which we set when we join a domain.
*
* [MS-DISO] A machine password is an ASCII string of randomly chosen
* characters. Each character's ASCII code is between 32 and 122 inclusive.
* That's space through 'z'.
*/
int
{
uchar_t t;
int i;
/* Last byte is the null. */
len--;
/* Temporarily put random data in the caller's buffer. */
/* Convert the random data to printable characters. */
for (i = 0; i < len; i++) {
/* need unsigned math */
buf[i] = (char)t;
}
return (0);
}