Don't include @ symbol in realmless names, to conform with draft-ietf-abfab-gss-eap
authorLuke Howard <lukeh@padl.com>
Fri, 18 Mar 2011 05:36:26 +0000 (16:36 +1100)
committerLuke Howard <lukeh@padl.com>
Fri, 18 Mar 2011 06:13:43 +0000 (17:13 +1100)
init_sec_context.c
util_name.c

index a731833..6694756 100644 (file)
@@ -199,13 +199,17 @@ peerConfigInit(OM_uint32 *minor,
                gss_cred_id_t cred,
                gss_ctx_id_t ctx)
 {
+    OM_uint32 major;
     krb5_context krbContext;
     struct eap_peer_config *eapPeerConfig = &ctx->initiatorCtx.eapPeerConfig;
-    krb5_error_code code;
-    char *identity, *anonymousIdentity;
+    gss_buffer_desc identity = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc anonymousIdentity = GSS_C_EMPTY_BUFFER;
+    ssize_t i;
 
     eapPeerConfig->identity = NULL;
     eapPeerConfig->identity_len = 0;
+    eapPeerConfig->anonymous_identity = NULL;
+    eapPeerConfig->anonymous_identity_len = 0;
     eapPeerConfig->password = NULL;
     eapPeerConfig->password_len = 0;
 
@@ -225,20 +229,29 @@ peerConfigInit(OM_uint32 *minor,
         return GSS_S_BAD_NAME;
     }
 
-    code = krb5_unparse_name(krbContext, cred->name->krbPrincipal, &identity);
-    if (code != 0) {
-        *minor = code;
-        return GSS_S_FAILURE;
+    major = gssEapDisplayName(minor, cred->name, &identity, NULL);
+    if (GSS_ERROR(major))
+        return major;
+
+    assert(identity.length > 0);
+
+    for (i = identity.length - 1; i >= 0; i--) {
+        unsigned char *p = (unsigned char *)identity.value + i;
+
+        if (*p == '@') {
+            anonymousIdentity.length = identity.length - i;
+            anonymousIdentity.value = p;
+            break;
+        }
     }
 
-    anonymousIdentity = strchr(identity, '@');
-    if (anonymousIdentity == NULL)
-        anonymousIdentity = "";
+    if (anonymousIdentity.length == 0)
+        anonymousIdentity.value = "";
 
-    eapPeerConfig->identity = (unsigned char *)identity;
-    eapPeerConfig->identity_len = strlen(identity);
-    eapPeerConfig->anonymous_identity = (unsigned char *)anonymousIdentity;
-    eapPeerConfig->anonymous_identity_len = strlen(anonymousIdentity);
+    eapPeerConfig->identity = (unsigned char *)identity.value;
+    eapPeerConfig->identity_len = identity.length;
+    eapPeerConfig->anonymous_identity = (unsigned char *)anonymousIdentity.value;
+    eapPeerConfig->anonymous_identity_len = anonymousIdentity.length;
     eapPeerConfig->password = (unsigned char *)cred->password.value;
     eapPeerConfig->password_len = cred->password.length;
 
@@ -250,12 +263,9 @@ static OM_uint32
 peerConfigFree(OM_uint32 *minor,
                gss_ctx_id_t ctx)
 {
-    krb5_context krbContext;
     struct eap_peer_config *eapPeerConfig = &ctx->initiatorCtx.eapPeerConfig;
 
-    GSSEAP_KRB_INIT(&krbContext);
-
-    krb5_free_unparsed_name(krbContext, (char *)eapPeerConfig->identity);
+    GSSEAP_FREE(eapPeerConfig->identity);
 
     *minor = 0;
     return GSS_S_COMPLETE;
index e52bb4e..c11c5bf 100644 (file)
@@ -689,6 +689,7 @@ gssEapDisplayName(OM_uint32 *minor,
     krb5_context krbContext;
     char *krbName;
     gss_OID name_type;
+    int flags = 0;
 
     GSSEAP_KRB_INIT(&krbContext);
 
@@ -700,7 +701,20 @@ gssEapDisplayName(OM_uint32 *minor,
         return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_BAD_NAME;
     }
 
-    *minor = krb5_unparse_name(krbContext, name->krbPrincipal, &krbName);
+    /*
+     * According to draft-ietf-abfab-gss-eap-01, when the realm is
+     * absent the trailing '@' is not included.
+     */
+#ifdef HAVE_HEIMDAL_VERSION
+    if (KRB_PRINC_REALM(name->krbPrincipal) == NULL ||
+        KRB_PRINC_REALM(name->krBPrincipal)[0] == '\0')
+#else
+    if (KRB_PRINC_REALM(name->krbPrincipal)->length == 0)
+#endif
+        flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM;
+
+    *minor = krb5_unparse_name_flags(krbContext, name->krbPrincipal,
+                                     flags, &krbName);
     if (*minor != 0) {
         return GSS_S_FAILURE;
     }