root/source3/libsmb/ntlmssp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. debug_ntlmssp_flags
  2. get_challenge
  3. may_set_challenge
  4. set_challenge
  5. ntlmssp_set_username
  6. ntlmssp_set_hashes
  7. ntlmssp_set_password
  8. ntlmssp_set_domain
  9. ntlmssp_set_workstation
  10. ntlmssp_store_response
  11. ntlmssp_want_feature_list
  12. ntlmssp_want_feature
  13. ntlmssp_update
  14. ntlmssp_end
  15. ntlmssp_target_name
  16. ntlmssp_handle_neg_flags
  17. ntlmssp_weaken_keys
  18. ntlmssp_server_negotiate
  19. ntlmssp_server_auth
  20. ntlmssp_server_start
  21. ntlmssp_client_initial
  22. ntlmssp_client_challenge
  23. ntlmssp_client_start

   1 /* 
   2    Unix SMB/Netbios implementation.
   3    Version 3.0
   4    handle NLTMSSP, server side
   5 
   6    Copyright (C) Andrew Tridgell      2001
   7    Copyright (C) Andrew Bartlett 2001-2003
   8    Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
   9 
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 3 of the License, or
  13    (at your option) any later version.
  14 
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19 
  20    You should have received a copy of the GNU General Public License
  21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22 */
  23 
  24 #include "includes.h"
  25 
  26 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
  27                                        DATA_BLOB reply, DATA_BLOB *next_request);
  28 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
  29                                          const DATA_BLOB in, DATA_BLOB *out);
  30 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
  31                                          const DATA_BLOB reply, DATA_BLOB *next_request);
  32 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
  33                                     const DATA_BLOB request, DATA_BLOB *reply);
  34 
  35 /**
  36  * Callbacks for NTLMSSP - for both client and server operating modes
  37  * 
  38  */
  39 
  40 static const struct ntlmssp_callbacks {
  41         enum NTLMSSP_ROLE role;
  42         enum NTLM_MESSAGE_TYPE ntlmssp_command;
  43         NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 
  44                        DATA_BLOB in, DATA_BLOB *out);
  45 } ntlmssp_callbacks[] = {
  46         {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
  47         {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
  48         {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
  49         {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
  50         {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
  51         {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
  52 };
  53 
  54 
  55 /**
  56  * Print out the NTLMSSP flags for debugging 
  57  * @param neg_flags The flags from the packet
  58  */
  59 
  60 void debug_ntlmssp_flags(uint32 neg_flags)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
  63 
  64         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) 
  65                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
  66         if (neg_flags & NTLMSSP_NEGOTIATE_OEM) 
  67                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
  68         if (neg_flags & NTLMSSP_REQUEST_TARGET) 
  69                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
  70         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) 
  71                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
  72         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 
  73                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
  74         if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)
  75                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));
  76         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
  77                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
  78         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 
  79                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
  80         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) 
  81                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
  82         if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) 
  83                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
  84         if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) 
  85                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
  86         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) 
  87                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
  88         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
  89                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
  90         if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)
  91                 DEBUGADD(4, ("  NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));
  92         if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)
  93                 DEBUGADD(4, ("  NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));
  94         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 
  95                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
  96         if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 
  97                 DEBUGADD(4, ("  NTLMSSP_CHAL_TARGET_INFO\n"));
  98         if (neg_flags & NTLMSSP_NEGOTIATE_VERSION)
  99                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_VERSION\n"));
 100         if (neg_flags & NTLMSSP_NEGOTIATE_128) 
 101                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
 102         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 
 103                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
 104         if (neg_flags & NTLMSSP_NEGOTIATE_56)
 105                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
 106 }
 107 
 108 /**
 109  * Default challenge generation code.
 110  *
 111  */
 112 
 113 static void get_challenge(const struct ntlmssp_state *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 114                           uint8_t chal[8])
 115 {
 116         generate_random_buffer(chal, 8);
 117 }
 118 
 119 /**
 120  * Default 'we can set the challenge to anything we like' implementation
 121  *
 122  */
 123 
 124 static bool may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
 125 {
 126         return True;
 127 }
 128 
 129 /**
 130  * Default 'we can set the challenge to anything we like' implementation
 131  *
 132  * Does not actually do anything, as the value is always in the structure anyway.
 133  *
 134  */
 135 
 136 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
     /* [<][>][^][v][top][bottom][index][help] */
 137 {
 138         SMB_ASSERT(challenge->length == 8);
 139         return NT_STATUS_OK;
 140 }
 141 
 142 /** 
 143  * Set a username on an NTLMSSP context - ensures it is talloc()ed 
 144  *
 145  */
 146 
 147 NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) 
     /* [<][>][^][v][top][bottom][index][help] */
 148 {
 149         ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" );
 150         if (!ntlmssp_state->user) {
 151                 return NT_STATUS_NO_MEMORY;
 152         }
 153         return NT_STATUS_OK;
 154 }
 155 
 156 /** 
 157  * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed 
 158  *
 159  */
 160 NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 161                 const unsigned char lm_hash[16],
 162                 const unsigned char nt_hash[16]) 
 163 {
 164         ntlmssp_state->lm_hash = (unsigned char *)
 165                 TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16);
 166         ntlmssp_state->nt_hash = (unsigned char *)
 167                 TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16);
 168         if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
 169                 TALLOC_FREE(ntlmssp_state->lm_hash);
 170                 TALLOC_FREE(ntlmssp_state->nt_hash);
 171                 return NT_STATUS_NO_MEMORY;
 172         }
 173         return NT_STATUS_OK;
 174 }
 175 
 176 /** 
 177  * Converts a password to the hashes on an NTLMSSP context.
 178  *
 179  */
 180 NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) 
     /* [<][>][^][v][top][bottom][index][help] */
 181 {
 182         if (!password) {
 183                 ntlmssp_state->lm_hash = NULL;
 184                 ntlmssp_state->nt_hash = NULL;
 185         } else {
 186                 unsigned char lm_hash[16];
 187                 unsigned char nt_hash[16];
 188 
 189                 E_deshash(password, lm_hash);
 190                 E_md4hash(password, nt_hash);
 191                 return ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
 192         }
 193         return NT_STATUS_OK;
 194 }
 195 
 196 /** 
 197  * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
 198  *
 199  */
 200 NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) 
     /* [<][>][^][v][top][bottom][index][help] */
 201 {
 202         ntlmssp_state->domain = talloc_strdup(ntlmssp_state,
 203                                               domain ? domain : "" );
 204         if (!ntlmssp_state->domain) {
 205                 return NT_STATUS_NO_MEMORY;
 206         }
 207         return NT_STATUS_OK;
 208 }
 209 
 210 /** 
 211  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
 212  *
 213  */
 214 NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) 
     /* [<][>][^][v][top][bottom][index][help] */
 215 {
 216         ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
 217         if (!ntlmssp_state->workstation) {
 218                 return NT_STATUS_NO_MEMORY;
 219         }
 220         return NT_STATUS_OK;
 221 }
 222 
 223 /**
 224  *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
 225  *  This copies the data blob
 226  */
 227 
 228 NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 229                                 DATA_BLOB response) 
 230 {
 231         ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
 232                                                           response.data,
 233                                                           response.length);
 234         return NT_STATUS_OK;
 235 }
 236 
 237 /**
 238  * Request features for the NTLMSSP negotiation
 239  *
 240  * @param ntlmssp_state NTLMSSP state
 241  * @param feature_list List of space seperated features requested from NTLMSSP.
 242  */
 243 void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list)
     /* [<][>][^][v][top][bottom][index][help] */
 244 {
 245         /*
 246          * We need to set this to allow a later SetPassword
 247          * via the SAMR pipe to succeed. Strange.... We could
 248          * also add  NTLMSSP_NEGOTIATE_SEAL here. JRA.
 249          */
 250         if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
 251                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
 252         }
 253         if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
 254                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
 255         }
 256         if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
 257                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
 258         }
 259 }
 260 
 261 /**
 262  * Request a feature for the NTLMSSP negotiation
 263  *
 264  * @param ntlmssp_state NTLMSSP state
 265  * @param feature Bit flag specifying the requested feature
 266  */
 267 void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature)
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269         /* As per JRA's comment above */
 270         if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
 271                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
 272         }
 273         if (feature & NTLMSSP_FEATURE_SIGN) {
 274                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
 275         }
 276         if (feature & NTLMSSP_FEATURE_SEAL) {
 277                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
 278         }
 279 }
 280 
 281 /**
 282  * Next state function for the NTLMSSP state machine
 283  * 
 284  * @param ntlmssp_state NTLMSSP State
 285  * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
 286  * @param out The reply, as an allocated DATA_BLOB, caller to free.
 287  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
 288  */
 289 
 290 NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 
     /* [<][>][^][v][top][bottom][index][help] */
 291                         const DATA_BLOB in, DATA_BLOB *out) 
 292 {
 293         DATA_BLOB input;
 294         uint32 ntlmssp_command;
 295         int i;
 296 
 297         if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
 298                 /* Called update after negotiations finished. */
 299                 DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
 300                 return NT_STATUS_INVALID_PARAMETER;
 301         }
 302 
 303         *out = data_blob_null;
 304 
 305         if (!in.length && ntlmssp_state->stored_response.length) {
 306                 input = ntlmssp_state->stored_response;
 307 
 308                 /* we only want to read the stored response once - overwrite it */
 309                 ntlmssp_state->stored_response = data_blob_null;
 310         } else {
 311                 input = in;
 312         }
 313 
 314         if (!input.length) {
 315                 switch (ntlmssp_state->role) {
 316                 case NTLMSSP_CLIENT:
 317                         ntlmssp_command = NTLMSSP_INITIAL;
 318                         break;
 319                 case NTLMSSP_SERVER:
 320                         /* 'datagram' mode - no neg packet */
 321                         ntlmssp_command = NTLMSSP_NEGOTIATE;
 322                         break;
 323                 }
 324         } else {
 325                 if (!msrpc_parse(&input, "Cd",
 326                                  "NTLMSSP",
 327                                  &ntlmssp_command)) {
 328                         DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
 329                         dump_data(2, input.data, input.length);
 330                         return NT_STATUS_INVALID_PARAMETER;
 331                 }
 332         }
 333 
 334         if (ntlmssp_command != ntlmssp_state->expected_state) {
 335                 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
 336                 return NT_STATUS_INVALID_PARAMETER;
 337         }
 338 
 339         for (i=0; ntlmssp_callbacks[i].fn; i++) {
 340                 if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
 341                     && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
 342                         return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
 343                 }
 344         }
 345 
 346         DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 
 347                   ntlmssp_state->role, ntlmssp_command)); 
 348 
 349         return NT_STATUS_INVALID_PARAMETER;
 350 }
 351 
 352 /**
 353  * End an NTLMSSP state machine
 354  * 
 355  * @param ntlmssp_state NTLMSSP State, free()ed by this function
 356  */
 357 
 358 void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
 359 {
 360         (*ntlmssp_state)->ref_count--;
 361 
 362         if ((*ntlmssp_state)->ref_count == 0) {
 363                 data_blob_free(&(*ntlmssp_state)->chal);
 364                 data_blob_free(&(*ntlmssp_state)->lm_resp);
 365                 data_blob_free(&(*ntlmssp_state)->nt_resp);
 366                 TALLOC_FREE(*ntlmssp_state);
 367         }
 368 
 369         *ntlmssp_state = NULL;
 370         return;
 371 }
 372 
 373 /**
 374  * Determine correct target name flags for reply, given server role 
 375  * and negotiated flags
 376  * 
 377  * @param ntlmssp_state NTLMSSP State
 378  * @param neg_flags The flags from the packet
 379  * @param chal_flags The flags to be set in the reply packet
 380  * @return The 'target name' string.
 381  */
 382 
 383 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 384                                        uint32 neg_flags, uint32 *chal_flags) 
 385 {
 386         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
 387                 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
 388                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
 389                 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
 390                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
 391                         return ntlmssp_state->get_global_myname();
 392                 } else {
 393                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
 394                         return ntlmssp_state->get_domain();
 395                 };
 396         } else {
 397                 return "";
 398         }
 399 }
 400 
 401 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 402                                       uint32 neg_flags, bool allow_lm) {
 403         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
 404                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
 405                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
 406                 ntlmssp_state->unicode = True;
 407         } else {
 408                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
 409                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
 410                 ntlmssp_state->unicode = False;
 411         }
 412 
 413         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
 414                 /* other end forcing us to use LM */
 415                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
 416                 ntlmssp_state->use_ntlmv2 = False;
 417         } else {
 418                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
 419         }
 420 
 421         if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
 422                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 423         }
 424 
 425         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
 426                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
 427         }
 428 
 429         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
 430                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
 431         }
 432 
 433         if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
 434                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
 435         }
 436 
 437         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
 438                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
 439         }
 440 
 441         if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
 442                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
 443         }
 444 
 445         if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
 446                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
 447         }
 448 
 449         /* Woop Woop - unknown flag for Windows compatibility...
 450            What does this really do ? JRA. */
 451         if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {
 452                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;
 453         }
 454 
 455         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
 456                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
 457         }
 458 }
 459 
 460 /**
 461  Weaken NTLMSSP keys to cope with down-level clients and servers.
 462 
 463  We probably should have some parameters to control this, but as
 464  it only occours for LM_KEY connections, and this is controlled
 465  by the client lanman auth/lanman auth parameters, it isn't too bad.
 466 */
 467 
 468 DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 469 {
 470         DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
 471                                         ntlmssp_state->session_key.data,
 472                                         ntlmssp_state->session_key.length);
 473 
 474         /* Nothing to weaken.  We certainly don't want to 'extend' the length... */
 475         if (weakened_key.length < 16) {
 476                 /* perhaps there was no key? */
 477                 return weakened_key;
 478         }
 479 
 480         /* Key weakening not performed on the master key for NTLM2
 481            and does not occour for NTLM1.  Therefore we only need
 482            to do this for the LM_KEY.
 483         */
 484 
 485         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
 486                 /* LM key doesn't support 128 bit crypto, so this is
 487                  * the best we can do.  If you negotiate 128 bit, but
 488                  * not 56, you end up with 40 bit... */
 489                 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
 490                         weakened_key.data[7] = 0xa0;
 491                 } else { /* forty bits */
 492                         weakened_key.data[5] = 0xe5;
 493                         weakened_key.data[6] = 0x38;
 494                         weakened_key.data[7] = 0xb0;
 495                 }
 496                 weakened_key.length = 8;
 497         }
 498         return weakened_key;
 499 }
 500 
 501 /**
 502  * Next state function for the Negotiate packet
 503  *
 504  * @param ntlmssp_state NTLMSSP State
 505  * @param request The request, as a DATA_BLOB
 506  * @param request The reply, as an allocated DATA_BLOB, caller to free.
 507  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.
 508  */
 509 
 510 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 511                                          const DATA_BLOB request, DATA_BLOB *reply) 
 512 {
 513         DATA_BLOB struct_blob;
 514         const char *dnsname;
 515         char *dnsdomname = NULL;
 516         uint32 neg_flags = 0;
 517         uint32 ntlmssp_command, chal_flags;
 518         uint8_t cryptkey[8];
 519         const char *target_name;
 520 
 521         /* parse the NTLMSSP packet */
 522 #if 0
 523         file_save("ntlmssp_negotiate.dat", request.data, request.length);
 524 #endif
 525 
 526         if (request.length) {
 527                 if ((request.length < 16) || !msrpc_parse(&request, "Cdd",
 528                                                         "NTLMSSP",
 529                                                         &ntlmssp_command,
 530                                                         &neg_flags)) {
 531                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
 532                                 (unsigned int)request.length));
 533                         dump_data(2, request.data, request.length);
 534                         return NT_STATUS_INVALID_PARAMETER;
 535                 }
 536                 debug_ntlmssp_flags(neg_flags);
 537         }
 538 
 539         ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
 540 
 541         /* Ask our caller what challenge they would like in the packet */
 542         ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);
 543 
 544         /* Check if we may set the challenge */
 545         if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
 546                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
 547         }
 548 
 549         /* The flags we send back are not just the negotiated flags,
 550          * they are also 'what is in this packet'.  Therfore, we
 551          * operate on 'chal_flags' from here on
 552          */
 553 
 554         chal_flags = ntlmssp_state->neg_flags;
 555 
 556         /* get the right name to fill in as 'target' */
 557         target_name = ntlmssp_target_name(ntlmssp_state,
 558                                           neg_flags, &chal_flags);
 559         if (target_name == NULL)
 560                 return NT_STATUS_INVALID_PARAMETER;
 561 
 562         ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
 563         ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
 564                                                         cryptkey, 8);
 565 
 566         /* This should be a 'netbios domain -> DNS domain' mapping */
 567         dnsdomname = get_mydnsdomname(ntlmssp_state);
 568         if (!dnsdomname) {
 569                 dnsdomname = talloc_strdup(ntlmssp_state, "");
 570         }
 571         if (!dnsdomname) {
 572                 return NT_STATUS_NO_MEMORY;
 573         }
 574         strlower_m(dnsdomname);
 575 
 576         dnsname = get_mydnsfullname();
 577         if (!dnsname) {
 578                 dnsname = "";
 579         }
 580 
 581         /* This creates the 'blob' of names that appears at the end of the packet */
 582         if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
 583         {
 584                 msrpc_gen(&struct_blob, "aaaaa",
 585                           NTLMSSP_NAME_TYPE_DOMAIN, target_name,
 586                           NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
 587                           NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
 588                           NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
 589                           0, "");
 590         } else {
 591                 struct_blob = data_blob_null;
 592         }
 593 
 594         {
 595                 /* Marshel the packet in the right format, be it unicode or ASCII */
 596                 const char *gen_string;
 597                 if (ntlmssp_state->unicode) {
 598                         gen_string = "CdUdbddB";
 599                 } else {
 600                         gen_string = "CdAdbddB";
 601                 }
 602 
 603                 msrpc_gen(reply, gen_string,
 604                           "NTLMSSP",
 605                           NTLMSSP_CHALLENGE,
 606                           target_name,
 607                           chal_flags,
 608                           cryptkey, 8,
 609                           0, 0,
 610                           struct_blob.data, struct_blob.length);
 611         }
 612 
 613         data_blob_free(&struct_blob);
 614 
 615         ntlmssp_state->expected_state = NTLMSSP_AUTH;
 616 
 617         return NT_STATUS_MORE_PROCESSING_REQUIRED;
 618 }
 619 
 620 /**
 621  * Next state function for the Authenticate packet
 622  *
 623  * @param ntlmssp_state NTLMSSP State
 624  * @param request The request, as a DATA_BLOB
 625  * @param request The reply, as an allocated DATA_BLOB, caller to free.
 626  * @return Errors or NT_STATUS_OK. 
 627  */
 628 
 629 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
     /* [<][>][^][v][top][bottom][index][help] */
 630                                     const DATA_BLOB request, DATA_BLOB *reply) 
 631 {
 632         DATA_BLOB encrypted_session_key = data_blob_null;
 633         DATA_BLOB user_session_key = data_blob_null;
 634         DATA_BLOB lm_session_key = data_blob_null;
 635         DATA_BLOB session_key = data_blob_null;
 636         uint32 ntlmssp_command, auth_flags;
 637         NTSTATUS nt_status = NT_STATUS_OK;
 638 
 639         /* used by NTLM2 */
 640         bool doing_ntlm2 = False;
 641 
 642         uchar session_nonce[16];
 643         uchar session_nonce_hash[16];
 644 
 645         const char *parse_string;
 646         char *domain = NULL;
 647         char *user = NULL;
 648         char *workstation = NULL;
 649 
 650         /* parse the NTLMSSP packet */
 651         *reply = data_blob_null;
 652 
 653 #if 0
 654         file_save("ntlmssp_auth.dat", request.data, request.length);
 655 #endif
 656 
 657         if (ntlmssp_state->unicode) {
 658                 parse_string = "CdBBUUUBd";
 659         } else {
 660                 parse_string = "CdBBAAABd";
 661         }
 662 
 663         data_blob_free(&ntlmssp_state->lm_resp);
 664         data_blob_free(&ntlmssp_state->nt_resp);
 665 
 666         ntlmssp_state->user = NULL;
 667         ntlmssp_state->domain = NULL;
 668         ntlmssp_state->workstation = NULL;
 669 
 670         /* now the NTLMSSP encoded auth hashes */
 671         if (!msrpc_parse(&request, parse_string,
 672                          "NTLMSSP", 
 673                          &ntlmssp_command, 
 674                          &ntlmssp_state->lm_resp,
 675                          &ntlmssp_state->nt_resp,
 676                          &domain, 
 677                          &user, 
 678                          &workstation,
 679                          &encrypted_session_key,
 680                          &auth_flags)) {
 681                 SAFE_FREE(domain);
 682                 SAFE_FREE(user);
 683                 SAFE_FREE(workstation);
 684                 data_blob_free(&encrypted_session_key);
 685                 auth_flags = 0;
 686 
 687                 /* Try again with a shorter string (Win9X truncates this packet) */
 688                 if (ntlmssp_state->unicode) {
 689                         parse_string = "CdBBUUU";
 690                 } else {
 691                         parse_string = "CdBBAAA";
 692                 }
 693 
 694                 /* now the NTLMSSP encoded auth hashes */
 695                 if (!msrpc_parse(&request, parse_string,
 696                                  "NTLMSSP", 
 697                                  &ntlmssp_command, 
 698                                  &ntlmssp_state->lm_resp,
 699                                  &ntlmssp_state->nt_resp,
 700                                  &domain, 
 701                                  &user, 
 702                                  &workstation)) {
 703                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
 704                         dump_data(2, request.data, request.length);
 705                         SAFE_FREE(domain);
 706                         SAFE_FREE(user);
 707                         SAFE_FREE(workstation);
 708 
 709                         return NT_STATUS_INVALID_PARAMETER;
 710                 }
 711         }
 712 
 713         if (auth_flags)
 714                 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
 715 
 716         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
 717                 SAFE_FREE(domain);
 718                 SAFE_FREE(user);
 719                 SAFE_FREE(workstation);
 720                 data_blob_free(&encrypted_session_key);
 721                 return nt_status;
 722         }
 723 
 724         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
 725                 SAFE_FREE(domain);
 726                 SAFE_FREE(user);
 727                 SAFE_FREE(workstation);
 728                 data_blob_free(&encrypted_session_key);
 729                 return nt_status;
 730         }
 731 
 732         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
 733                 SAFE_FREE(domain);
 734                 SAFE_FREE(user);
 735                 SAFE_FREE(workstation);
 736                 data_blob_free(&encrypted_session_key);
 737                 return nt_status;
 738         }
 739 
 740         SAFE_FREE(domain);
 741         SAFE_FREE(user);
 742         SAFE_FREE(workstation);
 743 
 744         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
 745                  ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
 746 
 747 #if 0
 748         file_save("nthash1.dat",  &ntlmssp_state->nt_resp.data,  &ntlmssp_state->nt_resp.length);
 749         file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
 750 #endif
 751 
 752         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
 753            client challenge 
 754 
 755            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
 756         */
 757         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
 758                 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
 759                         struct MD5Context md5_session_nonce_ctx;
 760                         SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
 761 
 762                         doing_ntlm2 = True;
 763 
 764                         memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
 765                         memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
 766 
 767                         MD5Init(&md5_session_nonce_ctx);
 768                         MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
 769                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
 770 
 771                         ntlmssp_state->chal = data_blob_talloc(
 772                                 ntlmssp_state, session_nonce_hash, 8);
 773 
 774                         /* LM response is no longer useful */
 775                         data_blob_free(&ntlmssp_state->lm_resp);
 776 
 777                         /* We changed the effective challenge - set it */
 778                         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
 779                                 data_blob_free(&encrypted_session_key);
 780                                 return nt_status;
 781                         }
 782 
 783                         /* LM Key is incompatible. */
 784                         ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
 785                 }
 786         }
 787 
 788         /*
 789          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
 790          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
 791          * smb.conf file) and no NTLMv2 response was sent then the password check
 792          * will fail here. JRA.
 793          */
 794 
 795         /* Finally, actually ask if the password is OK */
 796 
 797         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, 
 798                                                                        &user_session_key, &lm_session_key))) {
 799                 data_blob_free(&encrypted_session_key);
 800                 return nt_status;
 801         }
 802 
 803         dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
 804         dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
 805 
 806         /* Handle the different session key derivation for NTLM2 */
 807         if (doing_ntlm2) {
 808                 if (user_session_key.data && user_session_key.length == 16) {
 809                         session_key = data_blob_talloc(ntlmssp_state,
 810                                                        NULL, 16);
 811                         hmac_md5(user_session_key.data, session_nonce, 
 812                                  sizeof(session_nonce), session_key.data);
 813                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
 814                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
 815 
 816                 } else {
 817                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
 818                         session_key = data_blob_null;
 819                 }
 820         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
 821                 if (lm_session_key.data && lm_session_key.length >= 8) {
 822                         if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
 823                                 session_key = data_blob_talloc(ntlmssp_state,
 824                                                                NULL, 16);
 825                                 if (session_key.data == NULL) {
 826                                         return NT_STATUS_NO_MEMORY;
 827                                 }
 828                                 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, 
 829                                                           session_key.data);
 830                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
 831                         } else {
 832                                 uint8 zeros[24];
 833                                 ZERO_STRUCT(zeros);
 834                                 session_key = data_blob_talloc(
 835                                         ntlmssp_state, NULL, 16);
 836                                 if (session_key.data == NULL) {
 837                                         return NT_STATUS_NO_MEMORY;
 838                                 }
 839                                 SMBsesskeygen_lm_sess_key(
 840                                         lm_session_key.data, zeros,
 841                                         session_key.data);
 842                         }
 843                         dump_data_pw("LM session key:\n", session_key.data,
 844                                      session_key.length);
 845                 } else {
 846                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
 847                         session_key = data_blob_null;
 848                 }
 849         } else if (user_session_key.data) {
 850                 session_key = user_session_key;
 851                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
 852                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
 853         } else if (lm_session_key.data) {
 854                 session_key = lm_session_key;
 855                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
 856                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
 857         } else {
 858                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
 859                 session_key = data_blob_null;
 860         }
 861 
 862         /* With KEY_EXCH, the client supplies the proposed session key, 
 863            but encrypts it with the long-term key */
 864         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
 865                 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
 866                         data_blob_free(&encrypted_session_key);
 867                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
 868                                   (unsigned int)encrypted_session_key.length));
 869                         return NT_STATUS_INVALID_PARAMETER;
 870                 } else if (!session_key.data || session_key.length != 16) {
 871                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
 872                                   (unsigned int)session_key.length));
 873                         ntlmssp_state->session_key = session_key;
 874                 } else {
 875                         dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
 876                         SamOEMhash(encrypted_session_key.data, 
 877                                    session_key.data, 
 878                                    encrypted_session_key.length);
 879                         ntlmssp_state->session_key = data_blob_talloc(
 880                                 ntlmssp_state, encrypted_session_key.data,
 881                                 encrypted_session_key.length);
 882                         dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, 
 883                                      encrypted_session_key.length);
 884                 }
 885         } else {
 886                 ntlmssp_state->session_key = session_key;
 887         }
 888 
 889         if (!NT_STATUS_IS_OK(nt_status)) {
 890                 ntlmssp_state->session_key = data_blob_null;
 891         } else if (ntlmssp_state->session_key.length) {
 892                 nt_status = ntlmssp_sign_init(ntlmssp_state);
 893         }
 894 
 895         data_blob_free(&encrypted_session_key);
 896 
 897         /* Only one authentication allowed per server state. */
 898         ntlmssp_state->expected_state = NTLMSSP_DONE;
 899 
 900         return nt_status;
 901 }
 902 
 903 /**
 904  * Create an NTLMSSP state machine
 905  * 
 906  * @param ntlmssp_state NTLMSSP State, allocated by this function
 907  */
 908 
 909 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
 910 {
 911         *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
 912         if (!*ntlmssp_state) {
 913                 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
 914                 talloc_destroy(*ntlmssp_state);
 915                 return NT_STATUS_NO_MEMORY;
 916         }
 917 
 918         (*ntlmssp_state)->role = NTLMSSP_SERVER;
 919 
 920         (*ntlmssp_state)->get_challenge = get_challenge;
 921         (*ntlmssp_state)->set_challenge = set_challenge;
 922         (*ntlmssp_state)->may_set_challenge = may_set_challenge;
 923 
 924         (*ntlmssp_state)->get_global_myname = global_myname;
 925         (*ntlmssp_state)->get_domain = lp_workgroup;
 926         (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
 927 
 928         (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
 929 
 930         (*ntlmssp_state)->ref_count = 1;
 931 
 932         (*ntlmssp_state)->neg_flags = 
 933                 NTLMSSP_NEGOTIATE_128 |
 934                 NTLMSSP_NEGOTIATE_56 |
 935                 NTLMSSP_NEGOTIATE_VERSION |
 936                 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
 937                 NTLMSSP_NEGOTIATE_NTLM |
 938                 NTLMSSP_NEGOTIATE_NTLM2 |
 939                 NTLMSSP_NEGOTIATE_KEY_EXCH |
 940                 NTLMSSP_NEGOTIATE_SIGN |
 941                 NTLMSSP_NEGOTIATE_SEAL;
 942 
 943         return NT_STATUS_OK;
 944 }
 945 
 946 /*********************************************************************
 947  Client side NTLMSSP
 948 *********************************************************************/
 949 
 950 /**
 951  * Next state function for the Initial packet
 952  * 
 953  * @param ntlmssp_state NTLMSSP State
 954  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
 955  * @param request The reply, as an allocated DATA_BLOB, caller to free.
 956  * @return Errors or NT_STATUS_OK. 
 957  */
 958 
 959 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
     /* [<][>][^][v][top][bottom][index][help] */
 960                                   DATA_BLOB reply, DATA_BLOB *next_request) 
 961 {
 962         if (ntlmssp_state->unicode) {
 963                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
 964         } else {
 965                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
 966         }
 967 
 968         if (ntlmssp_state->use_ntlmv2) {
 969                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
 970         }
 971 
 972         /* generate the ntlmssp negotiate packet */
 973         msrpc_gen(next_request, "CddAA",
 974                   "NTLMSSP",
 975                   NTLMSSP_NEGOTIATE,
 976                   ntlmssp_state->neg_flags,
 977                   ntlmssp_state->get_domain(), 
 978                   ntlmssp_state->get_global_myname());
 979 
 980         ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
 981 
 982         return NT_STATUS_MORE_PROCESSING_REQUIRED;
 983 }
 984 
 985 /**
 986  * Next state function for the Challenge Packet.  Generate an auth packet.
 987  * 
 988  * @param ntlmssp_state NTLMSSP State
 989  * @param request The request, as a DATA_BLOB.  reply.data must be NULL
 990  * @param request The reply, as an allocated DATA_BLOB, caller to free.
 991  * @return Errors or NT_STATUS_OK. 
 992  */
 993 
 994 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
     /* [<][>][^][v][top][bottom][index][help] */
 995                                          const DATA_BLOB reply, DATA_BLOB *next_request) 
 996 {
 997         uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
 998         DATA_BLOB server_domain_blob;
 999         DATA_BLOB challenge_blob;
1000         DATA_BLOB struct_blob = data_blob_null;
1001         char *server_domain;
1002         const char *chal_parse_string;
1003         const char *auth_gen_string;
1004         DATA_BLOB lm_response = data_blob_null;
1005         DATA_BLOB nt_response = data_blob_null;
1006         DATA_BLOB session_key = data_blob_null;
1007         DATA_BLOB encrypted_session_key = data_blob_null;
1008         NTSTATUS nt_status = NT_STATUS_OK;
1009 
1010         if (!msrpc_parse(&reply, "CdBd",
1011                          "NTLMSSP",
1012                          &ntlmssp_command, 
1013                          &server_domain_blob,
1014                          &chal_flags)) {
1015                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
1016                 dump_data(2, reply.data, reply.length);
1017 
1018                 return NT_STATUS_INVALID_PARAMETER;
1019         }
1020 
1021         data_blob_free(&server_domain_blob);
1022 
1023         DEBUG(3, ("Got challenge flags:\n"));
1024         debug_ntlmssp_flags(chal_flags);
1025 
1026         ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
1027 
1028         if (ntlmssp_state->unicode) {
1029                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1030                         chal_parse_string = "CdUdbddB";
1031                 } else {
1032                         chal_parse_string = "CdUdbdd";
1033                 }
1034                 auth_gen_string = "CdBBUUUBd";
1035         } else {
1036                 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
1037                         chal_parse_string = "CdAdbddB";
1038                 } else {
1039                         chal_parse_string = "CdAdbdd";
1040                 }
1041 
1042                 auth_gen_string = "CdBBAAABd";
1043         }
1044 
1045         DEBUG(3, ("NTLMSSP: Set final flags:\n"));
1046         debug_ntlmssp_flags(ntlmssp_state->neg_flags);
1047 
1048         if (!msrpc_parse(&reply, chal_parse_string,
1049                          "NTLMSSP",
1050                          &ntlmssp_command, 
1051                          &server_domain,
1052                          &chal_flags,
1053                          &challenge_blob, 8,
1054                          &unkn1, &unkn2,
1055                          &struct_blob)) {
1056                 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
1057                 dump_data(2, reply.data, reply.length);
1058                 return NT_STATUS_INVALID_PARAMETER;
1059         }
1060 
1061         ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state,
1062                                                      server_domain);
1063 
1064         SAFE_FREE(server_domain);
1065         if (challenge_blob.length != 8) {
1066                 data_blob_free(&struct_blob);
1067                 return NT_STATUS_INVALID_PARAMETER;
1068         }
1069 
1070         if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
1071                 uchar zeros[16];
1072                 /* do nothing - blobs are zero length */
1073 
1074                 ZERO_STRUCT(zeros);
1075 
1076                 /* session key is all zeros */
1077                 session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
1078 
1079                 /* not doing NLTM2 without a password */
1080                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
1081         } else if (ntlmssp_state->use_ntlmv2) {
1082 
1083                 if (!struct_blob.length) {
1084                         /* be lazy, match win2k - we can't do NTLMv2 without it */
1085                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
1086                         return NT_STATUS_INVALID_PARAMETER;
1087                 }
1088 
1089                 /* TODO: if the remote server is standalone, then we should replace 'domain'
1090                    with the server name as supplied above */
1091 
1092                 if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user, 
1093                                       ntlmssp_state->domain, 
1094                                       ntlmssp_state->nt_hash, &challenge_blob, 
1095                                       &struct_blob, 
1096                                       &lm_response, &nt_response, &session_key)) {
1097                         data_blob_free(&challenge_blob);
1098                         data_blob_free(&struct_blob);
1099                         return NT_STATUS_NO_MEMORY;
1100                 }
1101         } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
1102                 struct MD5Context md5_session_nonce_ctx;
1103                 uchar session_nonce[16];
1104                 uchar session_nonce_hash[16];
1105                 uchar user_session_key[16];
1106 
1107                 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1108                 generate_random_buffer(lm_response.data, 8);
1109                 memset(lm_response.data+8, 0, 16);
1110 
1111                 memcpy(session_nonce, challenge_blob.data, 8);
1112                 memcpy(&session_nonce[8], lm_response.data, 8);
1113 
1114                 MD5Init(&md5_session_nonce_ctx);
1115                 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
1116                 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
1117                 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
1118 
1119                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
1120                 DEBUG(5, ("challenge is: \n"));
1121                 dump_data(5, session_nonce_hash, 8);
1122 
1123                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1124                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,
1125                              session_nonce_hash,
1126                              nt_response.data);
1127 
1128                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1129 
1130                 SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key);
1131                 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
1132                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
1133         } else {
1134                 /* lanman auth is insecure, it may be disabled */
1135                 if (lp_client_lanman_auth()) {
1136                         lm_response = data_blob_talloc(ntlmssp_state,
1137                                                        NULL, 24);
1138                         SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
1139                                    lm_response.data);
1140                 }
1141 
1142                 nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
1143                 SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data,
1144                              nt_response.data);
1145 
1146                 session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
1147                 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
1148                     && lp_client_lanman_auth()) {
1149                         SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
1150                                         session_key.data);
1151                         dump_data_pw("LM session key\n", session_key.data, session_key.length);
1152                 } else {
1153                         SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, session_key.data);
1154                         dump_data_pw("NT session key:\n", session_key.data, session_key.length);
1155                 }
1156         }
1157         data_blob_free(&struct_blob);
1158 
1159         /* Key exchange encryptes a new client-generated session key with
1160            the password-derived key */
1161         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
1162                 /* Make up a new session key */
1163                 uint8 client_session_key[16];
1164                 generate_random_buffer(client_session_key, sizeof(client_session_key));
1165 
1166                 /* Encrypt the new session key with the old one */
1167                 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
1168                 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
1169                 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
1170                 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
1171 
1172                 /* Mark the new session key as the 'real' session key */
1173                 data_blob_free(&session_key);
1174                 session_key = data_blob_talloc(ntlmssp_state,
1175                                                client_session_key,
1176                                                sizeof(client_session_key));
1177         }
1178 
1179         /* this generates the actual auth packet */
1180         if (!msrpc_gen(next_request, auth_gen_string, 
1181                        "NTLMSSP", 
1182                        NTLMSSP_AUTH, 
1183                        lm_response.data, lm_response.length,
1184                        nt_response.data, nt_response.length,
1185                        ntlmssp_state->domain, 
1186                        ntlmssp_state->user, 
1187                        ntlmssp_state->get_global_myname(), 
1188                        encrypted_session_key.data, encrypted_session_key.length,
1189                        ntlmssp_state->neg_flags)) {
1190 
1191                 return NT_STATUS_NO_MEMORY;
1192         }
1193 
1194         data_blob_free(&encrypted_session_key);
1195 
1196         data_blob_free(&ntlmssp_state->chal);
1197 
1198         ntlmssp_state->session_key = session_key;
1199 
1200         ntlmssp_state->chal = challenge_blob;
1201         ntlmssp_state->lm_resp = lm_response;
1202         ntlmssp_state->nt_resp = nt_response;
1203 
1204         ntlmssp_state->expected_state = NTLMSSP_DONE;
1205 
1206         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
1207                 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
1208         }
1209 
1210         return nt_status;
1211 }
1212 
1213 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
     /* [<][>][^][v][top][bottom][index][help] */
1214 {
1215         *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
1216         if (!*ntlmssp_state) {
1217                 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
1218                 talloc_destroy(*ntlmssp_state);
1219                 return NT_STATUS_NO_MEMORY;
1220         }
1221 
1222         (*ntlmssp_state)->role = NTLMSSP_CLIENT;
1223 
1224         (*ntlmssp_state)->get_global_myname = global_myname;
1225         (*ntlmssp_state)->get_domain = lp_workgroup;
1226 
1227         (*ntlmssp_state)->unicode = True;
1228 
1229         (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
1230 
1231         (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
1232 
1233         (*ntlmssp_state)->ref_count = 1;
1234 
1235         (*ntlmssp_state)->neg_flags = 
1236                 NTLMSSP_NEGOTIATE_128 |
1237                 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
1238                 NTLMSSP_NEGOTIATE_NTLM |
1239                 NTLMSSP_NEGOTIATE_NTLM2 |
1240                 NTLMSSP_NEGOTIATE_KEY_EXCH |
1241                 NTLMSSP_REQUEST_TARGET;
1242 
1243         return NT_STATUS_OK;
1244 }

/* [<][>][^][v][top][bottom][index][help] */