#include "system/time.h"
#include "auth/ntlmssp/ntlmssp.h"
#include "auth/ntlmssp/msrpc_parse.h"
-#include "lib/crypto/crypto.h"
+#include "../lib/crypto/crypto.h"
#include "libcli/auth/libcli_auth.h"
-#include "pstring.h"
/*
This implements the X/Open SMB password encryption
It takes a password ('unix' string), a 8 byte "crypt key"
and puts 24 bytes of encrypted password into p24
- Returns False if password must have been truncated to create LM hash
+ Returns false if password must have been truncated to create LM hash
*/
-BOOL SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24])
+bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24])
{
- BOOL ret;
+ bool ret;
uint8_t p21[21];
memset(p21,'\0',21);
* @param p16 return password hashed with md4, caller allocated 16 byte buffer
*/
-_PUBLIC_ BOOL E_md4hash(const char *passwd, uint8_t p16[16])
+bool E_md4hash(const char *passwd, uint8_t p16[16])
{
int len;
void *wpwd;
/* We don't want to return fixed data, as most callers
* don't check */
mdfour(p16, (const uint8_t *)passwd, strlen(passwd));
- return False;
+ return false;
}
len -= 2;
mdfour(p16, wpwd, len);
talloc_free(wpwd);
- return True;
+ return true;
}
/**
* Creates the DES forward-only Hash of the users password in DOS ASCII charset
* @param passwd password in 'unix' charset.
* @param p16 return password hashed with DES, caller allocated 16 byte buffer
- * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True
+ * @return false if password was > 14 characters, and therefore may be incorrect, otherwise true
* @note p16 is filled in regardless
*/
-_PUBLIC_ BOOL E_deshash(const char *passwd, uint8_t p16[16])
+bool E_deshash(const char *passwd, uint8_t p16[16])
{
- BOOL ret = True;
- fstring dospwd;
+ bool ret = true;
+ char dospwd[256];
ZERO_STRUCT(dospwd);
/* Password must be converted to DOS charset - null terminated, uppercase. */
push_string(dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE);
- /* Only the fisrt 14 chars are considered, password need not be null terminated. */
+ /* Only the first 14 chars are considered, password need not be null terminated. */
E_P16((const uint8_t *)dospwd, p16);
if (strlen(dospwd) > 14) {
- ret = False;
+ ret = false;
}
ZERO_STRUCT(dospwd);
}
/* Does both the NTLMv2 owfs of a user's password */
-BOOL ntv2_owf_gen(const uint8_t owf[16],
+bool ntv2_owf_gen(const uint8_t owf[16],
const char *user_in, const char *domain_in,
- BOOL upper_case_domain, /* Transform the domain into UPPER case */
+ bool upper_case_domain, /* Transform the domain into UPPER case */
uint8_t kr_buf[16])
{
void *user;
HMACMD5Context ctx;
TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in);
+
if (!mem_ctx) {
- return False;
+ return false;
}
if (!user_in) {
user_in = strupper_talloc(mem_ctx, user_in);
if (user_in == NULL) {
talloc_free(mem_ctx);
- return False;
+ return false;
}
if (upper_case_domain) {
domain_in = strupper_talloc(mem_ctx, domain_in);
if (domain_in == NULL) {
talloc_free(mem_ctx);
- return False;
+ return false;
}
}
if (user_byte_len == (ssize_t)-1) {
DEBUG(0, ("push_uss2_talloc() for user returned -1 (probably talloc() failure)\n"));
talloc_free(mem_ctx);
- return False;
+ return false;
}
domain_byte_len = push_ucs2_talloc(mem_ctx, &domain, domain_in);
if (domain_byte_len == (ssize_t)-1) {
DEBUG(0, ("push_ucs2_talloc() for domain returned -1 (probably talloc() failure)\n"));
talloc_free(mem_ctx);
- return False;
+ return false;
}
SMB_ASSERT(user_byte_len >= 2);
#endif
talloc_free(mem_ctx);
- return True;
+ return true;
}
/* Does the des encryption from the NT or LM MD4 hash. */
{
DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0);
- msrpc_gen(mem_ctx, &names_blob, "aaa",
+ msrpc_gen(mem_ctx, &names_blob,
+ "aaa",
NTLMSSP_NAME_TYPE_DOMAIN, domain,
NTLMSSP_NAME_TYPE_SERVER, hostname,
0, "");
return final_response;
}
-BOOL SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
+bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx,
const char *user, const char *domain, const uint8_t nt_hash[16],
const DATA_BLOB *server_chal,
const DATA_BLOB *names_blob,
the username and domain.
This prevents username swapping during the auth exchange
*/
- if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
- return False;
+ if (!ntv2_owf_gen(nt_hash, user, domain, true, ntlm_v2_hash)) {
+ return false;
}
if (nt_response) {
}
}
- return True;
+ return true;
}
-BOOL SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
+bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx,
const char *user, const char *domain,
const char *password,
const DATA_BLOB *server_chal,
encode a password buffer with a unicode password. The buffer
is filled with random data to make it harder to attack.
************************************************************/
-BOOL encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags)
+bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags)
{
uint8_t new_pw[512];
size_t new_pw_len;
*/
SIVAL(buffer, 512, new_pw_len);
ZERO_STRUCT(new_pw);
- return True;
+ return true;
}
*new_pw_len is the length in bytes of the possibly mulitbyte
returned password including termination.
************************************************************/
-BOOL decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32_t *new_pw_len,
- int string_flags)
+bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd,
+ int new_pwrd_size, int string_flags)
{
int byte_len=0;
+ ssize_t converted_pw_len;
/* the incoming buffer can be any alignment. */
string_flags |= STR_NOALIGN;
/* Password cannot be longer than the size of the password buffer */
if ( (byte_len < 0) || (byte_len > 512)) {
- return False;
+ return false;
}
/* decode into the return buffer. Buffer length supplied */
- *new_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size,
+ converted_pw_len = pull_string(new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size,
byte_len, string_flags);
+ if (converted_pw_len == -1) {
+ return false;
+ }
+
#ifdef DEBUG_PASSWORD
DEBUG(100,("decode_pw_buffer: new_pwrd: "));
- dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len);
- DEBUG(100,("multibyte len:%d\n", *new_pw_len));
+ dump_data(100, (const uint8_t *)new_pwrd, converted_pw_len);
+ DEBUG(100,("multibyte len:%d\n", (int)converted_pw_len));
DEBUG(100,("original char len:%d\n", byte_len/2));
#endif
- return True;
+ return true;
+}
+
+/***********************************************************
+ encode a password buffer with an already unicode password. The
+ rest of the buffer is filled with random data to make it harder to attack.
+************************************************************/
+bool set_pw_in_buffer(uint8_t buffer[516], DATA_BLOB *password)
+{
+ if (password->length > 512) {
+ return false;
+ }
+
+ memcpy(&buffer[512 - password->length], password->data, password->length);
+
+ generate_random_buffer(buffer, 512 - password->length);
+
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+ SIVAL(buffer, 512, password->length);
+ return true;
+}
+
+/***********************************************************
+ decode a password buffer
+ *new_pw_size is the length in bytes of the extracted unicode password
+************************************************************/
+bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx,
+ uint8_t in_buffer[516], DATA_BLOB *new_pass)
+{
+ int byte_len=0;
+
+ /* The length of the new password is in the last 4 bytes of the data buffer. */
+
+ byte_len = IVAL(in_buffer, 512);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, in_buffer, 516);
+#endif
+
+ /* Password cannot be longer than the size of the password buffer */
+ if ( (byte_len < 0) || (byte_len > 512)) {
+ return false;
+ }
+
+ *new_pass = data_blob_talloc(mem_ctx, &in_buffer[512 - byte_len], byte_len);
+
+ if (!new_pass->data) {
+ return false;
+ }
+
+ return true;
}