gss: allow source/target to be null on export/import
authorLuke Howard <lukeh@padl.com>
Tue, 14 Apr 2020 02:34:44 +0000 (12:34 +1000)
committerLuke Howard <lukeh@padl.com>
Thu, 16 Apr 2020 05:20:10 +0000 (15:20 +1000)
Allow the source and target names to be NULL when exporting or importing a
security context for the krb5 mechanism. This will be used in the future to
support skeletal contexts that only provide RFC4121 message protection
services.

lib/gssapi/krb5/export_sec_context.c
lib/gssapi/krb5/gsskrb5_locl.h
lib/gssapi/krb5/import_sec_context.c

index cba9f22f657d58ca0d8bb43fcfda44b4e2c373b0..63ffe4963feee8b837928cc2f5c79b01c77052b0 100644 (file)
@@ -82,6 +82,10 @@ _gsskrb5_export_sec_context(
        flags |= SC_LOCAL_SUBKEY;
     if (ac->remote_subkey)
        flags |= SC_REMOTE_SUBKEY;
+    if (ctx->source)
+       flags |= SC_SOURCE_NAME;
+    if (ctx->target)
+       flags |= SC_TARGET_NAME;
 
     kret = krb5_store_int32 (sp, flags);
     if (kret) {
@@ -164,34 +168,38 @@ _gsskrb5_export_sec_context(
     }
 
     /* names */
+    if (ctx->source) {
+       ret = _gsskrb5_export_name (minor_status,
+                                   (gss_name_t)ctx->source, &buffer);
+       if (ret)
+           goto failure;
+       data.data   = buffer.value;
+       data.length = buffer.length;
+       kret = krb5_store_data (sp, data);
+       _gsskrb5_release_buffer (&minor, &buffer);
 
-    ret = _gsskrb5_export_name (minor_status,
-                               (gss_name_t)ctx->source, &buffer);
-    if (ret)
-       goto failure;
-    data.data   = buffer.value;
-    data.length = buffer.length;
-    kret = krb5_store_data (sp, data);
-    _gsskrb5_release_buffer (&minor, &buffer);
-    if (kret) {
-       *minor_status = kret;
-       goto failure;
+       ret = GSS_S_FAILURE;
+       if (kret) {
+           *minor_status = kret;
+           goto failure;
+       }
     }
 
-    ret = _gsskrb5_export_name (minor_status,
-                               (gss_name_t)ctx->target, &buffer);
-    if (ret)
-       goto failure;
-    data.data   = buffer.value;
-    data.length = buffer.length;
-
-    ret = GSS_S_FAILURE;
+    if (ctx->target) {
+       ret = _gsskrb5_export_name (minor_status,
+                                   (gss_name_t)ctx->target, &buffer);
+       if (ret)
+           goto failure;
+       data.data   = buffer.value;
+       data.length = buffer.length;
+       kret = krb5_store_data (sp, data);
+       _gsskrb5_release_buffer (&minor, &buffer);
 
-    kret = krb5_store_data (sp, data);
-    _gsskrb5_release_buffer (&minor, &buffer);
-    if (kret) {
-       *minor_status = kret;
-       goto failure;
+       ret = GSS_S_FAILURE;
+       if (kret) {
+           *minor_status = kret;
+           goto failure;
+       }
     }
 
     kret = krb5_store_int32 (sp, ctx->flags);
index e323881fa37978c72e501f920b8a9aa7b0ede0b6..c427c7ef9f2ed2648b07dae7a3be97fdc89d8bfa 100644 (file)
@@ -134,5 +134,7 @@ extern HEIMDAL_MUTEX gssapi_keytab_mutex;
 #define SC_KEYBLOCK      0x04
 #define SC_LOCAL_SUBKEY          0x08
 #define SC_REMOTE_SUBKEY  0x10
+#define SC_SOURCE_NAME    0x20
+#define SC_TARGET_NAME    0x40
 
 #endif
index e34e07115a5f531b7deb1eb965d2fd0526c31e18..545b15fed4abcf3b49c0a5a455eca78e036f3502 100644 (file)
@@ -149,42 +149,45 @@ _gsskrb5_import_sec_context (
     ac->cksumtype = tmp;
 
     /* names */
+    if (flags & SC_SOURCE_NAME) {
+       if (krb5_ret_data (sp, &data))
+           goto failure;
+       buffer.value  = data.data;
+       buffer.length = data.length;
 
-    if (krb5_ret_data (sp, &data))
-       goto failure;
-    buffer.value  = data.data;
-    buffer.length = data.length;
-
-    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
-                               &name);
-    if (ret) {
-       ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+       ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
                                    &name);
        if (ret) {
-           krb5_data_free (&data);
-           goto failure;
+           ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+                                       &name);
+           if (ret) {
+               krb5_data_free (&data);
+               goto failure;
+           }
        }
+       ctx->source = (krb5_principal)name;
+       krb5_data_free (&data);
     }
-    ctx->source = (krb5_principal)name;
-    krb5_data_free (&data);
 
-    if (krb5_ret_data (sp, &data) != 0)
-       goto failure;
-    buffer.value  = data.data;
-    buffer.length = data.length;
+    if (flags & SC_TARGET_NAME) {
+       if (krb5_ret_data (sp, &data) != 0)
+           goto failure;
+       buffer.value  = data.data;
+       buffer.length = data.length;
 
-    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
-                               &name);
-    if (ret) {
-       ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+       ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
                                    &name);
        if (ret) {
-           krb5_data_free (&data);
-           goto failure;
+           ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
+                                       &name);
+           if (ret) {
+               krb5_data_free (&data);
+               goto failure;
+           }
        }
+       ctx->target = (krb5_principal)name;
+       krb5_data_free (&data);
     }
-    ctx->target = (krb5_principal)name;
-    krb5_data_free (&data);
 
     if (krb5_ret_int32 (sp, &tmp))
        goto failure;