Exemple #1
0
/****************************************************************************
 makes lm and nt OWF crypts
 ****************************************************************************/
void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
			 const char *user, const char *server,
			 const char *domain, uchar sess_key[16])
{
	uchar kr[16];

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 10, ("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
		   user, server, domain));


	SMBgenclientchals(pwd->lm_cli_chal,
			  pwd->nt_cli_chal,
			  &pwd->nt_cli_chal_len, server, domain);

	ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);

	/* lm # */
	SMBOWFencrypt_ntv2(kr,
			   srv_key, 8, pwd->lm_cli_chal, 8, pwd->smb_lm_owf);
	memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);

	/* nt # */
	SMBOWFencrypt_ntv2(kr,
			   srv_key, 8,
			   pwd->nt_cli_chal, pwd->nt_cli_chal_len,
			   pwd->smb_nt_owf);
	memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
	pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;

	SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, sess_key);

#ifdef DEBUG_PASSWORD
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("server cryptkey: "));
	dump_data(20, srv_key, 8);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("client lmv2 cryptkey: "));
	dump_data(20, pwd->lm_cli_chal, 8);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("client ntv2 cryptkey: "));
	dump_data(20, pwd->nt_cli_chal, pwd->nt_cli_chal_len);

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("ntv2_owf_passwd: "));
	dump_data(20, pwd->smb_nt_owf, pwd->nt_owf_len);
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("nt_sess_pwd: "));
	dump_data(20, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("lmv2_owf_passwd: "));
	dump_data(20, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("lm_sess_pwd: "));
	dump_data(20, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));

	RPC_DBG_PRINTF(rpc_e_dbg_auth, 20, ("session key:\n"));
	dump_data(20, sess_key, 16);
#endif
	pwd->crypted = True;

}
Exemple #2
0
static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx,
					const uint8_t ntlm_v2_hash[16],
					const DATA_BLOB *server_chal)
{
	uint8_t lmv2_response[16];
	DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8);
	DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24);

	/* LMv2 */
	/* client-supplied random data */
	generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length);

	/* Given that data, and the challenge from the server, generate a response */
	SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
	memcpy(final_response.data, lmv2_response, sizeof(lmv2_response));

	/* after the first 16 bytes is the random data we generated above,
	   so the server can verify us with it */
	memcpy(final_response.data+sizeof(lmv2_response),
	       lmv2_client_data.data, lmv2_client_data.length);

	data_blob_free(&lmv2_client_data);

	return final_response;
}
Exemple #3
0
static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx,
					  const uint8_t ntlm_v2_hash[16],
					  const DATA_BLOB *server_chal,
					  const DATA_BLOB *names_blob)
{
	uint8_t ntlmv2_response[16];
	DATA_BLOB ntlmv2_client_data;
	DATA_BLOB final_response;

	TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0,
					   "NTLMv2_generate_response internal context");

	if (!mem_ctx) {
		return data_blob(NULL, 0);
	}

	/* NTLMv2 */
	/* generate some data to pass into the response function - including
	   the hostname and domain name of the server */
	ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob);

	/* Given that data, and the challenge from the server, generate a response */
	SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);

	final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);

	memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));

	memcpy(final_response.data+sizeof(ntlmv2_response),
	       ntlmv2_client_data.data, ntlmv2_client_data.length);

	talloc_free(mem_ctx);

	return final_response;
}
Exemple #4
0
static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16],
					  const DATA_BLOB *server_chal,
					  const DATA_BLOB *names_blob)
{
	uchar ntlmv2_response[16];
	DATA_BLOB ntlmv2_client_data;
	DATA_BLOB final_response;
	
	/* NTLMv2 */
	/* generate some data to pass into the response function - including
	   the hostname and domain name of the server */
	ntlmv2_client_data = NTLMv2_generate_client_data(names_blob);

	/* Given that data, and the challenge from the server, generate a response */
	SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response);
	
	final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length);

	memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response));

	memcpy(final_response.data+sizeof(ntlmv2_response), 
	       ntlmv2_client_data.data, ntlmv2_client_data.length);

	data_blob_free(&ntlmv2_client_data);

	return final_response;
}
Exemple #5
0
static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
                                const DATA_BLOB *ntv2_response,
                                const uint8_t *part_passwd,
                                const DATA_BLOB *sec_blob,
                                const char *user, const char *domain,
                                bool upper_case_domain, /* should the domain be transformed into upper case? */
                                DATA_BLOB *user_sess_key)
{
    /* Finish the encryption of part_passwd. */
    uint8_t kr[16];
    uint8_t value_from_encryption[16];
    DATA_BLOB client_key_data;

    if (part_passwd == NULL) {
        DEBUG(10,("No password set - DISALLOWING access\n"));
        /* No password set - always false */
        return false;
    }

    if (sec_blob->length != 8) {
        DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n",
                  (unsigned long)sec_blob->length));
        return false;
    }

    if (ntv2_response->length < 24) {
        /* We MUST have more than 16 bytes, or the stuff below will go
           crazy.  No known implementation sends less than the 24 bytes
           for LMv2, let alone NTLMv2. */
        DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n",
                  (unsigned long)ntv2_response->length));
        return false;
    }

    client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);

    if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
        return false;
    }

    SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
    *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
    SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
    return true;
}
Exemple #6
0
static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
				 const DATA_BLOB *ntv2_response,
				 const uint8_t *part_passwd,
				 const DATA_BLOB *sec_blob,
				 const char *user, const char *domain,
				 DATA_BLOB *user_sess_key)
{
	/* Finish the encryption of part_passwd. */
	uint8_t kr[16];
	uint8_t value_from_encryption[16];
	DATA_BLOB client_key_data;

	if (part_passwd == NULL) {
		DEBUG(10,("No password set - DISALLOWING access\n"));
		/* No password set - always false */
		return false;
	}

	if (sec_blob->length != 8) {
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", 
			  (unsigned long)sec_blob->length));
		return false;
	}

	if (ntv2_response->length < 24) {
		/* We MUST have more than 16 bytes, or the stuff below will go
		   crazy.  No known implementation sends less than the 24 bytes
		   for LMv2, let alone NTLMv2. */
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", 
			  (unsigned long)ntv2_response->length));
		return false;
	}

	client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
	/* 
	   todo:  should we be checking this for anything?  We can't for LMv2, 
	   but for NTLMv2 it is meant to contain the current time etc.
	*/

	if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
		return false;
	}

	SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);

#if DEBUG_PASSWORD
	DEBUG(100,("Part password (P16) was |\n"));
	dump_data(100, part_passwd, 16);
	DEBUGADD(100,("Password from client was |\n"));
	dump_data(100, ntv2_response->data, ntv2_response->length);
	DEBUGADD(100,("Variable data from client was |\n"));
	dump_data(100, client_key_data.data, client_key_data.length);
	DEBUGADD(100,("Given challenge was |\n"));
	dump_data(100, sec_blob->data, sec_blob->length);
	DEBUGADD(100,("Value from encryption was |\n"));
	dump_data(100, value_from_encryption, 16);
#endif
	data_blob_clear_free(&client_key_data);
	if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { 
		if (user_sess_key != NULL) {
			*user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
			SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
		}
		return true;
	}
	return false;
}
Exemple #7
0
static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
				 const uchar *part_passwd,
				 const DATA_BLOB *sec_blob,
				 const char *user, const char *domain,
				 BOOL upper_case_domain, /* should the domain be transformed into upper case? */
				 DATA_BLOB *user_sess_key)
{
	/* Finish the encryption of part_passwd. */
	uchar kr[16];
	uchar value_from_encryption[16];
	uchar client_response[16];
	DATA_BLOB client_key_data;
	BOOL res;

	if (part_passwd == NULL) {
		DEBUG(10,("No password set - DISALLOWING access\n"));
		/* No password set - always False */
		return False;
	}

	if (sec_blob->length != 8) {
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", 
			  (unsigned long)sec_blob->length));
		return False;
	}
	
	if (ntv2_response->length < 24) {
		/* We MUST have more than 16 bytes, or the stuff below will go
		   crazy.  No known implementation sends less than the 24 bytes
		   for LMv2, let alone NTLMv2. */
		DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", 
			  (unsigned long)ntv2_response->length));
		return False;
	}

	client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16);
	/* 
	   todo:  should we be checking this for anything?  We can't for LMv2, 
	   but for NTLMv2 it is meant to contain the current time etc.
	*/

	memcpy(client_response, ntv2_response->data, sizeof(client_response));

	if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) {
		return False;
	}

	SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
	if (user_sess_key != NULL) {
		*user_sess_key = data_blob(NULL, 16);
		SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
	}

#if DEBUG_PASSWORD
	DEBUG(100,("Part password (P16) was |\n"));
	dump_data(100, part_passwd, 16);
	DEBUGADD(100,("Password from client was |\n"));
	dump_data(100, ntv2_response->data, ntv2_response->length);
	DEBUGADD(100,("Variable data from client was |\n"));
	dump_data(100, client_key_data.data, client_key_data.length);
	DEBUGADD(100,("Given challenge was |\n"));
	dump_data(100, sec_blob->data, sec_blob->length);
	DEBUGADD(100,("Value from encryption was |\n"));
	dump_data(100, value_from_encryption, 16);
#endif
	data_blob_clear_free(&client_key_data);
	res = (memcmp(value_from_encryption, client_response, 16) == 0);
	if ((!res) && (user_sess_key != NULL))
		data_blob_clear_free(user_sess_key);
	return res;
}