58 #else |
58 #else |
59 #define SEC_SUCCESS(Status) ((Status) >= 0) |
59 #define SEC_SUCCESS(Status) ((Status) >= 0) |
60 #define PP(dmt, ...) |
60 #define PP(dmt, ...) |
61 #endif |
61 #endif |
62 |
62 |
63 char KRB5_OID[9] = { |
63 gss_OID_desc KRB5_OID = {9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; |
64 (char)0x2a, (char)0x86, (char)0x48, (char)0x86, (char)0xf7, (char)0x12, |
64 gss_OID_desc SPNEGO_OID = {6, "\x2b\x06\x01\x05\x05\x02"}; |
65 (char)0x01, (char)0x02, (char)0x02}; |
65 gss_OID_desc USER_NAME_OID = {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"}; |
66 char SPNEGO_OID[6] = { |
66 gss_OID_desc HOST_SERVICE_NAME_OID = {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"}; |
67 (char)0x2b, (char)0x06, (char)0x01, (char)0x05, (char)0x05, (char)0x02}; |
67 gss_OID_desc EXPORT_NAME_OID = {6, "\x2b\x06\x01\x05\x06\x04"}; |
68 char USER_NAME_OID[10] = { |
|
69 (char)0x2a, (char)0x86, (char)0x48, (char)0x86, (char)0xf7, (char)0x12, |
|
70 (char)0x01, (char)0x02, (char)0x01, (char)0x01}; |
|
71 char HOST_SERVICE_NAME_OID[10] = { |
|
72 (char)0x2a, (char)0x86, (char)0x48, (char)0x86, (char)0xf7, (char)0x12, |
|
73 (char)0x01, (char)0x02, (char)0x01, (char)0x04}; |
|
74 char EXPORT_NAME_OID[6] = { |
|
75 (char)0x2b, (char)0x06, (char)0x01, (char)0x05, (char)0x06, (char)0x04}; |
|
76 |
68 |
77 // gss_name_t is Name* |
69 // gss_name_t is Name* |
78 // gss_cred_id_t is Credentials*. One CredHandle for each mech. |
70 // gss_cred_id_t is Credentials*. One CredHandle for each mech. |
79 // gss_ctx_id_t is Context* |
71 // gss_ctx_id_t is Context* |
80 |
72 |
109 #endif /* __cplusplus */ |
101 #endif /* __cplusplus */ |
110 |
102 |
111 /* This section holds supporting functions that are not exported */ |
103 /* This section holds supporting functions that are not exported */ |
112 |
104 |
113 long |
105 long |
114 TimeStampToLong(TimeStamp *time) |
106 SecondsUntil(TimeStamp *time) |
115 { |
107 { |
116 ULARGE_INTEGER *a, *b; |
108 ULARGE_INTEGER *a, *b; |
117 FILETIME fnow; |
109 FILETIME fnow; |
118 GetSystemTimeAsFileTime(&fnow); |
110 GetSystemTimeAsFileTime(&fnow); |
119 a = (ULARGE_INTEGER*)time; |
111 a = (ULARGE_INTEGER*)time; |
176 return fout; |
168 return fout; |
177 } |
169 } |
178 |
170 |
179 BOOLEAN |
171 BOOLEAN |
180 isKerberosOID(gss_OID mech) { |
172 isKerberosOID(gss_OID mech) { |
181 return mech->length == sizeof(KRB5_OID) |
173 return mech->length == KRB5_OID.length |
182 && !memcmp(mech->elements, KRB5_OID, sizeof(KRB5_OID)); |
174 && !memcmp(mech->elements, KRB5_OID.elements, KRB5_OID.length); |
183 } |
175 } |
184 |
176 |
185 BOOLEAN |
177 BOOLEAN |
186 isNegotiateOID(gss_OID mech) { |
178 isNegotiateOID(gss_OID mech) { |
187 return mech->length == sizeof(SPNEGO_OID) |
179 return mech->length == SPNEGO_OID.length |
188 && !memcmp(mech->elements, SPNEGO_OID, sizeof(SPNEGO_OID)); |
180 && !memcmp(mech->elements, SPNEGO_OID.elements, SPNEGO_OID.length); |
189 } |
181 } |
190 |
182 |
191 void |
183 void |
192 displayOID(gss_OID mech) |
184 displayOID(gss_OID mech) |
193 { |
185 { |
247 } |
239 } |
248 int len = (int)input_name_buffer->length; |
240 int len = (int)input_name_buffer->length; |
249 LPSTR input = (LPSTR)input_name_buffer->value; |
241 LPSTR input = (LPSTR)input_name_buffer->value; |
250 BOOLEAN isNegotiate = true; |
242 BOOLEAN isNegotiate = true; |
251 if (input_name_type != NULL |
243 if (input_name_type != NULL |
252 && input_name_type->length == sizeof(EXPORT_NAME_OID) |
244 && input_name_type->length == EXPORT_NAME_OID.length |
253 && !memcmp(input_name_type->elements, EXPORT_NAME_OID, |
245 && !memcmp(input_name_type->elements, EXPORT_NAME_OID.elements, |
254 sizeof(EXPORT_NAME_OID))) { |
246 EXPORT_NAME_OID.length)) { |
255 len -= (int)input[3] + 8; |
247 len -= (int)input[3] + 8; |
256 isNegotiate = (int)input[3] == 6; |
248 isNegotiate = (int)input[3] == 6; |
257 input = input + (int)input[3] + 8; |
249 input = input + (int)input[3] + 8; |
258 } |
250 } |
259 |
251 |
265 if (MultiByteToWideChar(CP_ACP, 0, input, len, name, len) == 0) { |
257 if (MultiByteToWideChar(CP_ACP, 0, input, len, name, len) == 0) { |
266 goto err; |
258 goto err; |
267 } |
259 } |
268 name[len] = 0; |
260 name[len] = 0; |
269 if (input_name_type != NULL |
261 if (input_name_type != NULL |
270 && input_name_type->length == sizeof(HOST_SERVICE_NAME_OID) |
262 && input_name_type->length == HOST_SERVICE_NAME_OID.length |
271 && !memcmp(input_name_type->elements, HOST_SERVICE_NAME_OID, |
263 && !memcmp(input_name_type->elements, HOST_SERVICE_NAME_OID.elements, |
272 sizeof(HOST_SERVICE_NAME_OID))) { |
264 HOST_SERVICE_NAME_OID.length)) { |
273 for (int i = 0; i < len; i++) { |
265 for (int i = 0; i < len; i++) { |
274 if (name[i] == '@') { |
266 if (name[i] == '@') { |
275 name[i] = '/'; |
267 name[i] = '/'; |
276 break; |
268 break; |
277 } |
269 } |
340 TCHAR mech = name1->PackageName[0]; |
332 TCHAR mech = name1->PackageName[0]; |
341 PP("name is %ls %ls", name1->PackageName, name1->name); |
333 PP("name is %ls %ls", name1->PackageName, name1->name); |
342 int len = (int)wcslen(names); |
334 int len = (int)wcslen(names); |
343 if (len < 256) { |
335 if (len < 256) { |
344 // 04 01 00 ** 06 ** OID len:int32 name |
336 // 04 01 00 ** 06 ** OID len:int32 name |
345 int mechLen = mech == 'K' ? sizeof(KRB5_OID) : sizeof(SPNEGO_OID); |
337 int mechLen = mech == 'K' ? KRB5_OID.length : SPNEGO_OID.length; |
346 char* buffer = new char[10 + mechLen + len]; |
338 char* buffer = new char[10 + mechLen + len]; |
347 buffer[0] = 4; |
339 buffer[0] = 4; |
348 buffer[1] = 1; |
340 buffer[1] = 1; |
349 buffer[2] = 0; |
341 buffer[2] = 0; |
350 buffer[3] = 2 + mechLen; |
342 buffer[3] = 2 + mechLen; |
351 buffer[4] = 6; |
343 buffer[4] = 6; |
352 buffer[5] = mechLen; |
344 buffer[5] = mechLen; |
353 memcpy(buffer + 6, mech == 'K' ? KRB5_OID : SPNEGO_OID, 9); |
345 memcpy(buffer + 6, mech == 'K' ? KRB5_OID.elements : SPNEGO_OID.elements, 9); |
354 buffer[6 + mechLen] = buffer[7 + mechLen] = buffer[8 + mechLen] = 0; |
346 buffer[6 + mechLen] = buffer[7 + mechLen] = buffer[8 + mechLen] = 0; |
355 buffer[9 + mechLen] = (char)len; |
347 buffer[9 + mechLen] = (char)len; |
356 WideCharToMultiByte(CP_ACP, 0, names, len, buffer+10+mechLen, len, NULL, NULL); |
348 WideCharToMultiByte(CP_ACP, 0, names, len, buffer+10+mechLen, len, NULL, NULL); |
357 exported_name->length = 10 + mechLen + len; |
349 exported_name->length = 10 + mechLen + len; |
358 exported_name->value = buffer; |
350 exported_name->value = buffer; |
377 output_name_buffer->length = len; |
369 output_name_buffer->length = len; |
378 output_name_buffer->value = buffer; |
370 output_name_buffer->value = buffer; |
379 PP("Name found: %ls", names); |
371 PP("Name found: %ls", names); |
380 PP("%d [%s]", len, buffer); |
372 PP("%d [%s]", len, buffer); |
381 if (output_name_type != NULL) { |
373 if (output_name_type != NULL) { |
382 gss_OID_desc* oid = new gss_OID_desc(); |
374 *output_name_type = &USER_NAME_OID; |
383 oid->length = (OM_uint32)strlen(USER_NAME_OID); |
|
384 oid->elements = strdup(USER_NAME_OID); |
|
385 *output_name_type = oid; |
|
386 } |
375 } |
387 return GSS_S_COMPLETE; |
376 return GSS_S_COMPLETE; |
388 } |
377 } |
389 |
378 |
390 __declspec(dllexport) OM_uint32 |
379 __declspec(dllexport) OM_uint32 |
424 cred->creds[i].phCred, |
413 cred->creds[i].phCred, |
425 &ts); |
414 &ts); |
426 } |
415 } |
427 actual_mechs = &desired_mech; // dup? |
416 actual_mechs = &desired_mech; // dup? |
428 *output_cred_handle = (void*)cred; |
417 *output_cred_handle = (void*)cred; |
429 cred->time = TimeStampToLong(&ts); |
418 cred->time = SecondsUntil(&ts); |
430 if (time_rec != NULL) { |
419 if (time_rec != NULL) { |
431 *time_rec = cred->time; |
420 *time_rec = cred->time; |
432 } |
421 } |
433 |
422 |
434 if (desired_name != NULL) { |
423 if (desired_name != NULL) { |
692 PP("new name at %p", n1->name); |
681 PP("new name at %p", n1->name); |
693 lstrcpy(n1->name, pc->nnames.sServerName); |
682 lstrcpy(n1->name, pc->nnames.sServerName); |
694 lstrcpy(n1->PackageName, pc->PackageName); |
683 lstrcpy(n1->PackageName, pc->PackageName); |
695 *targ_name = (gss_name_t) n1; |
684 *targ_name = (gss_name_t) n1; |
696 } |
685 } |
|
686 if (lifetime_rec != NULL) { |
|
687 SecPkgContext_Lifespan ls; |
|
688 QueryContextAttributes(&pc->hCtxt, SECPKG_ATTR_LIFESPAN, &ls); |
|
689 *lifetime_rec = SecondsUntil(&ls.tsExpiry); |
|
690 } |
|
691 if (mech_type != NULL) { |
|
692 // |
|
693 } |
697 // TODO: other inquiries |
694 // TODO: other inquiries |
698 return GSS_S_COMPLETE; |
695 return GSS_S_COMPLETE; |
699 } |
696 } |
700 |
697 |
701 __declspec(dllexport) OM_uint32 |
698 __declspec(dllexport) OM_uint32 |
717 __declspec(dllexport) OM_uint32 |
714 __declspec(dllexport) OM_uint32 |
718 gss_context_time(OM_uint32 *minor_status, |
715 gss_context_time(OM_uint32 *minor_status, |
719 gss_ctx_id_t context_handle, |
716 gss_ctx_id_t context_handle, |
720 OM_uint32 *time_rec) |
717 OM_uint32 *time_rec) |
721 { |
718 { |
722 PP(">>>> Calling UNIMPLEMENTED gss_context_time..."); |
719 PP(">>>> Calling IMPLEMENTED gss_context_time..."); |
723 Context* pc = (Context*) context_handle; |
720 Context* pc = (Context*) context_handle; |
724 return GSS_S_FAILURE; |
721 SecPkgContext_Lifespan ls; |
|
722 QueryContextAttributes(&pc->hCtxt, SECPKG_ATTR_LIFESPAN, &ls); |
|
723 *time_rec = SecondsUntil(&ls.tsExpiry); |
|
724 return GSS_S_COMPLETE; |
725 } |
725 } |
726 |
726 |
727 __declspec(dllexport) OM_uint32 |
727 __declspec(dllexport) OM_uint32 |
728 gss_wrap_size_limit(OM_uint32 *minor_status, |
728 gss_wrap_size_limit(OM_uint32 *minor_status, |
729 gss_ctx_id_t context_handle, |
729 gss_ctx_id_t context_handle, |
954 major = GSS_S_FAILURE; |
954 major = GSS_S_FAILURE; |
955 goto done; |
955 goto done; |
956 } |
956 } |
957 |
957 |
958 if (hasKerberos) { |
958 if (hasKerberos) { |
959 gss_OID_desc oid; |
959 gss_add_oid_set_member(minor_status, &KRB5_OID, mech_set); |
960 oid.length = sizeof(KRB5_OID); |
|
961 oid.elements = KRB5_OID; |
|
962 gss_add_oid_set_member(minor_status, &oid, mech_set); |
|
963 } |
960 } |
964 if (hasSpnego) { |
961 if (hasSpnego) { |
965 gss_OID_desc oid; |
962 gss_add_oid_set_member(minor_status, &SPNEGO_OID, mech_set); |
966 oid.length = sizeof(SPNEGO_OID); |
|
967 oid.elements = SPNEGO_OID; |
|
968 gss_add_oid_set_member(minor_status, &oid, mech_set); |
|
969 } |
963 } |
970 done: |
964 done: |
971 if (major != GSS_S_COMPLETE) { |
965 if (major != GSS_S_COMPLETE) { |
972 // (void) generic_gss_release_oid_set(&minor, ©); |
966 // (void) generic_gss_release_oid_set(&minor, ©); |
973 } |
967 } |
980 const gss_OID mechanism, |
974 const gss_OID mechanism, |
981 gss_OID_set *name_types) |
975 gss_OID_set *name_types) |
982 { |
976 { |
983 PP(">>>> Calling IMPLEMENTED gss_inquire_names_for_mech..."); |
977 PP(">>>> Calling IMPLEMENTED gss_inquire_names_for_mech..."); |
984 gss_create_empty_oid_set(minor_status, name_types); |
978 gss_create_empty_oid_set(minor_status, name_types); |
985 gss_OID_desc oid; |
979 gss_add_oid_set_member(minor_status, &USER_NAME_OID, name_types); |
986 oid.length = sizeof(USER_NAME_OID); |
980 gss_add_oid_set_member(minor_status, &HOST_SERVICE_NAME_OID, name_types); |
987 oid.elements = USER_NAME_OID; |
981 gss_add_oid_set_member(minor_status, &EXPORT_NAME_OID, name_types); |
988 gss_add_oid_set_member(minor_status, &oid, name_types); |
|
989 oid.length = sizeof(HOST_SERVICE_NAME_OID); |
|
990 oid.elements = HOST_SERVICE_NAME_OID; |
|
991 gss_add_oid_set_member(minor_status, &oid, name_types); |
|
992 oid.length = sizeof(EXPORT_NAME_OID); |
|
993 oid.elements = EXPORT_NAME_OID; |
|
994 gss_add_oid_set_member(minor_status, &oid, name_types); |
|
995 return GSS_S_COMPLETE; |
982 return GSS_S_COMPLETE; |
996 } |
983 } |
997 |
984 |
998 __declspec(dllexport) OM_uint32 |
985 __declspec(dllexport) OM_uint32 |
999 gss_add_oid_set_member(OM_uint32 *minor_status, |
986 gss_add_oid_set_member(OM_uint32 *minor_status, |