#include "includes.h"
#include "auth/ntlmssp/ntlmssp.h"
-#include "../lib/crypto/crypto.h"
#include "../libcli/auth/libcli_auth.h"
#include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h"
#include "../auth/ntlmssp/ntlmssp_ndr.h"
#include "../nsswitch/libwbclient/wbclient.h"
+#include "lib/crypto/gnutls_helpers.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
/*********************************************************************
Client side NTLMSSP
*********************************************************************/
const NTTIME *server_timestamp = NULL;
uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
DATA_BLOB mic_blob = data_blob_const(mic_buffer, sizeof(mic_buffer));
- HMACMD5Context ctx;
+ gnutls_hmac_hd_t hmac_hnd = NULL;
+ int rc;
TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
if (!mem_ctx) {
}
}
+ if (DEBUGLEVEL >= 10) {
+ struct CHALLENGE_MESSAGE *challenge =
+ talloc(ntlmssp_state, struct CHALLENGE_MESSAGE);
+ if (challenge != NULL) {
+ NTSTATUS status;
+ challenge->NegotiateFlags = chal_flags;
+ status = ntlmssp_pull_CHALLENGE_MESSAGE(
+ &in, challenge, challenge);
+ if (NT_STATUS_IS_OK(status)) {
+ NDR_PRINT_DEBUG(CHALLENGE_MESSAGE,
+ challenge);
+ }
+ TALLOC_FREE(challenge);
+ }
+ }
+
if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
ntlmssp_state->server.is_standalone = true;
} else {
return nt_status;
}
+ if (DEBUGLEVEL >= 10) {
+ struct AUTHENTICATE_MESSAGE *authenticate =
+ talloc(ntlmssp_state, struct AUTHENTICATE_MESSAGE);
+ if (authenticate != NULL) {
+ NTSTATUS status;
+ authenticate->NegotiateFlags = ntlmssp_state->neg_flags;
+ status = ntlmssp_pull_AUTHENTICATE_MESSAGE(
+ out, authenticate, authenticate);
+ if (NT_STATUS_IS_OK(status)) {
+ NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE,
+ authenticate);
+ }
+ TALLOC_FREE(authenticate);
+ }
+ }
+
/*
* We always include the MIC, even without:
* av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
*
* This matches a Windows client.
*/
- hmac_md5_init_limK_to_64(session_key.data,
- session_key.length,
- &ctx);
- hmac_md5_update(ntlmssp_state->negotiate_blob.data,
- ntlmssp_state->negotiate_blob.length,
- &ctx);
- hmac_md5_update(in.data, in.length, &ctx);
- hmac_md5_update(out->data, out->length, &ctx);
- hmac_md5_final(mic_buffer, &ctx);
+ rc = gnutls_hmac_init(&hmac_hnd,
+ GNUTLS_MAC_MD5,
+ session_key.data,
+ MIN(session_key.length, 64));
+ if (rc < 0) {
+ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
+ goto done;
+ }
+
+ rc = gnutls_hmac(hmac_hnd,
+ ntlmssp_state->negotiate_blob.data,
+ ntlmssp_state->negotiate_blob.length);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
+ goto done;
+ }
+ rc = gnutls_hmac(hmac_hnd, in.data, in.length);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
+ goto done;
+ }
+ rc = gnutls_hmac(hmac_hnd, out->data, out->length);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
+ goto done;
+ }
+
+ gnutls_hmac_deinit(hmac_hnd, mic_buffer);
+
memcpy(out->data + NTLMSSP_MIC_OFFSET, mic_buffer, NTLMSSP_MIC_SIZE);
+ ZERO_ARRAY(mic_buffer);
+ nt_status = NT_STATUS_OK;
done:
+ ZERO_ARRAY_LEN(ntlmssp_state->negotiate_blob.data,
+ ntlmssp_state->negotiate_blob.length);
data_blob_free(&ntlmssp_state->negotiate_blob);
ntlmssp_state->session_key = session_key;
}
talloc_free(mem_ctx);
- return NT_STATUS_OK;
+ return nt_status;
}
NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
- ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true);
+ ntlmssp_state->use_nt_response = \
+ gensec_setting_bool(gensec_security->settings,
+ "ntlmssp_client",
+ "send_nt_response",
+ true);
ntlmssp_state->allow_lm_response = lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx);
* is requested.
*/
ntlmssp_state->force_wrap_seal = true;
- /*
- * We want also work against old Samba servers
- * which didn't had GENSEC_FEATURE_LDAP_STYLE
- * we negotiate SEAL too. We may remove this
- * in a few years. As all servers should have
- * GENSEC_FEATURE_LDAP_STYLE by then.
- */
+ }
+ }
+ if (ntlmssp_state->force_wrap_seal) {
+ bool ret;
+
+ /*
+ * We want also work against old Samba servers
+ * which didn't had GENSEC_FEATURE_LDAP_STYLE
+ * we negotiate SEAL too. We may remove this
+ * in a few years. As all servers should have
+ * GENSEC_FEATURE_LDAP_STYLE by then.
+ */
+ ret = gensec_setting_bool(gensec_security->settings,
+ "ntlmssp_client",
+ "ldap_style_send_seal",
+ true);
+ if (ret) {
ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
}