37 #include <freetds/time.h>
38 #include <freetds/tds.h>
39 #include <freetds/bytes.h>
41 #include <freetds/iconv.h>
46 #include "replacements.h"
88 const unsigned char *challenge,
90 const unsigned char *names_blob,
TDS_INT names_blob_len,
TDSANSWER * answer,
unsigned char **ntlm_v2_response);
91 static void tds_encrypt_answer(
const unsigned char *
hash,
const unsigned char *challenge,
unsigned char *answer);
125 memset(suppress, 0,
sizeof(char_conv->
suppress));
136 size_t passwd_len = 0;
137 char passwd_usc2le[256];
138 size_t passwd_usc2le_len = 0;
140 passwd_len = strlen(passwd);
142 if (passwd_len > 128)
146 if (passwd_usc2le_len == (
size_t) -1) {
147 memset((
char *) passwd_usc2le, 0,
sizeof(passwd_usc2le));
157 memset((
char *) passwd_usc2le, 0, passwd_usc2le_len);
166 const char *user_name, *domain;
167 size_t domain_len, user_name_len = 0,
len, buf_usc2le_len = 0;
170 unsigned char ntlm_hash[16];
172 char buf_usc2le[512];
178 p = user_name ? strchr(user_name,
'\\') :
NULL;
181 domain_len = p ? p - user_name : 0;
185 user_name_len = strlen(user_name);
188 if (user_name_len > 128)
190 memcpy(
buf, user_name, user_name_len);
194 if (
len == (
size_t) -1)
196 buf_usc2le_len =
len;
198 if (domain_len > 128)
203 if (
len == (
size_t) -1)
205 buf_usc2le_len +=
len;
209 hmac_md5(ntlm_hash, (
const unsigned char *) buf_usc2le, buf_usc2le_len, ntlm_v2_hash);
212 memset(&ntlm_hash, 0,
sizeof(ntlm_hash));
213 memset(
buf, 0,
sizeof(
buf));
214 memset((
char *) buf_usc2le, 0, buf_usc2le_len);
224 static unsigned char *
226 const unsigned char *client_data,
TDS_INT client_data_len,
const unsigned char challenge[8])
228 int mac_len = 16 + client_data_len;
231 mac =
tds_new(
unsigned char, mac_len);
235 memcpy(mac + 8, challenge, 8);
236 if (client_data_len > 0) {
238 memcpy(mac + 16, client_data, client_data_len);
240 hmac_md5(ntlm_v2_hash, mac + 8, client_data_len + 8, mac);
248 const unsigned char *challenge,
250 const unsigned char *names_blob,
TDS_INT names_blob_len,
TDSANSWER * answer,
unsigned char **ntlm_v2_response)
256 unsigned char *lm_v2_response;
257 unsigned char ntlm_v2_hash[16];
273 memcpy(answer->
lm_resp, lm_v2_response, 24);
274 free(lm_v2_response);
278 *ntlm_v2_response =
make_lm_v2_response(ntlm_v2_hash, names_blob, names_blob_len, challenge);
279 if (!*ntlm_v2_response)
282 memset(ntlm_v2_hash, 0,
sizeof(ntlm_v2_hash));
299 const unsigned char *challenge,
301 const unsigned char *names_blob,
TDS_INT names_blob_len,
TDSANSWER * answer,
unsigned char **ntlm_v2_response)
306 unsigned char hash[24], ntlm2_challenge[16];
313 names_blob, names_blob_len, answer, ntlm_v2_response);
314 }
else if ((*
flags & 0x80000) != 0) {
319 memset(
hash + 8, 0, 16);
325 MD5Final(&md5_ctx, ntlm2_challenge);
326 challenge = ntlm2_challenge;
327 memset(&md5_ctx, 0,
sizeof(md5_ctx));
332 static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
336 len = strlen(passwd);
340 passwd_buf[
i] =
toupper((
unsigned char) passwd[
i]);
350 memset(
hash + 16, 0, 5);
353 memset(passwd_buf, 0,
sizeof(passwd_buf));
361 memset(
hash + 16, 0, 5);
366 memset(&ks, 0,
sizeof(ks));
368 memset(ntlm2_challenge, 0,
sizeof(ntlm2_challenge));
392 memset(&ks, 0,
sizeof(ks));
406 key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
407 key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
408 key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
409 key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
410 key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
411 key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
412 key[7] = (key_56[6] << 1) & 0xFF;
417 memset(&
key, 0,
sizeof(
key));
422 const unsigned char *challenge,
TDS_UINT flags,
const unsigned char *names_blob,
TDS_INT names_blob_len)
429 const char *user_name;
431 size_t user_name_len, host_name_len, domain_len;
434 unsigned char *ntlm_v2_response =
NULL;
435 unsigned int ntlm_response_len = 24;
436 const unsigned int lm_response_len = 24;
449 if (user_name ==
NULL || (p = strchr(user_name,
'\\')) ==
NULL)
453 domain_len = p - user_name;
456 user_name_len = strlen(user_name);
462 ntlm_response_len = ntlm_v2_response ? 16 + names_blob_len : 24;
470 current_pos = 64u + (domain_len + user_name_len + host_name_len) * 2u;
476 current_pos += lm_response_len;
489 current_pos += domain_len * 2u;
495 current_pos += user_name_len * 2u;
501 current_pos += host_name_len * 2u;
506 TDS_PUT_INT(
tds, current_pos + lm_response_len + ntlm_response_len);
523 if (ntlm_v2_response ==
NULL) {
529 memset(ntlm_v2_response, 0, ntlm_response_len);
530 free(ntlm_v2_response);
555 static const unsigned char ntlm_id[] =
"NTLMSSP";
565 #define TIME_FIXUP_CONSTANT (((TDS_UINT8) 134774U) * 86400U)
571 t2 *= 1000u * 1000u * 10u;
572 t2 += tv->tv_usec * 10u;
583 gettimeofday(&tv,
NULL);
590 #ifdef WORDS_BIGENDIAN
602 const int length = (
int)
len;
603 unsigned char nonce[8];
607 int data_block_offset;
609 int names_blob_len = 0;
610 unsigned char *names_blob =
NULL;
619 if (memcmp(nonce,
ntlm_id, 8) != 0)
634 if (data_block_offset >= 48 && where + 16 <= length) {
635 int target_info_len, target_info_offset;
646 if (data_block_offset >= 56 && where + 8 <= length) {
651 if (target_info_len > 0)
658 if (target_info_len > 0 && target_info_offset >= where && target_info_offset + target_info_len <= length) {
660 where = target_info_offset;
671 names_blob =
tds_new0(
unsigned char, names_blob_len);
677 where += target_info_len;
700 const char *user_name;
715 if ((p = strchr(user_name,
'\\')) ==
NULL)
719 domain_len = (
int)(p - user_name);
763 memcpy(packet + 40 + host_name_len, domain, domain_len);
std::ofstream out("events_result.xml")
main entry point for tests
static CS_CONNECTION * conn
#define TDS_PUT_A4LE(ptr, val)
#define TDS_PUT_A2LE(ptr, val)
#define TDS_PUT_A4(ptr, val)
#define TDS_ENCODING_MEMCPY
#define TDS_OFFSET(str, field)
tds_sysdep_int32_type TDS_INT
#define tds_get_smallint(tds)
unsigned char TDS_TINYINT
tds_sysdep_int16_type TDS_SMALLINT
#define tds_new0(type, n)
tds_sysdep_uint64_type TDS_UINT8
#define TDS_PUT_INT(tds, v)
tds_sysdep_uint32_type TDS_UINT
#define TDS_PUT_SMALLINT(tds, v)
#define TIME_FIXUP_CONSTANT
#define tds_random_buffer
#define tds_des_ecb_encrypt
#define tds_des_set_odd_parity
static TDSRET tds_answer_challenge_ntlmv2(TDSSOCKET *tds, TDSLOGIN *login, const unsigned char *challenge, TDS_UINT *flags, const unsigned char *names_blob, TDS_INT names_blob_len, TDSANSWER *answer, unsigned char **ntlm_v2_response)
static unsigned char * make_lm_v2_response(const unsigned char ntlm_v2_hash[16], const unsigned char *client_data, TDS_INT client_data_len, const unsigned char challenge[8])
static const unsigned char ntlm_id[]
static TDSRET tds7_send_auth(TDSSOCKET *tds, const unsigned char *challenge, TDS_UINT flags, const unsigned char *names_blob, TDS_INT names_blob_len)
static TDSRET make_ntlm_hash(TDSSOCKET *tds, const char *passwd, unsigned char ntlm_hash[16])
static TDSRET tds_answer_challenge(TDSSOCKET *tds, TDSLOGIN *login, const unsigned char *challenge, TDS_UINT *flags, const unsigned char *names_blob, TDS_INT names_blob_len, TDSANSWER *answer, unsigned char **ntlm_v2_response)
Crypt a given password using schema required for NTLMv1 or NTLM2 authentication.
static void tds_encrypt_answer(const unsigned char *hash, const unsigned char *challenge, unsigned char *answer)
static void convert_to_upper(char *buf, size_t len)
TDSAUTHENTICATION * tds_ntlm_get_auth(TDSSOCKET *tds)
Build a NTLMSPP packet to send to server.
static void fill_names_blob_prefix(names_blob_prefix_t *prefix)
static void unix_to_nt_time(TDS_UINT8 *nt, struct timeval *tv)
put a 8 byte filetime from a time_t This takes GMT as input
struct tds_ntlm_auth TDSNTLMAUTH
static TDSRET tds_ntlm_handle_next(TDSSOCKET *tds, struct tds_authentication *auth, size_t len)
static size_t convert_to_usc2le_string(TDSSOCKET *tds, const char *s, size_t len, char *out)
static void tds_convert_key(const unsigned char *key_56, DES_KEY *ks)
static TDSRET make_ntlm_v2_hash(TDSSOCKET *tds, const char *passwd, unsigned char ntlm_v2_hash[16])
struct tds_answer TDSANSWER
static TDSRET tds_ntlm_free(TDSCONNECTION *conn, TDSAUTHENTICATION *tds_auth)
static const char * tds_dstr_cstr(DSTR *s)
Returns a C version (NUL terminated string) of dstr.
static size_t tds_dstr_len(DSTR *s)
Returns the length of the string in bytes.
unsigned int
A callback function used to compare two keys in a database.
unsigned char des_cblock[8]
if(yy_accept[yy_current_state])
const struct ncbi::grid::netcache::search::fields::KEY key
TDS_TINYINT response_type
TDS_TINYINT max_response_type
unsigned char nt_resp[24]
unsigned char lm_resp[24]
TDSRET(* free)(TDSCONNECTION *conn, struct tds_authentication *auth)
TDSRET(* handle_next)(TDSSOCKET *tds, struct tds_authentication *auth, size_t len)
DSTR user_name
account for login
DSTR password
password of account login
TDSAUTHENTICATION tds_auth
Information for a server connection.
TDSLOGIN * login
config for login stuff.
unsigned char out_flag
output buffer type
TDS_ERRNO_MESSAGE_FLAGS suppress
static CS_CONTEXT * context