src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp
branchJDK-8199569-branch
changeset 56562 94c6b9e7df00
parent 56555 0cd4e27a12cf
child 56574 3813511b3d24
equal deleted inserted replaced
56555:0cd4e27a12cf 56562:94c6b9e7df00
    51         printf("SECURITY_STATUS: (%lx) %ls\n", ss, _bb), \
    51         printf("SECURITY_STATUS: (%lx) %ls\n", ss, _bb), \
    52         FALSE))
    52         FALSE))
    53 #define PP(fmt, ...) \
    53 #define PP(fmt, ...) \
    54         fprintf(stdout, "SSPI (%ld): ", __LINE__); \
    54         fprintf(stdout, "SSPI (%ld): ", __LINE__); \
    55         fprintf(stdout, fmt, ##__VA_ARGS__); \
    55         fprintf(stdout, fmt, ##__VA_ARGS__); \
       
    56         fprintf(stdout, "\n"); \
    56         fflush(stdout)
    57         fflush(stdout)
    57 #else
    58 #else
    58 #define SEC_SUCCESS(Status) ((Status) >= 0)
    59 #define SEC_SUCCESS(Status) ((Status) >= 0)
    59 #define PP(dmt, ...)
    60 #define PP(dmt, ...)
    60 #endif
    61 #endif
    69         (char)0x01, (char)0x02, (char)0x01, (char)0x01};
    70         (char)0x01, (char)0x02, (char)0x01, (char)0x01};
    70 char HOST_SERVICE_NAME_OID[10] = {
    71 char HOST_SERVICE_NAME_OID[10] = {
    71         (char)0x2a, (char)0x86, (char)0x48, (char)0x86, (char)0xf7, (char)0x12,
    72         (char)0x2a, (char)0x86, (char)0x48, (char)0x86, (char)0xf7, (char)0x12,
    72         (char)0x01, (char)0x02, (char)0x01, (char)0x04};
    73         (char)0x01, (char)0x02, (char)0x01, (char)0x04};
    73 
    74 
    74 // gss_name_t is SecPkgCredentials_Names*
    75 // gss_name_t is SecPkgCredentials_Names*. Same for all mechs (?)
    75 // gss_cred_id_t is CredHandle*
    76 // gss_cred_id_t is Credentials*. One CredHandle for each mech.
    76 // gss_ctx_id_t is Context*
    77 // gss_ctx_id_t is Context*
    77 
    78 
    78 typedef struct {
    79 typedef struct {
    79     TCHAR PackageName[20];
    80     TCHAR PackageName[20];
    80     CredHandle* phCred;
    81     CredHandle* phCred;
    81     struct _SecHandle hCtxt;
    82     struct _SecHandle hCtxt;
    82     DWORD cbMaxMessage;
    83     DWORD cbMaxMessage;
    83     SecPkgContext_Sizes SecPkgContextSizes;
    84     SecPkgContext_Sizes SecPkgContextSizes;
       
    85     SecPkgContext_NativeNames nnames;
       
    86     BOOLEAN established;
    84 } Context;
    87 } Context;
       
    88 
       
    89 typedef struct {
       
    90     TCHAR PackageName[20];
       
    91     CredHandle* phCred;
       
    92 } OneCred;
       
    93 
       
    94 typedef struct {
       
    95     int count;
       
    96     OneCred* creds;
       
    97 } Credential;
    85 
    98 
    86 #ifdef __cplusplus
    99 #ifdef __cplusplus
    87 extern "C" {
   100 extern "C" {
    88 #endif /* __cplusplus */
   101 #endif /* __cplusplus */
    89 
   102 
    95     ULARGE_INTEGER *a, *b;
   108     ULARGE_INTEGER *a, *b;
    96     FILETIME fnow;
   109     FILETIME fnow;
    97     GetSystemTimeAsFileTime(&fnow);
   110     GetSystemTimeAsFileTime(&fnow);
    98     a = (ULARGE_INTEGER*)time;
   111     a = (ULARGE_INTEGER*)time;
    99     b = (ULARGE_INTEGER*)&fnow;
   112     b = (ULARGE_INTEGER*)&fnow;
   100     PP("Difference %ld\n", (long)((a->QuadPart - b->QuadPart) / 10000000));
   113     PP("Difference %ld", (long)((a->QuadPart - b->QuadPart) / 10000000));
   101     return (long)((a->QuadPart - b->QuadPart) / 10000000);
   114     return (long)((a->QuadPart - b->QuadPart) / 10000000);
   102 }
   115 }
   103 
   116 
   104 void
   117 void
   105 FillContextAfterEstablished(Context *pc)
   118 FillContextAfterEstablished(Context *pc)
   119     if (!SEC_SUCCESS(ss)) {
   132     if (!SEC_SUCCESS(ss)) {
   120         return NULL;
   133         return NULL;
   121     }
   134     }
   122     out->phCred = NULL;
   135     out->phCred = NULL;
   123     out->cbMaxMessage = pkgInfo->cbMaxToken;
   136     out->cbMaxMessage = pkgInfo->cbMaxToken;
   124     PP("   QuerySecurityPackageInfo %ls goes %ld\n", PackageName, out->cbMaxMessage);
   137     PP("   QuerySecurityPackageInfo %ls goes %ld", PackageName, out->cbMaxMessage);
   125     wcscpy(out->PackageName, PackageName);
   138     wcscpy(out->PackageName, PackageName);
   126     FreeContextBuffer(pkgInfo);
   139     FreeContextBuffer(pkgInfo);
   127     return out;
   140     return out;
   128 }
   141 }
   129 
   142 
   151 	if (fin & GSS_C_REPLAY_FLAG) fout |= ISC_RET_REPLAY_DETECT;
   164 	if (fin & GSS_C_REPLAY_FLAG) fout |= ISC_RET_REPLAY_DETECT;
   152 	if (fin & GSS_C_SEQUENCE_FLAG) fout |= ISC_RET_SEQUENCE_DETECT;
   165 	if (fin & GSS_C_SEQUENCE_FLAG) fout |= ISC_RET_SEQUENCE_DETECT;
   153 	return fout;
   166 	return fout;
   154 }
   167 }
   155 
   168 
       
   169 BOOLEAN
       
   170 isKerberosOID(gss_OID mech) {
       
   171     return mech->length == sizeof(KRB5_OID)
       
   172             && !memcmp(mech->elements, KRB5_OID, sizeof(KRB5_OID));
       
   173 }
       
   174 
       
   175 BOOLEAN
       
   176 isNegotiateOID(gss_OID mech) {
       
   177     return mech->length == sizeof(SPNEGO_OID)
       
   178             && !memcmp(mech->elements, SPNEGO_OID, sizeof(SPNEGO_OID));
       
   179 }
       
   180 
       
   181 void
       
   182 displayOID(gss_OID mech)
       
   183 {
       
   184     if (isKerberosOID(mech)) {
       
   185         PP("Kerberos OID");
       
   186     } else if (isNegotiateOID(mech)) {
       
   187         PP("SPNEGO OID");
       
   188     } else {
       
   189         PP("UNKNOWN %d", mech->length);
       
   190     }
       
   191 }
       
   192 
       
   193 void
       
   194 displayOidSet(gss_OID_set mechs)
       
   195 {
       
   196     if (mechs == NULL) {
       
   197         PP("OID set is NULL");
       
   198         return;
       
   199     }
       
   200     PP("set.count is %d", (int)mechs->count);
       
   201     for (int i = 0; i < mechs->count; i++) {
       
   202         displayOID(&mechs->elements[i]);
       
   203     }
       
   204 }
       
   205 
   156 /* End support section */
   206 /* End support section */
   157 
   207 
   158 /* This section holds exported functions that currently have no implementation */
   208 /* This section holds exported functions that currently have no implementation */
   159 
   209 
   160 __declspec(dllexport) OM_uint32
   210 __declspec(dllexport) OM_uint32
   161 gss_release_name(OM_uint32 *minor_status,
   211 gss_release_name(OM_uint32 *minor_status,
   162                  gss_name_t *name)
   212                  gss_name_t *name)
   163 {
   213 {
   164     if (name != NULL) {
   214     PP(">>>> Calling gss_release_name...");
   165         SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)name;
   215     if (name != NULL && *name != GSS_C_NO_NAME) {
   166         if (names->sUserName != NULL) {
   216 //        SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)*name;
   167             delete[] names->sUserName;
   217 //        if (names->sUserName != NULL) {
   168         }
   218 //            delete[] names->sUserName;
   169         delete names;
   219 //        }
   170         *name = GSS_C_NO_NAME;
   220 //        delete names;
       
   221 //        *name = GSS_C_NO_NAME;
   171     }
   222     }
   172     return GSS_S_COMPLETE;
   223     return GSS_S_COMPLETE;
   173 }
   224 }
   174 
   225 
   175 __declspec(dllexport) OM_uint32
   226 __declspec(dllexport) OM_uint32
   176 gss_import_name(OM_uint32 *minor_status,
   227 gss_import_name(OM_uint32 *minor_status,
   177                 gss_buffer_t input_name_buffer,
   228                 gss_buffer_t input_name_buffer,
   178                 gss_OID input_name_type,
   229                 gss_OID input_name_type,
   179                 gss_name_t *output_name)
   230                 gss_name_t *output_name)
   180 {
   231 {
       
   232     PP(">>>> Calling gss_import_name...");
   181     if (input_name_buffer == NULL || input_name_buffer->value == NULL
   233     if (input_name_buffer == NULL || input_name_buffer->value == NULL
   182             || input_name_buffer->length == 0) {
   234             || input_name_buffer->length == 0) {
   183         return GSS_S_BAD_NAME;
   235         return GSS_S_CALL_INACCESSIBLE_READ;
   184     }
   236     }
   185     SecPkgCredentials_Names* names = new SecPkgCredentials_Names();
   237     SecPkgCredentials_Names* names = new SecPkgCredentials_Names();
   186     if (names == NULL) {
   238     if (names == NULL) {
   187         goto err;
   239         return GSS_S_CALL_INACCESSIBLE_WRITE;
   188     }
   240     }
   189     int len = (int)input_name_buffer->length;
   241     int len = (int)input_name_buffer->length;
   190     names->sUserName = new SEC_WCHAR[len + 1];
   242     names->sUserName = new SEC_WCHAR[len + 1];
   191     if (names->sUserName == NULL) {
   243     if (names->sUserName == NULL) {
   192         goto err;
   244         goto err;
   221 gss_compare_name(OM_uint32 *minor_status,
   273 gss_compare_name(OM_uint32 *minor_status,
   222                  gss_name_t name1,
   274                  gss_name_t name1,
   223                  gss_name_t name2,
   275                  gss_name_t name2,
   224                  int *name_equal)
   276                  int *name_equal)
   225 {
   277 {
       
   278     PP(">>>> Calling gss_compare_name...");
   226     if (name1 == NULL || name2 == NULL) {
   279     if (name1 == NULL || name2 == NULL) {
   227         *name_equal = 0;
   280         *name_equal = 0;
   228         return GSS_S_BAD_NAME;
   281         return GSS_S_CALL_INACCESSIBLE_READ;
   229     }
   282     }
   230 
   283 
   231     SecPkgCredentials_Names* names1 = (SecPkgCredentials_Names*)name1;
   284     SecPkgCredentials_Names* names1 = (SecPkgCredentials_Names*)name1;
   232     SecPkgCredentials_Names* names2 = (SecPkgCredentials_Names*)name2;
   285     SecPkgCredentials_Names* names2 = (SecPkgCredentials_Names*)name2;
   233     if (lstrcmp(names1->sUserName, names2->sUserName)) {
   286     if (lstrcmp(names1->sUserName, names2->sUserName)) {
   242 gss_canonicalize_name(OM_uint32 *minor_status,
   295 gss_canonicalize_name(OM_uint32 *minor_status,
   243                       gss_name_t input_name,
   296                       gss_name_t input_name,
   244                       gss_OID mech_type,
   297                       gss_OID mech_type,
   245                       gss_name_t *output_name)
   298                       gss_name_t *output_name)
   246 {
   299 {
       
   300     PP(">>>> Calling gss_canonicalize_name...");
   247     SecPkgCredentials_Names* names1 = (SecPkgCredentials_Names*)input_name;
   301     SecPkgCredentials_Names* names1 = (SecPkgCredentials_Names*)input_name;
   248     SecPkgCredentials_Names* names2 = new SecPkgCredentials_Names();
   302     SecPkgCredentials_Names* names2 = new SecPkgCredentials_Names();
   249     names2->sUserName = new SEC_WCHAR[lstrlen(names1->sUserName) + 1];
   303     names2->sUserName = new SEC_WCHAR[lstrlen(names1->sUserName) + 1];
   250     lstrcpy(names2->sUserName, names1->sUserName);
   304     lstrcpy(names2->sUserName, names1->sUserName);
   251     *output_name = (gss_name_t)names2;
   305     *output_name = (gss_name_t)names2;
   255 __declspec(dllexport) OM_uint32
   309 __declspec(dllexport) OM_uint32
   256 gss_export_name(OM_uint32 *minor_status,
   310 gss_export_name(OM_uint32 *minor_status,
   257                 gss_name_t input_name,
   311                 gss_name_t input_name,
   258                 gss_buffer_t exported_name)
   312                 gss_buffer_t exported_name)
   259 {
   313 {
       
   314     PP(">>>> Calling gss_export_name...");
   260     SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)input_name;
   315     SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)input_name;
   261     int len = (int)wcslen(names->sUserName);
   316     int len = (int)wcslen(names->sUserName);
   262     char* buffer = new char[len+1];
   317     char* buffer = new char[len+1];
   263     WideCharToMultiByte(CP_ACP, 0, names->sUserName, len, buffer, len, NULL, NULL);
   318     WideCharToMultiByte(CP_ACP, 0, names->sUserName, len, buffer, len, NULL, NULL);
   264     buffer[len] = 0;
   319     buffer[len] = 0;
   271 gss_display_name(OM_uint32 *minor_status,
   326 gss_display_name(OM_uint32 *minor_status,
   272                  gss_name_t input_name,
   327                  gss_name_t input_name,
   273                  gss_buffer_t output_name_buffer,
   328                  gss_buffer_t output_name_buffer,
   274                  gss_OID *output_name_type)
   329                  gss_OID *output_name_type)
   275 {
   330 {
       
   331     PP(">>>> Calling gss_display_name...");
   276     SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)input_name;
   332     SecPkgCredentials_Names* names = (SecPkgCredentials_Names*)input_name;
   277     int len = (int)wcslen(names->sUserName);
   333     int len = (int)wcslen(names->sUserName);
   278     char* buffer = new char[len+1];
   334     char* buffer = new char[len+1];
   279     WideCharToMultiByte(CP_ACP, 0, names->sUserName, len, buffer, len, NULL, NULL);
   335     WideCharToMultiByte(CP_ACP, 0, names->sUserName, len, buffer, len, NULL, NULL);
   280     buffer[len] = 0;
   336     buffer[len] = 0;
   281     output_name_buffer->length = len+1;
   337     output_name_buffer->length = len+1;
   282     output_name_buffer->value = buffer;
   338     output_name_buffer->value = buffer;
   283     PP("Name found: %ls\n", names->sUserName);
   339     PP("Name found: %ls", names->sUserName);
   284     PP("%d [%s]", len, buffer);
   340     PP("%d [%s]", len, buffer);
   285     if (output_name_type != NULL) {
   341     if (output_name_type != NULL) {
   286         gss_OID_desc* oid = new gss_OID_desc();
   342         gss_OID_desc* oid = new gss_OID_desc();
   287         oid->length = (OM_uint32)strlen(USER_NAME_OID);
   343         oid->length = (OM_uint32)strlen(USER_NAME_OID);
   288         oid->elements = strdup(USER_NAME_OID);
   344         oid->elements = strdup(USER_NAME_OID);
   299                  gss_cred_usage_t cred_usage,
   355                  gss_cred_usage_t cred_usage,
   300                  gss_cred_id_t *output_cred_handle,
   356                  gss_cred_id_t *output_cred_handle,
   301                  gss_OID_set *actual_mechs,
   357                  gss_OID_set *actual_mechs,
   302                  OM_uint32 *time_rec)
   358                  OM_uint32 *time_rec)
   303 {
   359 {
   304     if (desired_name != NULL) {
   360     PP(">>>> Calling gss_acquire_cred...");
   305         return GSS_S_FAILURE; // Only support default cred
       
   306     }
       
   307     SECURITY_STATUS ss;
   361     SECURITY_STATUS ss;
   308     CredHandle* cred = new CredHandle();
       
   309     TimeStamp ts;
   362     TimeStamp ts;
   310 	cred_usage = 0;
   363 	cred_usage = 0;
   311     PP("AcquireCredentialsHandle with %d\n", cred_usage);
   364     PP("AcquireCredentialsHandle with %d %p", cred_usage, desired_mech);
   312     ss = AcquireCredentialsHandle(
   365     displayOidSet(desired_mech);
   313             NULL,
   366     Credential* cred = new Credential();
   314             L"Kerberos",
   367     cred->count = (int)desired_mech->count;
   315             cred_usage == 0 ? SECPKG_CRED_BOTH :
   368     cred->creds = new OneCred[cred->count];
   316                 (cred_usage == 1 ? SECPKG_CRED_OUTBOUND : SECPKG_CRED_INBOUND),
   369     for (int i = 0; i < cred->count; i++) {
   317             NULL,
   370 PP("");
   318             NULL,
   371         TCHAR* name = isKerberosOID(&desired_mech->elements[i])
   319             NULL,
   372                 ? L"Kerberos" : L"Negotiate";
   320             NULL,
   373 PP("");
   321             cred,
   374         wcscpy(cred->creds[i].PackageName, name);
   322             &ts);
   375         cred->creds[i].phCred = new CredHandle();
   323 
   376 PP("");
   324     actual_mechs = &desired_mech;
   377         ss = AcquireCredentialsHandle(
       
   378                 NULL,
       
   379                 name,
       
   380                 cred_usage == 0 ? SECPKG_CRED_BOTH :
       
   381                     (cred_usage == 1 ? SECPKG_CRED_OUTBOUND : SECPKG_CRED_INBOUND),
       
   382                 NULL,
       
   383                 NULL,
       
   384                 NULL,
       
   385                 NULL,
       
   386                 cred->creds[i].phCred,
       
   387                 &ts);
       
   388 PP("");
       
   389     }
       
   390 PP("");
       
   391     actual_mechs = &desired_mech; // dup?
   325     *output_cred_handle = (void*)cred;
   392     *output_cred_handle = (void*)cred;
   326     if (time_rec != NULL) {
   393     if (time_rec != NULL) {
   327         *time_rec = TimeStampToLong(&ts);
   394         *time_rec = TimeStampToLong(&ts);
   328     }
   395     }
   329 
   396 
       
   397     if (desired_name != NULL) {
       
   398         gss_name_t realname;
       
   399         gss_inquire_cred(minor_status, *output_cred_handle, &realname,
       
   400                 NULL, NULL, NULL);
       
   401         SecPkgCredentials_Names* dnames = (SecPkgCredentials_Names*)desired_name;
       
   402         SecPkgCredentials_Names* rnames = (SecPkgCredentials_Names*)realname;
       
   403         int cmp = lstrcmp(dnames->sUserName, rnames->sUserName);
       
   404         gss_release_name(minor_status, &realname);
       
   405         return cmp ? GSS_S_FAILURE : GSS_S_COMPLETE; // Only support default cred
       
   406     }
       
   407 
   330     return GSS_S_COMPLETE;
   408     return GSS_S_COMPLETE;
   331 }
   409 }
   332 
   410 
   333 __declspec(dllexport) OM_uint32
   411 __declspec(dllexport) OM_uint32
   334 gss_release_cred(OM_uint32 *minor_status,
   412 gss_release_cred(OM_uint32 *minor_status,
   335                  gss_cred_id_t *cred_handle)
   413                  gss_cred_id_t *cred_handle)
   336 {
   414 {
       
   415     PP(">>>> Calling gss_release_cred...");
   337     if (cred_handle && *cred_handle) {
   416     if (cred_handle && *cred_handle) {
   338         FreeCredentialsHandle((CredHandle*)*cred_handle);
   417         Credential* cred = (Credential*)*cred_handle;
       
   418         for (int i = 0; i < cred->count; i++) {
       
   419             FreeCredentialsHandle(cred->creds[i].phCred);
       
   420             delete cred->creds[i].phCred;
       
   421         }
       
   422         delete cred;
   339         *cred_handle = GSS_C_NO_CREDENTIAL;
   423         *cred_handle = GSS_C_NO_CREDENTIAL;
   340     }
   424     }
   341     return GSS_S_COMPLETE;
   425     return GSS_S_COMPLETE;
   342 }
   426 }
   343 
   427 
   347                  gss_name_t *name,
   431                  gss_name_t *name,
   348                  OM_uint32 *lifetime,
   432                  OM_uint32 *lifetime,
   349                  gss_cred_usage_t *cred_usage,
   433                  gss_cred_usage_t *cred_usage,
   350                  gss_OID_set *mechanisms)
   434                  gss_OID_set *mechanisms)
   351 {
   435 {
   352     CredHandle* cred = (CredHandle*)cred_handle;
   436     PP(">>>> Calling gss_inquire_cred...");
       
   437     CredHandle* cred = ((Credential*)cred_handle)->creds[0].phCred;
   353     SECURITY_STATUS ss;
   438     SECURITY_STATUS ss;
   354     if (name) {
   439     if (name) {
   355         SecPkgCredentials_Names* names = new SecPkgCredentials_Names();
   440         SecPkgCredentials_Names* names = new SecPkgCredentials_Names();
   356         ss = QueryCredentialsAttributes(cred, SECPKG_CRED_ATTR_NAMES, names);
   441         ss = QueryCredentialsAttributes(cred, SECPKG_CRED_ATTR_NAMES, names);
   357         *name = (gss_name_t) names;
   442         *name = (gss_name_t) names;
   363 __declspec(dllexport) OM_uint32
   448 __declspec(dllexport) OM_uint32
   364 gss_import_sec_context(OM_uint32 *minor_status,
   449 gss_import_sec_context(OM_uint32 *minor_status,
   365                        gss_buffer_t interprocess_token,
   450                        gss_buffer_t interprocess_token,
   366                        gss_ctx_id_t *context_handle)
   451                        gss_ctx_id_t *context_handle)
   367 {
   452 {
       
   453     PP(">>>> Calling UNIMPLEMENTED gss_import_sec_context...");
   368     return GSS_S_FAILURE;
   454     return GSS_S_FAILURE;
   369 }
   455 }
   370 
   456 
   371 __declspec(dllexport) OM_uint32
   457 __declspec(dllexport) OM_uint32
   372 gss_init_sec_context(OM_uint32 *minor_status,
   458 gss_init_sec_context(OM_uint32 *minor_status,
   381                      gss_OID *actual_mech_type,
   467                      gss_OID *actual_mech_type,
   382                      gss_buffer_t output_token,
   468                      gss_buffer_t output_token,
   383                      OM_uint32 *ret_flags,
   469                      OM_uint32 *ret_flags,
   384                      OM_uint32 *time_rec)
   470                      OM_uint32 *time_rec)
   385 {
   471 {
       
   472     PP(">>>> Calling gss_init_sec_context...");
   386     SECURITY_STATUS ss;
   473     SECURITY_STATUS ss;
   387     TimeStamp Lifetime;
   474     TimeStamp Lifetime;
   388     SecBufferDesc InBuffDesc;
   475     SecBufferDesc InBuffDesc;
   389     SecBuffer InSecBuff;
   476     SecBuffer InSecBuff;
   390     SecBufferDesc OutBuffDesc;
   477     SecBufferDesc OutBuffDesc;
   391     SecBuffer OutSecBuff;
   478     SecBuffer OutSecBuff;
   392 
   479 
   393     Context* pc;
   480     Context* pc;
   394     if (input_token->length == 0) {
   481     if (input_token->length == 0) {
   395         pc = NewContext(L"Kerberos");
   482         TCHAR* name = isKerberosOID(mech_type) ? L"Kerberos" : L"Negotiate";
   396         pc->phCred = (CredHandle*)initiator_cred_handle;
   483         pc = NewContext(name);
       
   484         Credential* cred = (Credential*)initiator_cred_handle;
       
   485         if (cred != NULL) {
       
   486             for (int i = 0; i < cred->count; i++) {
       
   487                 if (!lstrcmp(cred->creds[i].PackageName, name)) {
       
   488                     pc->phCred = cred->creds[i].phCred;
       
   489                 }
       
   490             }
       
   491         }
   397         *context_handle = (gss_ctx_id_t) pc;
   492         *context_handle = (gss_ctx_id_t) pc;
   398     } else {
   493     } else {
   399         pc = (Context*)*context_handle;
   494         pc = (Context*)*context_handle;
   400     }
   495     }
   401 
   496 
   431         InSecBuff.BufferType = SECBUFFER_TOKEN;
   526         InSecBuff.BufferType = SECBUFFER_TOKEN;
   432         InSecBuff.cbBuffer = (ULONG)input_token->length;
   527         InSecBuff.cbBuffer = (ULONG)input_token->length;
   433         InSecBuff.pvBuffer = input_token->value;
   528         InSecBuff.pvBuffer = input_token->value;
   434     } else {
   529     } else {
   435         if (!pc->phCred) {
   530         if (!pc->phCred) {
   436             PP("No credentials provided, acquire automatically");
   531             PP("No credentials %p provided, acquire %ls automatically",
       
   532                     pc->phCred, pc->PackageName);
       
   533             CredHandle* newCred = new CredHandle();
   437             ss = AcquireCredentialsHandle(
   534             ss = AcquireCredentialsHandle(
   438                     NULL,
   535                     NULL,
   439                     pc->PackageName,
   536                     pc->PackageName,
   440                     SECPKG_CRED_OUTBOUND,
   537                     SECPKG_CRED_OUTBOUND,
   441                     NULL,
   538                     NULL,
   442                     NULL,
   539                     NULL,
   443                     NULL,
   540                     NULL,
   444                     NULL,
   541                     NULL,
   445                     pc->phCred,
   542                     newCred,
   446                     &Lifetime);
   543                     &Lifetime);
       
   544             pc->phCred = newCred;
   447             PP("end");
   545             PP("end");
   448             if (!(SEC_SUCCESS(ss))) {
   546             if (!(SEC_SUCCESS(ss))) {
   449                 PP("Failed");
   547                 PP("Failed");
   450                 return GSS_S_FAILURE;
   548                 return GSS_S_FAILURE;
   451             }
   549             }
   490 
   588 
   491     *ret_flags = (OM_uint32)outFlag;
   589     *ret_flags = (OM_uint32)outFlag;
   492     if (ss == SEC_I_CONTINUE_NEEDED) {
   590     if (ss == SEC_I_CONTINUE_NEEDED) {
   493         return GSS_S_CONTINUE_NEEDED;
   591         return GSS_S_CONTINUE_NEEDED;
   494     } else {
   592     } else {
       
   593         pc->established = true;
       
   594         QueryContextAttributes(&pc->hCtxt, SECPKG_ATTR_NATIVE_NAMES, &pc->nnames);
   495         *ret_flags |= GSS_C_PROT_READY_FLAG;
   595         *ret_flags |= GSS_C_PROT_READY_FLAG;
   496         return GSS_S_COMPLETE;
   596         return GSS_S_COMPLETE;
   497     }
   597     }
   498 }
   598 }
   499 
   599 
   508                        gss_buffer_t output_token,
   608                        gss_buffer_t output_token,
   509                        OM_uint32 *ret_flags,
   609                        OM_uint32 *ret_flags,
   510                        OM_uint32 *time_rec,
   610                        OM_uint32 *time_rec,
   511                        gss_cred_id_t *delegated_cred_handle)
   611                        gss_cred_id_t *delegated_cred_handle)
   512 {
   612 {
       
   613     PP(">>>> Calling UNIMPLEMENTED gss_accept_sec_context...");
   513     return GSS_S_FAILURE;
   614     return GSS_S_FAILURE;
   514 }
   615 }
   515 
   616 
   516 __declspec(dllexport) OM_uint32
   617 __declspec(dllexport) OM_uint32
   517 gss_inquire_context(OM_uint32 *minor_status,
   618 gss_inquire_context(OM_uint32 *minor_status,
   522                     gss_OID *mech_type,
   623                     gss_OID *mech_type,
   523                     OM_uint32 *ctx_flags,
   624                     OM_uint32 *ctx_flags,
   524                     int *locally_initiated,
   625                     int *locally_initiated,
   525                     int *open)
   626                     int *open)
   526 {
   627 {
       
   628     PP(">>>> Calling UNIMPLEMENTED gss_inquire_context...");
   527     Context* pc = (Context*) context_handle;
   629     Context* pc = (Context*) context_handle;
   528     return GSS_S_FAILURE;
   630     if (!pc->established) {
       
   631         return GSS_S_NO_CONTEXT;
       
   632     }
       
   633     if (src_name != NULL) {
       
   634         SecPkgCredentials_Names* n = new SecPkgCredentials_Names();
       
   635         n->sUserName = new SEC_WCHAR[lstrlen(pc->nnames.sClientName) + 1];
       
   636         lstrcpy(n->sUserName, pc->nnames.sClientName);
       
   637         *src_name = (gss_name_t) n;
       
   638     }
       
   639     if (targ_name != NULL) {
       
   640         SecPkgCredentials_Names* n = new SecPkgCredentials_Names();
       
   641         n->sUserName = new SEC_WCHAR[lstrlen(pc->nnames.sServerName) + 1];
       
   642         lstrcpy(n->sUserName, pc->nnames.sServerName);
       
   643         *targ_name = (gss_name_t) n;
       
   644     }
       
   645     // TODO: other inquiries
       
   646     return GSS_S_COMPLETE;
   529 }
   647 }
   530 
   648 
   531 __declspec(dllexport) OM_uint32
   649 __declspec(dllexport) OM_uint32
   532 gss_delete_sec_context(OM_uint32 *minor_status,
   650 gss_delete_sec_context(OM_uint32 *minor_status,
   533                        gss_ctx_id_t *context_handle,
   651                        gss_ctx_id_t *context_handle,
   534                        gss_buffer_t output_token)
   652                        gss_buffer_t output_token)
   535 {
   653 {
       
   654     PP(">>>> Calling UNIMPLEMENTED gss_delete_sec_context...");
   536     return GSS_S_FAILURE;
   655     return GSS_S_FAILURE;
   537 }
   656 }
   538 
   657 
   539 __declspec(dllexport) OM_uint32
   658 __declspec(dllexport) OM_uint32
   540 gss_context_time(OM_uint32 *minor_status,
   659 gss_context_time(OM_uint32 *minor_status,
   541                  gss_ctx_id_t context_handle,
   660                  gss_ctx_id_t context_handle,
   542                  OM_uint32 *time_rec)
   661                  OM_uint32 *time_rec)
   543 {
   662 {
       
   663     PP(">>>> Calling UNIMPLEMENTED gss_context_time...");
   544     Context* pc = (Context*) context_handle;
   664     Context* pc = (Context*) context_handle;
   545     return GSS_S_FAILURE;
   665     return GSS_S_FAILURE;
   546 }
   666 }
   547 
   667 
   548 __declspec(dllexport) OM_uint32
   668 __declspec(dllexport) OM_uint32
   551                     int conf_req_flag,
   671                     int conf_req_flag,
   552                     gss_qop_t qop_req,
   672                     gss_qop_t qop_req,
   553                     OM_uint32 req_output_size,
   673                     OM_uint32 req_output_size,
   554                     OM_uint32 *max_input_size)
   674                     OM_uint32 *max_input_size)
   555 {
   675 {
       
   676     PP(">>>> Calling gss_wrap_size_limit...");
   556     Context* pc = (Context*) context_handle;
   677     Context* pc = (Context*) context_handle;
   557     *max_input_size = pc->cbMaxMessage;
   678     *max_input_size = pc->cbMaxMessage;
   558     return GSS_S_COMPLETE;
   679     return GSS_S_COMPLETE;
   559 }
   680 }
   560 
   681 
   561 __declspec(dllexport) OM_uint32
   682 __declspec(dllexport) OM_uint32
   562 gss_export_sec_context(OM_uint32 *minor_status,
   683 gss_export_sec_context(OM_uint32 *minor_status,
   563                        gss_ctx_id_t *context_handle,
   684                        gss_ctx_id_t *context_handle,
   564                        gss_buffer_t interprocess_token)
   685                        gss_buffer_t interprocess_token)
   565 {
   686 {
       
   687     PP(">>>> Calling UNIMPLEMENTED gss_export_sec_context...");
   566     return GSS_S_FAILURE;
   688     return GSS_S_FAILURE;
   567 }
   689 }
   568 
   690 
   569 __declspec(dllexport) OM_uint32
   691 __declspec(dllexport) OM_uint32
   570 gss_get_mic(OM_uint32 *minor_status,
   692 gss_get_mic(OM_uint32 *minor_status,
   571             gss_ctx_id_t context_handle,
   693             gss_ctx_id_t context_handle,
   572             gss_qop_t qop_req,
   694             gss_qop_t qop_req,
   573             gss_buffer_t message_buffer,
   695             gss_buffer_t message_buffer,
   574             gss_buffer_t msg_token)
   696             gss_buffer_t msg_token)
   575 {
   697 {
       
   698     PP(">>>> Calling gss_get_mic...");
   576     Context* pc = (Context*) context_handle;
   699     Context* pc = (Context*) context_handle;
   577 
   700 
   578     SECURITY_STATUS ss;
   701     SECURITY_STATUS ss;
   579     SecBufferDesc BuffDesc;
   702     SecBufferDesc BuffDesc;
   580     SecBuffer SecBuff[2];
   703     SecBuffer SecBuff[2];
   607                gss_ctx_id_t context_handle,
   730                gss_ctx_id_t context_handle,
   608                gss_buffer_t message_buffer,
   731                gss_buffer_t message_buffer,
   609                gss_buffer_t token_buffer,
   732                gss_buffer_t token_buffer,
   610                gss_qop_t *qop_state)
   733                gss_qop_t *qop_state)
   611 {
   734 {
       
   735     PP(">>>> Calling gss_verify_mic...");
   612     Context* pc = (Context*) context_handle;
   736     Context* pc = (Context*) context_handle;
   613 
   737 
   614     SECURITY_STATUS ss;
   738     SECURITY_STATUS ss;
   615     SecBufferDesc BuffDesc;
   739     SecBufferDesc BuffDesc;
   616     SecBuffer SecBuff[2];
   740     SecBuffer SecBuff[2];
   647          gss_qop_t qop_req,
   771          gss_qop_t qop_req,
   648          gss_buffer_t input_message_buffer,
   772          gss_buffer_t input_message_buffer,
   649          int *conf_state,
   773          int *conf_state,
   650          gss_buffer_t output_message_buffer)
   774          gss_buffer_t output_message_buffer)
   651 {
   775 {
       
   776     PP(">>>> Calling gss_wrap...");
   652     Context* pc = (Context*) context_handle;
   777     Context* pc = (Context*) context_handle;
   653 
   778 
   654     SECURITY_STATUS ss;
   779     SECURITY_STATUS ss;
   655     SecBufferDesc BuffDesc;
   780     SecBufferDesc BuffDesc;
   656     SecBuffer SecBuff[3];
   781     SecBuffer SecBuff[3];
   706            gss_buffer_t input_message_buffer,
   831            gss_buffer_t input_message_buffer,
   707            gss_buffer_t output_message_buffer,
   832            gss_buffer_t output_message_buffer,
   708            int *conf_state,
   833            int *conf_state,
   709            gss_qop_t *qop_state)
   834            gss_qop_t *qop_state)
   710 {
   835 {
       
   836     PP(">>>> Calling gss_unwrap...");
   711     Context* pc = (Context*) context_handle;
   837     Context* pc = (Context*) context_handle;
   712 
   838 
   713     SECURITY_STATUS ss;
   839     SECURITY_STATUS ss;
   714     SecBufferDesc BuffDesc;
   840     SecBufferDesc BuffDesc;
   715     SecBuffer SecBuff[2];
   841     SecBuffer SecBuff[2];
   743 
   869 
   744 __declspec(dllexport) OM_uint32
   870 __declspec(dllexport) OM_uint32
   745 gss_indicate_mechs(OM_uint32 *minor_status,
   871 gss_indicate_mechs(OM_uint32 *minor_status,
   746                    gss_OID_set *mech_set)
   872                    gss_OID_set *mech_set)
   747 {
   873 {
       
   874     PP(">>>> Calling gss_indicate_mechs...");
   748     gss_OID_set_desc *copy;
   875     gss_OID_set_desc *copy;
   749     OM_uint32 minor = 0;
   876     OM_uint32 minor = 0;
   750     OM_uint32 major = GSS_S_COMPLETE;
   877     OM_uint32 major = GSS_S_COMPLETE;
   751     int n = 0;
   878     int n = 0;
   752     int i = 0;
   879     int i = 0;
   753     BOOLEAN hasSpnego = false, hasKerberos = false;
   880     BOOLEAN hasSpnego = false, hasKerberos = false;
   754 
   881 
   755     ULONG ccPackages;
   882     ULONG ccPackages;
   756     PSecPkgInfo packages;
   883     PSecPkgInfo packages;
   757     EnumerateSecurityPackages(&ccPackages, &packages);
   884     EnumerateSecurityPackages(&ccPackages, &packages);
   758     PP("EnumerateSecurityPackages returns %ld\n", ccPackages);
   885     PP("EnumerateSecurityPackages returns %ld", ccPackages);
   759     // TODO: only return Kerberos, so no need to check input later
   886 
   760     PSecPkgInfo pkgInfo;
   887     PSecPkgInfo pkgInfo;
   761     SECURITY_STATUS ss = QuerySecurityPackageInfo(L"Negotiate", &pkgInfo);
   888     SECURITY_STATUS ss = QuerySecurityPackageInfo(L"Negotiate", &pkgInfo);
   762     if (ss == SEC_E_OK) {
   889     if (ss == SEC_E_OK) {
   763         // n++;
   890         n++;
   764         // hasSpnego = true;
   891         hasSpnego = true;
   765     }
   892     }
   766     ss = QuerySecurityPackageInfo(L"Kerberos", &pkgInfo);
   893     ss = QuerySecurityPackageInfo(L"Kerberos", &pkgInfo);
   767     if (ss == SEC_E_OK) {
   894     if (ss == SEC_E_OK) {
   768         n++;
   895         n++;
   769         hasKerberos = true;
   896         hasKerberos = true;
   789         out->length = sizeof(KRB5_OID);
   916         out->length = sizeof(KRB5_OID);
   790         i++;
   917         i++;
   791     }    
   918     }    
   792     if (hasSpnego) {
   919     if (hasSpnego) {
   793         gss_OID_desc *out = &copy->elements[i];
   920         gss_OID_desc *out = &copy->elements[i];
   794         char in[6] = { 0x2B, 0x06, 0x01, 0x05, 0x05, 0x02 };
   921         if ((out->elements = new char[sizeof(SPNEGO_OID)]) == NULL) {
   795         if ((out->elements = new char[sizeof(in)]) == NULL) {
       
   796             major = GSS_S_FAILURE;
   922             major = GSS_S_FAILURE;
   797             goto done;
   923             goto done;
   798         }
   924         }
   799         (void) memcpy(out->elements, in, sizeof(in));
   925         (void) memcpy(out->elements, SPNEGO_OID, sizeof(SPNEGO_OID));
   800         out->length = sizeof(in);
   926         out->length = sizeof(SPNEGO_OID);
   801         i++;
   927         i++;
   802     }    
   928     }    
   803     copy->count = i;
   929     copy->count = i;
   804 
   930 
   805     *mech_set = copy;
   931     *mech_set = copy;
   814 __declspec(dllexport) OM_uint32
   940 __declspec(dllexport) OM_uint32
   815 gss_inquire_names_for_mech(OM_uint32 *minor_status,
   941 gss_inquire_names_for_mech(OM_uint32 *minor_status,
   816                            const gss_OID mechanism,
   942                            const gss_OID mechanism,
   817                            gss_OID_set *name_types)
   943                            gss_OID_set *name_types)
   818 {
   944 {
       
   945     PP(">>>> Calling UNIMPLEMENTED gss_inquire_names_for_mech...");
   819     return GSS_S_FAILURE;
   946     return GSS_S_FAILURE;
   820 }
   947 }
   821 
   948 
   822 __declspec(dllexport) OM_uint32
   949 __declspec(dllexport) OM_uint32
   823 gss_add_oid_set_member(OM_uint32 *minor_status,
   950 gss_add_oid_set_member(OM_uint32 *minor_status,
   824                        gss_OID member_oid,
   951                        gss_OID member_oid,
   825                        gss_OID_set *oid_set)
   952                        gss_OID_set *oid_set)
   826 {
   953 {
   827     return GSS_S_FAILURE;
   954     PP(">>>> Calling gss_add_oid_set_member...");
       
   955     if (member_oid == NULL || member_oid->length == 0
       
   956             || member_oid->elements == NULL) {
       
   957         return GSS_S_CALL_INACCESSIBLE_READ;
       
   958     }
       
   959 
       
   960     if (oid_set == NULL) {
       
   961         return GSS_S_CALL_INACCESSIBLE_WRITE;
       
   962     }
       
   963 
       
   964     int count = (int)(*oid_set)->count;
       
   965     for (int i = 0; i < count; i++) {
       
   966         if ((*oid_set)->elements[i].length == member_oid->length
       
   967                 && !memcmp((*oid_set)->elements[i].elements, member_oid->elements, member_oid->length)) {
       
   968             // already there
       
   969             return GSS_S_COMPLETE;
       
   970         }
       
   971     }
       
   972     gss_OID existing = (*oid_set)->elements;
       
   973     gss_OID newcopy = new gss_OID_desc[count + 1];
       
   974     if (newcopy == NULL) {
       
   975         return GSS_S_FAILURE;
       
   976     }
       
   977     if (existing) {
       
   978         memcpy(newcopy, existing, count * sizeof(gss_OID_desc));
       
   979     }
       
   980     newcopy[count].length = member_oid->length;
       
   981     newcopy[count].elements = new char[member_oid->length];
       
   982     if (newcopy[count].elements == NULL) {
       
   983         delete[] newcopy;
       
   984         return GSS_S_FAILURE;
       
   985     }
       
   986     memcpy(newcopy[count].elements, member_oid->elements, member_oid->length);
       
   987     (*oid_set)->elements = newcopy;
       
   988     (*oid_set)->count++;
       
   989     if (existing) {
       
   990         delete[] existing;
       
   991     }
       
   992 
       
   993     return GSS_S_COMPLETE;
   828 }
   994 }
   829 
   995 
   830 __declspec(dllexport) OM_uint32
   996 __declspec(dllexport) OM_uint32
   831 gss_display_status(OM_uint32 *minor_status,
   997 gss_display_status(OM_uint32 *minor_status,
   832                    OM_uint32 status_value,
   998                    OM_uint32 status_value,
   833                    int status_type,
   999                    int status_type,
   834                    gss_OID mech_type,
  1000                    gss_OID mech_type,
   835                    OM_uint32 *message_context,
  1001                    OM_uint32 *message_context,
   836                    gss_buffer_t status_string)
  1002                    gss_buffer_t status_string)
   837 {
  1003 {
   838     return GSS_S_FAILURE;
  1004     PP(">>>> Calling UNIMPLEMENTED gss_display_status...");
       
  1005     status_string->value = new char[8];
       
  1006     memcpy(status_string->value, "Nothing", 8);
       
  1007     status_string->length = 7;
       
  1008     return GSS_S_COMPLETE;
   839 }
  1009 }
   840 
  1010 
   841 __declspec(dllexport) OM_uint32
  1011 __declspec(dllexport) OM_uint32
   842 gss_create_empty_oid_set(OM_uint32 *minor_status,
  1012 gss_create_empty_oid_set(OM_uint32 *minor_status,
   843                          gss_OID_set *oid_set)
  1013                          gss_OID_set *oid_set)
   844 {
  1014 {
       
  1015     PP(">>>> Calling gss_create_empty_oid_set...");
       
  1016     if (oid_set == NULL) {
       
  1017         return GSS_S_CALL_INACCESSIBLE_WRITE;
       
  1018     }
       
  1019 
       
  1020     if (*oid_set = new gss_OID_set_desc) {
       
  1021         memset(*oid_set, 0, sizeof(gss_OID_set_desc));
       
  1022         return GSS_S_COMPLETE;
       
  1023     }
   845     return GSS_S_FAILURE;
  1024     return GSS_S_FAILURE;
   846 }
  1025 }
   847 
  1026 
   848 __declspec(dllexport) OM_uint32
  1027 __declspec(dllexport) OM_uint32
   849 gss_release_oid_set(OM_uint32 *minor_status,
  1028 gss_release_oid_set(OM_uint32 *minor_status,
   850                     gss_OID_set *set)
  1029                     gss_OID_set *set)
   851 {
  1030 {
   852     return GSS_S_FAILURE;
  1031     PP(">>>> Calling gss_release_oid_set...");
       
  1032     if (set == NULL || *set == GSS_C_NO_OID_SET) {
       
  1033         return GSS_S_COMPLETE;
       
  1034     }
       
  1035     for (int i = 0; i < (*set)->count; i++) {
       
  1036         delete[] (*set)->elements[i].elements;
       
  1037     }
       
  1038     delete[] (*set)->elements;
       
  1039     delete *set;
       
  1040     *set = GSS_C_NO_OID_SET;
       
  1041     return GSS_S_COMPLETE;
   853 }
  1042 }
   854 
  1043 
   855 __declspec(dllexport) OM_uint32
  1044 __declspec(dllexport) OM_uint32
   856 gss_release_buffer(OM_uint32 *minor_status,
  1045 gss_release_buffer(OM_uint32 *minor_status,
   857                    gss_buffer_t buffer)
  1046                    gss_buffer_t buffer)
   858 {
  1047 {
   859     return GSS_S_FAILURE;
  1048     PP(">>>> Calling gss_release_buffer...");
       
  1049     if (buffer == NULL) {
       
  1050         return GSS_S_COMPLETE;
       
  1051     }
       
  1052     if (buffer->value) {
       
  1053         delete[] buffer->value;
       
  1054         buffer->value = NULL;
       
  1055         buffer->length = 0;
       
  1056     }
       
  1057     return GSS_S_COMPLETE;
   860 }
  1058 }
   861 
  1059 
   862 /* End implemented section */
  1060 /* End implemented section */
   863 
  1061 
   864 #ifdef __cplusplus
  1062 #ifdef __cplusplus