#include "../lib/crypto/crypto.h"
#include "libcli/auth/libcli_auth.h"
#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_internal.h"
_PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
int *flags,
/* LM Key is incompatible... */
*flags &= ~CLI_CRED_LANMAN_AUTH;
} else if (*flags & CLI_CRED_NTLM2) {
- struct MD5Context md5_session_nonce_ctx;
+ MD5_CTX md5_session_nonce_ctx;
uint8_t session_nonce[16];
uint8_t session_nonce_hash[16];
uint8_t user_session_key[16];
lm_response = nt_response;
/* LM Key is incompatible with 'long' passwords */
*flags &= ~CLI_CRED_LANMAN_AUTH;
- } else {
- E_deshash(password, lm_hash);
+ } else if (E_deshash(password, lm_hash)) {
lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
memcpy(lm_session_key.data, lm_hash, 8);
memset(&lm_session_key.data[8], '\0', 8);
*flags &= ~CLI_CRED_LANMAN_AUTH;
password = cli_credentials_get_password(cred);
- if (password) {
- E_deshash(password, lm_hash);
+ if (password && E_deshash(password, lm_hash)) {
lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
memcpy(lm_session_key.data, lm_hash, 8);
memset(&lm_session_key.data[8], '\0', 8);
}
return NT_STATUS_OK;
}
-
+
+/*
+ * Set a utf16 password on the credentials context, including an indication
+ * of 'how' the password was obtained
+ *
+ * This is required because the nt_hash is calculated over the raw utf16 blob,
+ * which might not be completely valid utf16, which means the conversion
+ * from CH_UTF16MUNGED to CH_UTF8 might loose information.
+ */
+_PUBLIC_ bool cli_credentials_set_utf16_password(struct cli_credentials *cred,
+ const DATA_BLOB *password_utf16,
+ enum credentials_obtained obtained)
+{
+ if (password_utf16 == NULL) {
+ return cli_credentials_set_password(cred, NULL, obtained);
+ }
+
+ if (obtained >= cred->password_obtained) {
+ struct samr_Password *nt_hash = NULL;
+ char *password_talloc = NULL;
+ size_t password_len = 0;
+ bool ok;
+
+ nt_hash = talloc(cred, struct samr_Password);
+ if (nt_hash == NULL) {
+ return false;
+ }
+
+ ok = convert_string_talloc(cred,
+ CH_UTF16MUNGED, CH_UTF8,
+ password_utf16->data,
+ password_utf16->length,
+ (void *)&password_talloc,
+ &password_len);
+ if (!ok) {
+ TALLOC_FREE(nt_hash);
+ return false;
+ }
+
+ ok = cli_credentials_set_password(cred, password_talloc, obtained);
+ TALLOC_FREE(password_talloc);
+ if (!ok) {
+ TALLOC_FREE(nt_hash);
+ return false;
+ }
+
+ mdfour(nt_hash->hash, password_utf16->data, password_utf16->length);
+ cred->nt_hash = nt_hash;
+ return true;
+ }
+
+ return false;
+}
+
_PUBLIC_ bool cli_credentials_set_nt_hash(struct cli_credentials *cred,
const struct samr_Password *nt_hash,
enum credentials_obtained obtained)