Blame SOURCES/gssproxy-0.3.0-continuations.patch

4c520e
From 556ea844a5783f9876ee748e1c686bb268f54e8a Mon Sep 17 00:00:00 2001
4c520e
From: Simo Sorce <simo@redhat.com>
4c520e
Date: Fri, 15 Nov 2013 10:33:52 -0500
4c520e
Subject: [PATCH] Fix continuations in context establishment calls
4c520e
MIME-Version: 1.0
4c520e
Content-Type: text/plain; charset=UTF-8
4c520e
Content-Transfer-Encoding: 8bit
4c520e
4c520e
Properly support continuations, including returning the rigth error code
4c520e
and exporting partial contexts.
4c520e
4c520e
Fixes multistep authentications in particular for the initialization case
4c520e
which always uses continuations.
4c520e
4c520e
Resolves: https://fedorahosted.org/gss-proxy/ticket/108
4c520e
4c520e
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
4c520e
---
4c520e
 proxy/src/client/gpm_init_sec_context.c | 21 ++++++++++-----------
4c520e
 proxy/src/gp_export.c                   | 33 +++++++++++++++++++++++++++++----
4c520e
 proxy/src/gp_export.h                   |  3 ++-
4c520e
 proxy/src/gp_rpc_accept_sec_context.c   | 20 +++++++++++++++++---
4c520e
 proxy/src/gp_rpc_get_mic.c              |  2 +-
4c520e
 proxy/src/gp_rpc_init_sec_context.c     | 16 +++++++++++++++-
4c520e
 proxy/src/gp_rpc_unwrap.c               |  2 +-
4c520e
 proxy/src/gp_rpc_verify_mic.c           |  2 +-
4c520e
 proxy/src/gp_rpc_wrap.c                 |  2 +-
4c520e
 9 files changed, 77 insertions(+), 24 deletions(-)
4c520e
4c520e
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c
4c520e
index b6ce34f..f6dfe53 100644
4c520e
--- a/proxy/src/client/gpm_init_sec_context.c
4c520e
+++ b/proxy/src/client/gpm_init_sec_context.c
4c520e
@@ -104,13 +104,6 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
4c520e
         }
4c520e
     }
4c520e
 
4c520e
-    if (res->status.major_status) {
4c520e
-        gpm_save_status(&res->status);
4c520e
-        ret_maj = res->status.major_status;
4c520e
-        ret_min = res->status.minor_status;
4c520e
-        goto done;
4c520e
-    }
4c520e
-
4c520e
     if (res->context_handle) {
4c520e
         ctx = res->context_handle;
4c520e
         /* we are stealing the delegated creds on success, so we do not want
4c520e
@@ -118,12 +111,18 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
4c520e
         res->context_handle = NULL;
4c520e
     }
4c520e
 
4c520e
-    ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
4c520e
-    if (ret) {
4c520e
-        gpm_save_internal_status(ret, strerror(ret));
4c520e
-        goto done;
4c520e
+    if (res->output_token) {
4c520e
+        ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
4c520e
+        if (ret) {
4c520e
+            gpm_save_internal_status(ret, strerror(ret));
4c520e
+            goto done;
4c520e
+        }
4c520e
     }
4c520e
 
4c520e
+    ret_maj = res->status.major_status;
4c520e
+    ret_min = res->status.minor_status;
4c520e
+    gpm_save_status(&res->status);
4c520e
+
4c520e
 done:
4c520e
     if (ret != 0) {
4c520e
         ret_min = ret;
4c520e
diff --git a/proxy/src/gp_export.c b/proxy/src/gp_export.c
4c520e
index 51dd686..3cd5148 100644
4c520e
--- a/proxy/src/gp_export.c
4c520e
+++ b/proxy/src/gp_export.c
4c520e
@@ -390,6 +390,7 @@ done:
4c520e
 #define LINUX_LUCID_V1      "linux_lucid_v1"
4c520e
 
4c520e
 enum exp_ctx_types {
4c520e
+    EXP_CTX_PARTIAL = -1, /* cannot be specified by client */
4c520e
     EXP_CTX_DEFAULT = 0,
4c520e
     EXP_CTX_LINUX_LUCID_V1 = 1,
4c520e
 };
4c520e
@@ -418,6 +419,11 @@ int gp_get_exported_context_type(struct gssx_call_ctx *ctx)
4c520e
     return EXP_CTX_DEFAULT;
4c520e
 }
4c520e
 
4c520e
+int gp_get_continue_needed_type(void)
4c520e
+{
4c520e
+    return EXP_CTX_PARTIAL;
4c520e
+}
4c520e
+
4c520e
 #define KRB5_CTX_FLAG_INITIATOR         0x00000001
4c520e
 #define KRB5_CTX_FLAG_CFX               0x00000002
4c520e
 #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY   0x00000004
4c520e
@@ -513,7 +519,7 @@ done:
4c520e
 }
4c520e
 
4c520e
 
4c520e
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
4c520e
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
4c520e
                                   gss_ctx_id_t *in, gssx_ctx *out)
4c520e
 {
4c520e
     uint32_t ret_maj;
4c520e
@@ -529,9 +535,6 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
4c520e
     int is_open;
4c520e
     int ret;
4c520e
 
4c520e
-/* TODO: For mechs that need multiple roundtrips to complete */
4c520e
-    /* out->state; */
4c520e
-
4c520e
     /* we do not need the client to release anything until we handle state */
4c520e
     out->needs_release = false;
4c520e
 
4c520e
@@ -539,6 +542,11 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
4c520e
                                   &lifetime_rec, &mech_type, &ctx_flags,
4c520e
                                   &is_locally_initiated, &is_open);
4c520e
     if (ret_maj) {
4c520e
+        if (type == EXP_CTX_PARTIAL) {
4c520e
+            /* This may happen on partially established context,
4c520e
+             * so just go on and put in what we can */
4c520e
+            goto export;
4c520e
+        }
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
@@ -571,9 +579,26 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
4c520e
         out->open = true;
4c520e
     }
4c520e
 
4c520e
+export:
4c520e
     /* note: once converted the original context token is not usable anymore,
4c520e
      * so this must be the last call to use it */
4c520e
     switch (type) {
4c520e
+    case EXP_CTX_PARTIAL:
4c520e
+        /* this happens only when a init_sec_context call returns a partially
4c520e
+         * initialized context so we return only what we have, not much */
4c520e
+        ret = gp_conv_oid_to_gssx(mech, &out->mech);
4c520e
+        if (ret) {
4c520e
+            ret_maj = GSS_S_FAILURE;
4c520e
+            ret_min = ret;
4c520e
+            goto done;
4c520e
+        }
4c520e
+
4c520e
+        out->locally_initiated = true;
4c520e
+        out->open = false;
4c520e
+
4c520e
+        /* out->state; */
4c520e
+
4c520e
+        /* fall through */
4c520e
     case EXP_CTX_DEFAULT:
4c520e
         ret_maj = gss_export_sec_context(&ret_min, in, &export_buffer);
4c520e
         if (ret_maj) {
4c520e
diff --git a/proxy/src/gp_export.h b/proxy/src/gp_export.h
4c520e
index 58c0040..03e5d18 100644
4c520e
--- a/proxy/src/gp_export.h
4c520e
+++ b/proxy/src/gp_export.h
4c520e
@@ -37,7 +37,8 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
4c520e
                              gssx_cred *cred, gss_cred_id_t *out);
4c520e
 
4c520e
 int gp_get_exported_context_type(struct gssx_call_ctx *ctx);
4c520e
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
4c520e
+int gp_get_continue_needed_type(void);
4c520e
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
4c520e
                                   gss_ctx_id_t *in, gssx_ctx *out);
4c520e
 uint32_t gp_import_gssx_to_ctx_id(uint32_t *min, int type,
4c520e
                                   gssx_ctx *in, gss_ctx_id_t *out);
4c520e
diff --git a/proxy/src/gp_rpc_accept_sec_context.c b/proxy/src/gp_rpc_accept_sec_context.c
4c520e
index 40370aa..efbf07a 100644
4c520e
--- a/proxy/src/gp_rpc_accept_sec_context.c
4c520e
+++ b/proxy/src/gp_rpc_accept_sec_context.c
4c520e
@@ -46,6 +46,8 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
4c520e
     gss_cred_id_t *pdch = NULL;
4c520e
     int exp_ctx_type;
4c520e
     int exp_creds_type;
4c520e
+    uint32_t acpt_maj;
4c520e
+    uint32_t acpt_min;
4c520e
     int ret;
4c520e
 
4c520e
     asca = &arg->accept_sec_context;
4c520e
@@ -109,17 +111,25 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
4c520e
                                      &ret_flags,
4c520e
                                      NULL,
4c520e
                                      pdch);
4c520e
-    if (ret_maj) {
4c520e
+    if (ret_maj != GSS_S_COMPLETE &&
4c520e
+        ret_maj != GSS_S_CONTINUE_NEEDED) {
4c520e
         goto done;
4c520e
+    } else {
4c520e
+        acpt_maj = ret_maj;
4c520e
+        acpt_min = ret_min;
4c520e
+    }
4c520e
+    if (acpt_maj == GSS_S_CONTINUE_NEEDED) {
4c520e
+        exp_ctx_type = gp_get_continue_needed_type();
4c520e
     }
4c520e
 
4c520e
+
4c520e
     ascr->context_handle = calloc(1, sizeof(gssx_ctx));
4c520e
     if (!ascr->context_handle) {
4c520e
         ret_maj = GSS_S_FAILURE;
4c520e
         ret_min = ENOMEM;
4c520e
         goto done;
4c520e
     }
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, oid,
4c520e
                                        &ctx, ascr->context_handle);
4c520e
     if (ret_maj) {
4c520e
         goto done;
4c520e
@@ -138,7 +148,7 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
-    if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred) {
4c520e
+    if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred && dch) {
4c520e
         ascr->delegated_cred_handle = calloc(1, sizeof(gssx_cred));
4c520e
         if (!ascr->delegated_cred_handle) {
4c520e
             ret_maj = GSS_S_FAILURE;
4c520e
@@ -159,6 +169,10 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
4c520e
                                               &ascr->options.options_val);
4c520e
 
4c520e
 done:
4c520e
+    if (ret_maj == GSS_S_COMPLETE) {
4c520e
+        ret_maj = acpt_maj;
4c520e
+        ret_min = acpt_min;
4c520e
+    }
4c520e
     ret = gp_conv_status_to_gssx(&asca->call_ctx,
4c520e
                                  ret_maj, ret_min, oid,
4c520e
                                  &ascr->status);
4c520e
diff --git a/proxy/src/gp_rpc_get_mic.c b/proxy/src/gp_rpc_get_mic.c
4c520e
index ca60fe4..2db7d3f 100644
4c520e
--- a/proxy/src/gp_rpc_get_mic.c
4c520e
+++ b/proxy/src/gp_rpc_get_mic.c
4c520e
@@ -73,7 +73,7 @@ int gp_get_mic(struct gp_call_ctx *gpcall,
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
4c520e
                                        &context_handle,
4c520e
                                        gmr->context_handle);
4c520e
     if (ret_maj) {
4c520e
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
4c520e
index 944389c..2781238 100644
4c520e
--- a/proxy/src/gp_rpc_init_sec_context.c
4c520e
+++ b/proxy/src/gp_rpc_init_sec_context.c
4c520e
@@ -45,6 +45,8 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
4c520e
     gss_buffer_desc obuf = GSS_C_EMPTY_BUFFER;
4c520e
     uint32_t ret_maj;
4c520e
     uint32_t ret_min;
4c520e
+    uint32_t init_maj;
4c520e
+    uint32_t init_min;
4c520e
     int exp_ctx_type;
4c520e
     int ret;
4c520e
 
4c520e
@@ -121,6 +123,12 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
4c520e
     if (ret_maj != GSS_S_COMPLETE &&
4c520e
         ret_maj != GSS_S_CONTINUE_NEEDED) {
4c520e
         goto done;
4c520e
+    } else {
4c520e
+        init_maj = ret_maj;
4c520e
+        init_min = ret_min;
4c520e
+    }
4c520e
+    if (init_maj == GSS_S_CONTINUE_NEEDED) {
4c520e
+        exp_ctx_type = gp_get_continue_needed_type();
4c520e
     }
4c520e
 
4c520e
     iscr->context_handle = calloc(1, sizeof(gssx_ctx));
4c520e
@@ -129,7 +137,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
4c520e
         ret_min = ENOMEM;
4c520e
         goto done;
4c520e
     }
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, mech_type,
4c520e
                                        &ctx, iscr->context_handle);
4c520e
     if (ret_maj) {
4c520e
         goto done;
4c520e
@@ -150,7 +158,13 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
4c520e
         }
4c520e
     }
4c520e
 
4c520e
+    ret_maj = GSS_S_COMPLETE;
4c520e
+
4c520e
 done:
4c520e
+    if (ret_maj == GSS_S_COMPLETE) {
4c520e
+        ret_maj = init_maj;
4c520e
+        ret_min = init_min;
4c520e
+    }
4c520e
     ret = gp_conv_status_to_gssx(&isca->call_ctx,
4c520e
                                  ret_maj, ret_min, mech_type,
4c520e
                                  &iscr->status);
4c520e
diff --git a/proxy/src/gp_rpc_unwrap.c b/proxy/src/gp_rpc_unwrap.c
4c520e
index a20b8ea..faffa82 100644
4c520e
--- a/proxy/src/gp_rpc_unwrap.c
4c520e
+++ b/proxy/src/gp_rpc_unwrap.c
4c520e
@@ -85,7 +85,7 @@ int gp_unwrap(struct gp_call_ctx *gpcall,
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
4c520e
                                        &context_handle,
4c520e
                                        uwr->context_handle);
4c520e
     if (ret_maj) {
4c520e
diff --git a/proxy/src/gp_rpc_verify_mic.c b/proxy/src/gp_rpc_verify_mic.c
4c520e
index 68369a0..a2d3f7e 100644
4c520e
--- a/proxy/src/gp_rpc_verify_mic.c
4c520e
+++ b/proxy/src/gp_rpc_verify_mic.c
4c520e
@@ -76,7 +76,7 @@ int gp_verify_mic(struct gp_call_ctx *gpcall,
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
4c520e
                                        &context_handle,
4c520e
                                        vmr->context_handle);
4c520e
     if (ret_maj) {
4c520e
diff --git a/proxy/src/gp_rpc_wrap.c b/proxy/src/gp_rpc_wrap.c
4c520e
index d17c292..c2da7ba 100644
4c520e
--- a/proxy/src/gp_rpc_wrap.c
4c520e
+++ b/proxy/src/gp_rpc_wrap.c
4c520e
@@ -85,7 +85,7 @@ int gp_wrap(struct gp_call_ctx *gpcall,
4c520e
         goto done;
4c520e
     }
4c520e
 
4c520e
-    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
4c520e
+    ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
4c520e
                                        &context_handle, wr->context_handle);
4c520e
     if (ret_maj) {
4c520e
         goto done;
4c520e
-- 
4c520e
1.8.3.1
4c520e