summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/ntlmssp.h4
-rw-r--r--source3/libsmb/cliconnect.c1
-rw-r--r--source3/libsmb/ntlmssp.c50
-rw-r--r--source3/utils/ntlm_auth.c71
4 files changed, 120 insertions, 6 deletions
diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h
index a2dac7dc0b..a158fb614f 100644
--- a/source3/include/ntlmssp.h
+++ b/source3/include/ntlmssp.h
@@ -65,6 +65,10 @@ enum NTLM_MESSAGE_TYPE
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
#define NTLMSSP_NEGOTIATE_56 0x80000000
+#define NTLMSSP_FEATURE_SESSION_KEY 0x00000001
+#define NTLMSSP_FEATURE_SIGN 0x00000002
+#define NTLMSSP_FEATURE_SEAL 0x00000004
+
#define NTLMSSP_NAME_TYPE_SERVER 0x01
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 4c3c4f4565..d547bb3854 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -599,6 +599,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
return nt_status;
}
+ ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
return nt_status;
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index 986fa8cce9..a6fb3b426b 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -211,6 +211,50 @@ NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
}
/**
+ * Request features for the NTLMSSP negotiation
+ *
+ * @param ntlmssp_state NTLMSSP state
+ * @param feature_list List of space seperated features requested from NTLMSSP.
+ */
+void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list)
+{
+ /*
+ * We need to set this to allow a later SetPassword
+ * via the SAMR pipe to succeed. Strange.... We could
+ * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
+ */
+ if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ }
+}
+
+/**
+ * Request a feature for the NTLMSSP negotiation
+ *
+ * @param ntlmssp_state NTLMSSP state
+ * @param feature Bit flag specifying the requested feature
+ */
+void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature)
+{
+ /* As per JRA's comment above */
+ if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (feature & NTLMSSP_FEATURE_SIGN) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (feature & NTLMSSP_FEATURE_SEAL) {
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ }
+}
+
+/**
* Next state function for the NTLMSSP state machine
*
* @param ntlmssp_state NTLMSSP State
@@ -1163,12 +1207,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_NEGOTIATE_NTLM2 |
NTLMSSP_NEGOTIATE_KEY_EXCH |
- /*
- * We need to set this to allow a later SetPassword
- * via the SAMR pipe to succeed. Strange.... We could
- * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
- * */
- NTLMSSP_NEGOTIATE_SIGN |
NTLMSSP_REQUEST_TARGET;
return NT_STATUS_OK;
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 9e178ec945..c33ab9f8ac 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -621,6 +621,10 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
char *buf, int length)
{
static NTLMSSP_STATE *ntlmssp_state = NULL;
+ static char* want_feature_list = NULL;
+ static uint32 neg_flags = 0;
+ static BOOL have_session_key = False;
+ static DATA_BLOB session_key;
DATA_BLOB request, reply;
NTSTATUS nt_status;
@@ -631,6 +635,13 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
}
if (strlen(buf) > 3) {
+ if(strncmp(buf, "SF ", 3) == 0){
+ DEBUG(10, ("Setting flags to negotioate\n"));
+ SAFE_FREE(want_feature_list);
+ want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
+ x_fprintf(x_stdout, "OK\n");
+ return;
+ }
request = base64_decode_data_blob(buf + 3);
} else {
request = data_blob(NULL, 0);
@@ -658,6 +669,20 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
ntlmssp_end(&ntlmssp_state);
} else if (strncmp(buf, "KK", 2) == 0) {
+ } else if (strncmp(buf, "GF", 2) == 0) {
+ DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
+ x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
+ data_blob_free(&request);
+ return;
+ } else if (strncmp(buf, "GK", 2) == 0) {
+ DEBUG(10, ("Requested NTLMSSP session key\n"));
+ if(have_session_key)
+ x_fprintf(x_stdout, "GK %s\n", base64_encode_data_blob(session_key));
+ else
+ x_fprintf(x_stdout, "BH\n");
+
+ data_blob_free(&request);
+ return;
} else {
DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
@@ -669,6 +694,7 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
return;
}
+ ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
}
DEBUG(10, ("got NTLMSSP packet:\n"));
@@ -693,6 +719,13 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
} else {
x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context);
DEBUG(10, ("NTLMSSP OK!\n"));
+
+ if(have_session_key)
+ data_blob_free(&session_key);
+ session_key = data_blob(ntlmssp_state->session_key.data,
+ ntlmssp_state->session_key.length);
+ neg_flags = ntlmssp_state->neg_flags;
+ have_session_key = True;
}
data_blob_free(&request);
@@ -702,6 +735,10 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
char *buf, int length)
{
static NTLMSSP_STATE *ntlmssp_state = NULL;
+ static char* want_feature_list = NULL;
+ static uint32 neg_flags = 0;
+ static BOOL have_session_key = False;
+ static DATA_BLOB session_key;
DATA_BLOB request, reply;
NTSTATUS nt_status;
BOOL first = False;
@@ -713,6 +750,13 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
}
if (strlen(buf) > 3) {
+ if(strncmp(buf, "SF ", 3) == 0) {
+ DEBUG(10, ("Looking for flags to negotiate\n"));
+ SAFE_FREE(want_feature_list);
+ want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
+ x_fprintf(x_stdout, "OK\n");
+ return;
+ }
request = base64_decode_data_blob(buf + 3);
} else {
request = data_blob(NULL, 0);
@@ -750,6 +794,23 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
ntlmssp_end(&ntlmssp_state);
} else if (strncmp(buf, "TT", 2) == 0) {
+ } else if (strncmp(buf, "GF", 2) == 0) {
+ DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
+ x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
+ data_blob_free(&request);
+ return;
+ } else if (strncmp(buf, "GK", 2) == 0 ) {
+ DEBUG(10, ("Requested session key\n"));
+
+ if(have_session_key) {
+ x_fprintf(x_stdout, "GK %s\n", base64_encode_data_blob(session_key));
+ }
+ else {
+ x_fprintf(x_stdout, "BH\n");
+ }
+
+ data_blob_free(&request);
+ return;
} else {
DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
@@ -761,6 +822,7 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
return;
}
+ ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
first = True;
}
@@ -783,6 +845,15 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
char *reply_base64 = base64_encode_data_blob(reply);
x_fprintf(x_stdout, "AF %s\n", reply_base64);
SAFE_FREE(reply_base64);
+
+ if(have_session_key)
+ data_blob_free(&session_key);
+
+ session_key = data_blob(ntlmssp_state->session_key.data,
+ ntlmssp_state->session_key.length);
+ neg_flags = ntlmssp_state->neg_flags;
+ have_session_key = True;
+
DEBUG(10, ("NTLMSSP OK!\n"));
if (ntlmssp_state)
ntlmssp_end(&ntlmssp_state);