1/* 2 Unix SMB/Netbios implementation. 3 Version 3.0 4 handle NLTMSSP, client server side parsing 5 6 Copyright (C) Andrew Tridgell 2001 7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005 8 Copyright (C) Stefan Metzmacher 2005 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#include "auth/ntlmssp/ntlmssp.h" 26#include "../librpc/gen_ndr/ntlmssp.h" 27#include "../lib/crypto/crypto.h" 28#include "../libcli/auth/libcli_auth.h" 29#include "auth/credentials/credentials.h" 30#include "auth/gensec/gensec.h" 31#include "param/param.h" 32 33/********************************************************************* 34 Client side NTLMSSP 35*********************************************************************/ 36 37/** 38 * Next state function for the Initial packet 39 * 40 * @param ntlmssp_state NTLMSSP State 41 * @param out_mem_ctx The DATA_BLOB *out will be allocated on this context 42 * @param in A NULL data blob (input ignored) 43 * @param out The initial negotiate request to the server, as an talloc()ed DATA_BLOB, on out_mem_ctx 44 * @return Errors or NT_STATUS_OK. 45 */ 46 47NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security, 48 TALLOC_CTX *out_mem_ctx, 49 DATA_BLOB in, DATA_BLOB *out) 50{ 51 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 52 const char *domain = gensec_ntlmssp_state->domain; 53 const char *workstation = cli_credentials_get_workstation(gensec_security->credentials); 54 55 /* These don't really matter in the initial packet, so don't panic if they are not set */ 56 if (!domain) { 57 domain = ""; 58 } 59 60 if (!workstation) { 61 workstation = ""; 62 } 63 64 if (gensec_ntlmssp_state->unicode) { 65 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; 66 } else { 67 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; 68 } 69 70 if (gensec_ntlmssp_state->use_ntlmv2) { 71 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 72 } 73 74 /* generate the ntlmssp negotiate packet */ 75 msrpc_gen(out_mem_ctx, 76 out, "CddAA", 77 "NTLMSSP", 78 NTLMSSP_NEGOTIATE, 79 gensec_ntlmssp_state->neg_flags, 80 domain, 81 workstation); 82 83 gensec_ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; 84 85 return NT_STATUS_MORE_PROCESSING_REQUIRED; 86} 87 88/** 89 * Next state function for the Challenge Packet. Generate an auth packet. 90 * 91 * @param gensec_security GENSEC state 92 * @param out_mem_ctx Memory context for *out 93 * @param in The server challnege, as a DATA_BLOB. reply.data must be NULL 94 * @param out The next request (auth packet) to the server, as an allocated DATA_BLOB, on the out_mem_ctx context 95 * @return Errors or NT_STATUS_OK. 96 */ 97 98NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, 99 TALLOC_CTX *out_mem_ctx, 100 const DATA_BLOB in, DATA_BLOB *out) 101{ 102 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 103 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; 104 DATA_BLOB server_domain_blob; 105 DATA_BLOB challenge_blob; 106 DATA_BLOB target_info = data_blob(NULL, 0); 107 char *server_domain; 108 const char *chal_parse_string; 109 const char *auth_gen_string; 110 DATA_BLOB lm_response = data_blob(NULL, 0); 111 DATA_BLOB nt_response = data_blob(NULL, 0); 112 DATA_BLOB session_key = data_blob(NULL, 0); 113 DATA_BLOB lm_session_key = data_blob(NULL, 0); 114 DATA_BLOB encrypted_session_key = data_blob(NULL, 0); 115 NTSTATUS nt_status; 116 int flags = 0; 117 const char *user, *domain; 118 119 TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx); 120 if (!mem_ctx) { 121 return NT_STATUS_NO_MEMORY; 122 } 123 124 if (!msrpc_parse(mem_ctx, 125 &in, "CdBd", 126 "NTLMSSP", 127 &ntlmssp_command, 128 &server_domain_blob, 129 &chal_flags)) { 130 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); 131 dump_data(2, in.data, in.length); 132 talloc_free(mem_ctx); 133 134 return NT_STATUS_INVALID_PARAMETER; 135 } 136 137 data_blob_free(&server_domain_blob); 138 139 DEBUG(3, ("Got challenge flags:\n")); 140 debug_ntlmssp_flags(chal_flags); 141 142 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, chal_flags, gensec_ntlmssp_state->allow_lm_key); 143 144 if (gensec_ntlmssp_state->unicode) { 145 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { 146 chal_parse_string = "CdUdbddB"; 147 } else { 148 chal_parse_string = "CdUdbdd"; 149 } 150 auth_gen_string = "CdBBUUUBd"; 151 } else { 152 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { 153 chal_parse_string = "CdAdbddB"; 154 } else { 155 chal_parse_string = "CdAdbdd"; 156 } 157 158 auth_gen_string = "CdBBAAABd"; 159 } 160 161 if (!msrpc_parse(mem_ctx, 162 &in, chal_parse_string, 163 "NTLMSSP", 164 &ntlmssp_command, 165 &server_domain, 166 &chal_flags, 167 &challenge_blob, 8, 168 &unkn1, &unkn2, 169 &target_info)) { 170 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); 171 dump_data(2, in.data, in.length); 172 talloc_free(mem_ctx); 173 return NT_STATUS_INVALID_PARAMETER; 174 } 175 176 gensec_ntlmssp_state->server_domain = server_domain; 177 178 if (challenge_blob.length != 8) { 179 talloc_free(mem_ctx); 180 return NT_STATUS_INVALID_PARAMETER; 181 } 182 183 cli_credentials_get_ntlm_username_domain(gensec_security->credentials, mem_ctx, 184 &user, &domain); 185 186 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 187 flags |= CLI_CRED_NTLM2; 188 } 189 if (gensec_ntlmssp_state->use_ntlmv2) { 190 flags |= CLI_CRED_NTLMv2_AUTH; 191 } 192 if (gensec_ntlmssp_state->use_nt_response) { 193 flags |= CLI_CRED_NTLM_AUTH; 194 } 195 if (lp_client_lanman_auth(gensec_security->settings->lp_ctx)) { 196 flags |= CLI_CRED_LANMAN_AUTH; 197 } 198 199 nt_status = cli_credentials_get_ntlm_response(gensec_security->credentials, mem_ctx, 200 &flags, challenge_blob, target_info, 201 &lm_response, &nt_response, 202 &lm_session_key, &session_key); 203 204 if (!NT_STATUS_IS_OK(nt_status)) { 205 return nt_status; 206 } 207 208 if (!(flags & CLI_CRED_LANMAN_AUTH)) { 209 /* LM Key is still possible, just silly. Fortunetly 210 * we require command line options to end up here */ 211 /* gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */ 212 } 213 214 if (!(flags & CLI_CRED_NTLM2)) { 215 /* NTLM2 is incompatible... */ 216 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; 217 } 218 219 if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 220 && lp_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { 221 DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); 222 if (lm_response.length == 24) { 223 SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, 224 new_session_key.data); 225 } else { 226 static const uint8_t zeros[24]; 227 SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros, 228 new_session_key.data); 229 } 230 session_key = new_session_key; 231 dump_data_pw("LM session key\n", session_key.data, session_key.length); 232 } 233 234 235 /* Key exchange encryptes a new client-generated session key with 236 the password-derived key */ 237 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { 238 /* Make up a new session key */ 239 uint8_t client_session_key[16]; 240 generate_secret_buffer(client_session_key, sizeof(client_session_key)); 241 242 /* Encrypt the new session key with the old one */ 243 encrypted_session_key = data_blob_talloc(gensec_ntlmssp_state, 244 client_session_key, sizeof(client_session_key)); 245 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); 246 arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length); 247 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); 248 249 /* Mark the new session key as the 'real' session key */ 250 session_key = data_blob_talloc(mem_ctx, client_session_key, sizeof(client_session_key)); 251 } 252 253 DEBUG(3, ("NTLMSSP: Set final flags:\n")); 254 debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags); 255 256 /* this generates the actual auth packet */ 257 if (!msrpc_gen(mem_ctx, 258 out, auth_gen_string, 259 "NTLMSSP", 260 NTLMSSP_AUTH, 261 lm_response.data, lm_response.length, 262 nt_response.data, nt_response.length, 263 domain, 264 user, 265 cli_credentials_get_workstation(gensec_security->credentials), 266 encrypted_session_key.data, encrypted_session_key.length, 267 gensec_ntlmssp_state->neg_flags)) { 268 talloc_free(mem_ctx); 269 return NT_STATUS_NO_MEMORY; 270 } 271 272 gensec_ntlmssp_state->session_key = session_key; 273 talloc_steal(gensec_ntlmssp_state, session_key.data); 274 275 talloc_steal(out_mem_ctx, out->data); 276 277 gensec_ntlmssp_state->chal = challenge_blob; 278 gensec_ntlmssp_state->lm_resp = lm_response; 279 talloc_steal(gensec_ntlmssp_state->lm_resp.data, lm_response.data); 280 gensec_ntlmssp_state->nt_resp = nt_response; 281 talloc_steal(gensec_ntlmssp_state->nt_resp.data, nt_response.data); 282 283 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE; 284 285 if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) { 286 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state); 287 if (!NT_STATUS_IS_OK(nt_status)) { 288 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", 289 nt_errstr(nt_status))); 290 talloc_free(mem_ctx); 291 return nt_status; 292 } 293 } 294 295 talloc_free(mem_ctx); 296 return NT_STATUS_OK; 297} 298 299NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) 300{ 301 struct gensec_ntlmssp_state *gensec_ntlmssp_state; 302 NTSTATUS nt_status; 303 304 nt_status = gensec_ntlmssp_start(gensec_security); 305 NT_STATUS_NOT_OK_RETURN(nt_status); 306 307 gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 308 309 gensec_ntlmssp_state->role = NTLMSSP_CLIENT; 310 311 gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx); 312 313 gensec_ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true); 314 315 gensec_ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); 316 317 gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->settings->lp_ctx) 318 && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false) 319 || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false))); 320 321 gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->settings->lp_ctx); 322 323 gensec_ntlmssp_state->expected_state = NTLMSSP_INITIAL; 324 325 gensec_ntlmssp_state->neg_flags = 326 NTLMSSP_NEGOTIATE_NTLM | 327 NTLMSSP_REQUEST_TARGET; 328 329 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) { 330 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; 331 } 332 333 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) { 334 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; 335 } 336 337 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) { 338 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; 339 } 340 341 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) { 342 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; 343 } 344 345 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) { 346 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 347 } 348 349 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) { 350 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 351 } else { 352 /* apparently we can't do ntlmv2 if we don't do ntlm2 */ 353 gensec_ntlmssp_state->use_ntlmv2 = false; 354 } 355 356 if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) { 357 /* 358 * We need to set this to allow a later SetPassword 359 * via the SAMR pipe to succeed. Strange.... We could 360 * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. 361 * 362 * Without this, Windows will not create the master key 363 * that it thinks is only used for NTLMSSP signing and 364 * sealing. (It is actually pulled out and used directly) 365 */ 366 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 367 } 368 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 369 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 370 } 371 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 372 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 373 } 374 375 gensec_security->private_data = gensec_ntlmssp_state; 376 377 return NT_STATUS_OK; 378} 379 380