with talloc() for the NTLMSSP system.
Andrew Bartlett
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
}
-/**
- * Store a DATA_BLOB containing an NTLMSSP response, for use later.
- * This copies the data blob
- */
-
-NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
- DATA_BLOB response)
-{
- ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
- response.data, response.length);
- return NT_STATUS_OK;
-}
-
/**
* Next state function for the wrapped NTLMSSP state machine
*
static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
- const DATA_BLOB in, DATA_BLOB *out)
+ const DATA_BLOB input, DATA_BLOB *out)
{
struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
NTSTATUS status;
- DATA_BLOB input;
uint32_t ntlmssp_command;
int i;
out_mem_ctx = ntlmssp_state;
}
- if (!in.length && ntlmssp_state->stored_response.length) {
- input = ntlmssp_state->stored_response;
-
- /* we only want to read the stored response once - overwrite it */
- ntlmssp_state->stored_response = data_blob(NULL, 0);
- } else {
- input = in;
- }
-
if (!input.length) {
switch (ntlmssp_state->role) {
case NTLMSSP_CLIENT:
struct ntlmssp_state
{
- uint_t ref_count;
enum ntlmssp_role role;
enum samr_Role server_role;
uint32_t expected_state;
/* ntlmv2 */
DATA_BLOB send_sign_key;
- DATA_BLOB send_seal_key;
DATA_BLOB recv_sign_key;
- DATA_BLOB recv_seal_key;
- uint8_t send_seal_hash[258];
- uint8_t recv_seal_hash[258];
+ struct arcfour_state *send_seal_hash;
+ struct arcfour_state *recv_seal_hash;
/* ntlmv1 */
- uint8_t ntlmssp_hash[258];
+ struct arcfour_state *ntlmssp_hash;
- /* it turns out that we don't always get the
- response in at the time we want to process it.
- Store it here, until we need it */
- DATA_BLOB stored_response;
-
};
struct gensec_ntlmssp_state {
(*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
- (*ntlmssp_state)->ref_count = 1;
-
(*ntlmssp_state)->neg_flags =
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_REQUEST_TARGET;
(*ntlmssp_state)->server_use_session_keys = True;
(*ntlmssp_state)->server_multiple_authentications = False;
- (*ntlmssp_state)->ref_count = 1;
-
(*ntlmssp_state)->neg_flags =
NTLMSSP_NEGOTIATE_NTLM;
const char *recv_sign_const;
const char *recv_seal_const;
+ DATA_BLOB send_seal_key;
+ DATA_BLOB recv_seal_key;
+
switch (ntlmssp_state->role) {
case NTLMSSP_CLIENT:
send_sign_const = CLI_SIGN;
return NT_STATUS_INTERNAL_ERROR;
}
+ ntlmssp_state->send_seal_hash = talloc(ntlmssp_state, struct arcfour_state);
+ NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->send_seal_hash);
+ ntlmssp_state->recv_seal_hash = talloc(ntlmssp_state, struct arcfour_state);
+ NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->recv_seal_hash);
+
/**
Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
ntlmssp_state->send_sign_key.length);
calc_ntlmv2_key(ntlmssp_state,
- &ntlmssp_state->send_seal_key,
+ &send_seal_key,
weak_session_key, send_seal_const);
dump_data_pw("NTLMSSP send seal key:\n",
- ntlmssp_state->send_seal_key.data,
- ntlmssp_state->send_seal_key.length);
+ send_seal_key.data,
+ send_seal_key.length);
arcfour_init(ntlmssp_state->send_seal_hash,
- &ntlmssp_state->send_seal_key);
+ &send_seal_key);
dump_data_pw("NTLMSSP send sesl hash:\n",
- ntlmssp_state->send_seal_hash,
- sizeof(ntlmssp_state->send_seal_hash));
+ ntlmssp_state->send_seal_hash->sbox,
+ sizeof(ntlmssp_state->send_seal_hash->sbox));
/* RECV */
calc_ntlmv2_key(ntlmssp_state,
ntlmssp_state->recv_sign_key.length);
calc_ntlmv2_key(ntlmssp_state,
- &ntlmssp_state->recv_seal_key,
+ &recv_seal_key,
weak_session_key, recv_seal_const);
dump_data_pw("NTLMSSP recv seal key:\n",
- ntlmssp_state->recv_seal_key.data,
- ntlmssp_state->recv_seal_key.length);
+ recv_seal_key.data,
+ recv_seal_key.length);
arcfour_init(ntlmssp_state->recv_seal_hash,
- &ntlmssp_state->recv_seal_key);
+ &recv_seal_key);
dump_data_pw("NTLMSSP receive seal hash:\n",
- ntlmssp_state->recv_seal_hash,
- sizeof(ntlmssp_state->recv_seal_hash));
+ ntlmssp_state->recv_seal_hash->sbox,
+ sizeof(ntlmssp_state->recv_seal_hash->sbox));
} else {
DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
+ ntlmssp_state->ntlmssp_hash = talloc(ntlmssp_state, struct arcfour_state);
+ NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->ntlmssp_hash);
+
arcfour_init(ntlmssp_state->ntlmssp_hash,
&ntlmssp_state->session_key);
- dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
- sizeof(ntlmssp_state->ntlmssp_hash));
+ dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash->sbox,
+ sizeof(ntlmssp_state->ntlmssp_hash->sbox));
}
ntlmssp_state->ntlm_seq_num = 0;
struct wrepl_associate;
struct wrepl_pull_table;
struct wrepl_pull_names;
+
+struct arcfour_state;
#include "lib/crypto/md4.h"
#include "lib/crypto/hmacmd5.h"
#include "lib/crypto/crc32.h"
+
+struct arcfour_state {
+ uint8_t sbox[256];
+ uint8_t index_i;
+ uint8_t index_j;
+};
*/
#include "includes.h"
+#include "lib/crypto/crypto.h"
/* NOTES:
}
/* initialise the arcfour sbox with key */
-void arcfour_init(uint8_t s_box[258], const DATA_BLOB *key)
+void arcfour_init(struct arcfour_state *state, const DATA_BLOB *key)
{
int ind;
uint8_t j = 0;
- for (ind = 0; ind < 256; ind++) {
- s_box[ind] = (uint8_t)ind;
+ for (ind = 0; ind < sizeof(state->sbox); ind++) {
+ state->sbox[ind] = (uint8_t)ind;
}
- for (ind = 0; ind < 256; ind++) {
+ for (ind = 0; ind < sizeof(state->sbox); ind++) {
uint8_t tc;
- j += (s_box[ind] + key->data[ind%key->length]);
+ j += (state->sbox[ind] + key->data[ind%key->length]);
- tc = s_box[ind];
- s_box[ind] = s_box[j];
- s_box[j] = tc;
+ tc = state->sbox[ind];
+ state->sbox[ind] = state->sbox[j];
+ state->sbox[j] = tc;
}
- s_box[256] = 0; /* i */
- s_box[257] = 0; /* j */
-
+ state->index_i = 0;
+ state->index_j = 0;
}
/* crypt the data with arcfour */
-void arcfour_crypt_sbox(uint8_t s_box[258], uint8_t *data, int len)
+void arcfour_crypt_sbox(struct arcfour_state *state, uint8_t *data, int len)
{
- uint8_t index_i = s_box[256];
- uint8_t index_j = s_box[257];
int ind;
for (ind = 0; ind < len; ind++) {
uint8_t tc;
uint8_t t;
- index_i++;
- index_j += s_box[index_i];
+ state->index_i++;
+ state->index_j += state->sbox[state->index_i];
- tc = s_box[index_i];
- s_box[index_i] = s_box[index_j];
- s_box[index_j] = tc;
+ tc = state->sbox[state->index_i];
+ state->sbox[state->index_i] = state->sbox[state->index_j];
+ state->sbox[state->index_j] = tc;
- t = s_box[index_i] + s_box[index_j];
- data[ind] = data[ind] ^ s_box[t];
+ t = state->sbox[state->index_i] + state->sbox[state->index_j];
+ data[ind] = data[ind] ^ state->sbox[t];
}
- s_box[256] = index_i;
- s_box[257] = index_j;
}
/*
*/
void arcfour_crypt_blob(uint8_t *data, int len, const DATA_BLOB *key)
{
- uint8_t s_box[258];
- arcfour_init(s_box, key);
- arcfour_crypt_sbox(s_box, data, len);
+ struct arcfour_state state;
+ arcfour_init(&state, key);
+ arcfour_crypt_sbox(&state, data, len);
}
/*