@@ -21,27 +21,55 @@ uint32_t gssntlm_cli_auth(uint32_t *minor_status,
21
21
struct ntlm_buffer auth_mic = { NULL , 16 };
22
22
uint8_t micbuf [16 ];
23
23
struct ntlm_buffer mic = { micbuf , 16 };
24
+ char * username ;
25
+ char * domain ;
26
+ bool ext_sec ;
24
27
bool add_mic = false;
25
28
bool key_exch ;
26
29
uint32_t retmaj ;
27
30
uint32_t retmin ;
28
31
32
+ ext_sec = (in_flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY );
33
+
29
34
switch (cred -> type ) {
30
35
36
+ case GSSNTLM_CRED_EXTERNAL :
37
+ retmin = external_cli_auth (ctx , cred , in_flags , input_chan_bindings );
38
+ if (retmin ) {
39
+ set_GSSERR (retmin );
40
+ goto done ;
41
+ }
42
+ set_GSSERRS (0 , GSS_S_COMPLETE );
43
+ return GSSERR ();
44
+
45
+ case GSSNTLM_CRED_ANON :
46
+
47
+ /* Anonymous auth, empty responses */
48
+ if (!(ctx -> gss_flags & GSS_C_ANON_FLAG )) {
49
+ set_GSSERR (EINVAL );
50
+ goto done ;
51
+ }
52
+
53
+ domain = NULL ;
54
+ username = NULL ;
55
+ memset (& nt_chal_resp , 0 , sizeof (nt_chal_resp ));
56
+ lm_chal_resp .data = malloc (1 );
57
+ if (!lm_chal_resp .data ) {
58
+ set_GSSERR (ENOMEM );
59
+ goto done ;
60
+ }
61
+ lm_chal_resp .data [0 ] = 0 ;
62
+ lm_chal_resp .length = 1 ;
63
+
64
+ memset (key_exchange_key .data , 0 , 16 );
65
+ break ;
66
+
31
67
case GSSNTLM_CRED_USER :
32
68
33
- if (ctx -> gss_flags & GSS_C_ANON_FLAG ) {
34
- /* Anonymous auth, empty responses */
35
- memset (& nt_chal_resp , 0 , sizeof (nt_chal_resp ));
36
- lm_chal_resp .data = malloc (1 );
37
- if (!lm_chal_resp .data ) {
38
- set_GSSERR (ENOMEM );
39
- goto done ;
40
- }
41
- lm_chal_resp .data [0 ] = 0 ;
42
- lm_chal_resp .length = 1 ;
69
+ domain = cred -> cred .user .user .data .user .domain ;
70
+ username = cred -> cred .user .user .data .user .name ;
43
71
44
- } else if (gssntlm_sec_v2_ok (ctx )) {
72
+ if (gssntlm_sec_v2_ok (ctx )) {
45
73
46
74
/* ### NTLMv2 ### */
47
75
uint8_t client_chal [8 ];
@@ -111,9 +139,7 @@ uint32_t gssntlm_cli_auth(uint32_t *minor_status,
111
139
112
140
/* NTLMv2 Key */
113
141
retmin = NTOWFv2 (ctx -> ntlm , & cred -> cred .user .nt_hash ,
114
- cred -> cred .user .user .data .user .name ,
115
- cred -> cred .user .user .data .user .domain ,
116
- & ntlmv2_key );
142
+ username , domain , & ntlmv2_key );
117
143
if (retmin ) {
118
144
set_GSSERR (retmin );
119
145
goto done ;
@@ -160,7 +186,6 @@ uint32_t gssntlm_cli_auth(uint32_t *minor_status,
160
186
struct ntlm_buffer cli_chal = { client_chal , 8 };
161
187
struct ntlm_key session_base_key = { .length = 16 };
162
188
bool NoLMResponseNTLMv1 = !gssntlm_sec_lm_ok (ctx );
163
- bool ext_sec ;
164
189
165
190
nt_chal_resp .length = 24 ;
166
191
nt_chal_resp .data = calloc (1 , nt_chal_resp .length );
@@ -178,8 +203,6 @@ uint32_t gssntlm_cli_auth(uint32_t *minor_status,
178
203
goto done ;
179
204
}
180
205
181
- ext_sec = (in_flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY );
182
-
183
206
retmin = ntlm_compute_nt_response (& cred -> cred .user .nt_hash ,
184
207
ext_sec , ctx -> server_chal ,
185
208
client_chal , & nt_chal_resp );
@@ -219,77 +242,69 @@ uint32_t gssntlm_cli_auth(uint32_t *minor_status,
219
242
}
220
243
}
221
244
222
- key_exch = (in_flags & NTLMSSP_NEGOTIATE_KEY_EXCH );
223
-
224
- retmin = ntlm_exported_session_key (& key_exchange_key , key_exch ,
225
- & ctx -> exported_session_key );
226
- if (retmin ) {
227
- set_GSSERR (retmin );
228
- goto done ;
229
- }
245
+ break ;
230
246
231
- if (key_exch ) {
232
- retmin = ntlm_encrypted_session_key (& key_exchange_key ,
233
- & ctx -> exported_session_key ,
234
- & encrypted_random_session_key );
235
- if (retmin ) {
236
- set_GSSERR (retmin );
237
- goto done ;
238
- }
239
- }
247
+ default :
248
+ set_GSSERR (ERR_NOUSRCRED );
249
+ goto done ;
250
+ }
240
251
241
- /* in_flags all verified, assign as current flags */
242
- ctx -> neg_flags |= in_flags ;
252
+ key_exch = (in_flags & NTLMSSP_NEGOTIATE_KEY_EXCH );
243
253
244
- enc_sess_key .data = encrypted_random_session_key .data ;
245
- enc_sess_key .length = encrypted_random_session_key .length ;
254
+ retmin = ntlm_exported_session_key (& key_exchange_key , key_exch ,
255
+ & ctx -> exported_session_key );
256
+ if (retmin ) {
257
+ set_GSSERR (retmin );
258
+ goto done ;
259
+ }
246
260
247
- retmin = ntlm_encode_auth_msg (ctx -> ntlm , ctx -> neg_flags ,
248
- & lm_chal_resp , & nt_chal_resp ,
249
- cred -> cred .user .user .data .user .domain ,
250
- cred -> cred .user .user .data .user .name ,
251
- ctx -> workstation , & enc_sess_key ,
252
- add_mic ? & auth_mic : NULL ,
253
- & ctx -> auth_msg );
261
+ if (key_exch ) {
262
+ retmin = ntlm_encrypted_session_key (& key_exchange_key ,
263
+ & ctx -> exported_session_key ,
264
+ & encrypted_random_session_key );
254
265
if (retmin ) {
255
266
set_GSSERR (retmin );
256
267
goto done ;
257
268
}
269
+ }
258
270
259
- /* Now we need to calculate the MIC, because the MIC is part of the
260
- * message it protects, ntlm_encode_auth_msg() always add a zeroeth
261
- * buffer, however it returns in data_mic the pointer to the actual
262
- * area in the auth_msg that points at the mic, so we can backfill */
263
- if (add_mic ) {
264
- retmin = ntlm_mic (& ctx -> exported_session_key , & ctx -> nego_msg ,
265
- & ctx -> chal_msg , & ctx -> auth_msg , & mic );
266
- if (retmin ) {
267
- set_GSSERR (retmin );
268
- goto done ;
269
- }
270
- /* now that we have the mic, copy it into the auth message */
271
- memcpy (auth_mic .data , mic .data , 16 );
271
+ /* in_flags all verified, assign as current flags */
272
+ ctx -> neg_flags |= in_flags ;
272
273
273
- /* Make sure SPNEGO gets to know it has to add mechlistMIC too */
274
- ctx -> int_flags |= NTLMSSP_CTX_FLAG_AUTH_WITH_MIC ;
275
- }
274
+ enc_sess_key .data = encrypted_random_session_key .data ;
275
+ enc_sess_key .length = encrypted_random_session_key .length ;
276
276
277
- set_GSSERRS (0 , GSS_S_COMPLETE );
278
- break ;
277
+ retmin = ntlm_encode_auth_msg (ctx -> ntlm , ctx -> neg_flags ,
278
+ & lm_chal_resp , & nt_chal_resp ,
279
+ domain , username ,
280
+ ctx -> workstation , & enc_sess_key ,
281
+ add_mic ? & auth_mic : NULL ,
282
+ & ctx -> auth_msg );
283
+ if (retmin ) {
284
+ set_GSSERR (retmin );
285
+ goto done ;
286
+ }
279
287
280
- case GSSNTLM_CRED_EXTERNAL :
281
- retmin = external_cli_auth (ctx , cred , in_flags , input_chan_bindings );
288
+ /* Now we need to calculate the MIC, because the MIC is part of the
289
+ * message it protects, ntlm_encode_auth_msg() always add a zeroeth
290
+ * buffer, however it returns in data_mic the pointer to the actual
291
+ * area in the auth_msg that points at the mic, so we can backfill */
292
+ if (add_mic ) {
293
+ retmin = ntlm_mic (& ctx -> exported_session_key , & ctx -> nego_msg ,
294
+ & ctx -> chal_msg , & ctx -> auth_msg , & mic );
282
295
if (retmin ) {
283
296
set_GSSERR (retmin );
284
297
goto done ;
285
298
}
286
- set_GSSERRS ( 0 , GSS_S_COMPLETE );
287
- break ;
299
+ /* now that we have the mic, copy it into the auth message */
300
+ memcpy ( auth_mic . data , mic . data , 16 ) ;
288
301
289
- default :
290
- set_GSSERR ( ERR_NOUSRCRED ) ;
302
+ /* Make sure SPNEGO gets to know it has to add mechlistMIC too */
303
+ ctx -> int_flags |= NTLMSSP_CTX_FLAG_AUTH_WITH_MIC ;
291
304
}
292
305
306
+ set_GSSERRS (0 , GSS_S_COMPLETE );
307
+
293
308
done :
294
309
ntlm_free_buffer_data (& client_target_info );
295
310
ntlm_free_buffer_data (& nt_chal_resp );
0 commit comments