summaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
Diffstat (limited to 'auth')
-rw-r--r--auth/ntlmssp/ntlmssp_server.c118
1 files changed, 87 insertions, 31 deletions
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index 140e89daeb1..48bd743ef74 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -29,7 +29,6 @@
#include "../librpc/gen_ndr/ndr_ntlmssp.h"
#include "auth/ntlmssp/ntlmssp_ndr.h"
#include "../libcli/auth/libcli_auth.h"
-#include "../lib/crypto/crypto.h"
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_internal.h"
#include "auth/common_auth.h"
@@ -37,6 +36,9 @@
#include "param/loadparm.h"
#include "libcli/security/session.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
@@ -424,7 +426,6 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
DATA_BLOB version_blob = data_blob_null;
const unsigned int mic_len = NTLMSSP_MIC_SIZE;
DATA_BLOB mic_blob = data_blob_null;
- uint8_t session_nonce_hash[16];
const char *parse_string;
bool ok;
struct timeval endtime;
@@ -751,7 +752,6 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
*/
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
- MD5_CTX md5_session_nonce_ctx;
state->doing_ntlm2 = true;
memcpy(state->session_nonce, ntlmssp_state->internal_chal.data, 8);
@@ -759,18 +759,30 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
- MD5Init(&md5_session_nonce_ctx);
- MD5Update(&md5_session_nonce_ctx, state->session_nonce, 16);
- MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
-
/* LM response is no longer useful */
data_blob_free(&ntlmssp_state->lm_resp);
/* We changed the effective challenge - set it */
if (auth_context->set_ntlm_challenge) {
+ uint8_t session_nonce_hash[16];
+ int rc;
+
+ rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
+ state->session_nonce,
+ 16,
+ session_nonce_hash);
+ if (rc < 0) {
+ if (rc == GNUTLS_E_UNWANTED_ALGORITHM) {
+ return NT_STATUS_NTLM_BLOCKED;
+ }
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+
nt_status = auth_context->set_ntlm_challenge(auth_context,
session_nonce_hash,
"NTLMSSP callback (NTLM2)");
+ ZERO_ARRAY(session_nonce_hash);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("gensec_ntlmssp_server_negotiate: failed to get challenge: %s\n",
nt_errstr(nt_status)));
@@ -927,10 +939,24 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
/* Handle the different session key derivation for NTLM2 */
if (state->doing_ntlm2) {
if (user_session_key.data && user_session_key.length == 16) {
+ int rc;
+
session_key = data_blob_talloc(ntlmssp_state,
NULL, 16);
- hmac_md5(user_session_key.data, state->session_nonce,
- sizeof(state->session_nonce), session_key.data);
+
+ rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
+ user_session_key.data,
+ user_session_key.length,
+ state->session_nonce,
+ sizeof(state->session_nonce),
+ session_key.data);
+ if (rc < 0) {
+ if (rc == GNUTLS_E_UNWANTED_ALGORITHM) {
+ return NT_STATUS_NTLM_BLOCKED;
+ }
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
@@ -1031,33 +1057,58 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
}
if (ntlmssp_state->new_spnego) {
- HMACMD5Context ctx;
+ gnutls_hmac_hd_t hmac_hnd = NULL;
uint8_t mic_buffer[NTLMSSP_MIC_SIZE] = { 0, };
int cmp;
-
- hmac_md5_init_limK_to_64(ntlmssp_state->session_key.data,
- ntlmssp_state->session_key.length,
- &ctx);
-
- hmac_md5_update(ntlmssp_state->negotiate_blob.data,
- ntlmssp_state->negotiate_blob.length,
- &ctx);
- hmac_md5_update(ntlmssp_state->challenge_blob.data,
- ntlmssp_state->challenge_blob.length,
- &ctx);
+ int rc;
+
+ rc = gnutls_hmac_init(&hmac_hnd,
+ GNUTLS_MAC_MD5,
+ ntlmssp_state->session_key.data,
+ MIN(ntlmssp_state->session_key.length, 64));
+ if (rc < 0) {
+ if (rc == GNUTLS_E_UNWANTED_ALGORITHM) {
+ return NT_STATUS_NTLM_BLOCKED;
+ }
+ return NT_STATUS_NO_MEMORY;
+ }
+ rc = gnutls_hmac(hmac_hnd,
+ ntlmssp_state->negotiate_blob.data,
+ ntlmssp_state->negotiate_blob.length);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ rc = gnutls_hmac(hmac_hnd,
+ ntlmssp_state->challenge_blob.data,
+ ntlmssp_state->challenge_blob.length);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
/* checked were we set ntlmssp_state->new_spnego */
SMB_ASSERT(request.length >
(NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
- hmac_md5_update(request.data, NTLMSSP_MIC_OFFSET, &ctx);
- hmac_md5_update(mic_buffer, NTLMSSP_MIC_SIZE, &ctx);
- hmac_md5_update(request.data +
- (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
- request.length -
- (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
- &ctx);
- hmac_md5_final(mic_buffer, &ctx);
+ rc = gnutls_hmac(hmac_hnd, request.data, NTLMSSP_MIC_OFFSET);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ rc = gnutls_hmac(hmac_hnd, mic_buffer, NTLMSSP_MIC_SIZE);
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ rc = gnutls_hmac(hmac_hnd,
+ request.data + (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE),
+ request.length - (NTLMSSP_MIC_OFFSET + NTLMSSP_MIC_SIZE));
+ if (rc < 0) {
+ gnutls_hmac_deinit(hmac_hnd, NULL);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ gnutls_hmac_deinit(hmac_hnd, mic_buffer);
cmp = memcmp(request.data + NTLMSSP_MIC_OFFSET,
mic_buffer, NTLMSSP_MIC_SIZE);
@@ -1068,10 +1119,15 @@ static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
ntlmssp_state->user,
ntlmssp_state->domain,
ntlmssp_state->client.netbios_name));
- dump_data(1, request.data + NTLMSSP_MIC_OFFSET,
+ dump_data(11, request.data + NTLMSSP_MIC_OFFSET,
NTLMSSP_MIC_SIZE);
- dump_data(1, mic_buffer,
+ dump_data(11, mic_buffer,
NTLMSSP_MIC_SIZE);
+ }
+
+ ZERO_ARRAY(mic_buffer);
+
+ if (cmp != 0) {
return NT_STATUS_INVALID_PARAMETER;
}
}