summaryrefslogtreecommitdiffstats
path: root/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'proxy')
-rw-r--r--proxy/src/client/gpm_init_sec_context.c21
-rw-r--r--proxy/src/gp_export.c33
-rw-r--r--proxy/src/gp_export.h3
-rw-r--r--proxy/src/gp_rpc_accept_sec_context.c20
-rw-r--r--proxy/src/gp_rpc_get_mic.c2
-rw-r--r--proxy/src/gp_rpc_init_sec_context.c16
-rw-r--r--proxy/src/gp_rpc_unwrap.c2
-rw-r--r--proxy/src/gp_rpc_verify_mic.c2
-rw-r--r--proxy/src/gp_rpc_wrap.c2
9 files changed, 77 insertions, 24 deletions
diff --git a/proxy/src/client/gpm_init_sec_context.c b/proxy/src/client/gpm_init_sec_context.c
index b6ce34f..f6dfe53 100644
--- a/proxy/src/client/gpm_init_sec_context.c
+++ b/proxy/src/client/gpm_init_sec_context.c
@@ -104,13 +104,6 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
}
}
- if (res->status.major_status) {
- gpm_save_status(&res->status);
- ret_maj = res->status.major_status;
- ret_min = res->status.minor_status;
- goto done;
- }
-
if (res->context_handle) {
ctx = res->context_handle;
/* we are stealing the delegated creds on success, so we do not want
@@ -118,12 +111,18 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
res->context_handle = NULL;
}
- ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
- if (ret) {
- gpm_save_internal_status(ret, strerror(ret));
- goto done;
+ if (res->output_token) {
+ ret = gp_conv_gssx_to_buffer_alloc(res->output_token, &outbuf);
+ if (ret) {
+ gpm_save_internal_status(ret, strerror(ret));
+ goto done;
+ }
}
+ ret_maj = res->status.major_status;
+ ret_min = res->status.minor_status;
+ gpm_save_status(&res->status);
+
done:
if (ret != 0) {
ret_min = ret;
diff --git a/proxy/src/gp_export.c b/proxy/src/gp_export.c
index 51dd686..3cd5148 100644
--- a/proxy/src/gp_export.c
+++ b/proxy/src/gp_export.c
@@ -390,6 +390,7 @@ done:
#define LINUX_LUCID_V1 "linux_lucid_v1"
enum exp_ctx_types {
+ EXP_CTX_PARTIAL = -1, /* cannot be specified by client */
EXP_CTX_DEFAULT = 0,
EXP_CTX_LINUX_LUCID_V1 = 1,
};
@@ -418,6 +419,11 @@ int gp_get_exported_context_type(struct gssx_call_ctx *ctx)
return EXP_CTX_DEFAULT;
}
+int gp_get_continue_needed_type(void)
+{
+ return EXP_CTX_PARTIAL;
+}
+
#define KRB5_CTX_FLAG_INITIATOR 0x00000001
#define KRB5_CTX_FLAG_CFX 0x00000002
#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004
@@ -513,7 +519,7 @@ done:
}
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
gss_ctx_id_t *in, gssx_ctx *out)
{
uint32_t ret_maj;
@@ -529,9 +535,6 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
int is_open;
int ret;
-/* TODO: For mechs that need multiple roundtrips to complete */
- /* out->state; */
-
/* we do not need the client to release anything until we handle state */
out->needs_release = false;
@@ -539,6 +542,11 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
&lifetime_rec, &mech_type, &ctx_flags,
&is_locally_initiated, &is_open);
if (ret_maj) {
+ if (type == EXP_CTX_PARTIAL) {
+ /* This may happen on partially established context,
+ * so just go on and put in what we can */
+ goto export;
+ }
goto done;
}
@@ -571,9 +579,26 @@ uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
out->open = true;
}
+export:
/* note: once converted the original context token is not usable anymore,
* so this must be the last call to use it */
switch (type) {
+ case EXP_CTX_PARTIAL:
+ /* this happens only when a init_sec_context call returns a partially
+ * initialized context so we return only what we have, not much */
+ ret = gp_conv_oid_to_gssx(mech, &out->mech);
+ if (ret) {
+ ret_maj = GSS_S_FAILURE;
+ ret_min = ret;
+ goto done;
+ }
+
+ out->locally_initiated = true;
+ out->open = false;
+
+ /* out->state; */
+
+ /* fall through */
case EXP_CTX_DEFAULT:
ret_maj = gss_export_sec_context(&ret_min, in, &export_buffer);
if (ret_maj) {
diff --git a/proxy/src/gp_export.h b/proxy/src/gp_export.h
index 58c0040..03e5d18 100644
--- a/proxy/src/gp_export.h
+++ b/proxy/src/gp_export.h
@@ -37,7 +37,8 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
gssx_cred *cred, gss_cred_id_t *out);
int gp_get_exported_context_type(struct gssx_call_ctx *ctx);
-uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type,
+int gp_get_continue_needed_type(void);
+uint32_t gp_export_ctx_id_to_gssx(uint32_t *min, int type, gss_OID mech,
gss_ctx_id_t *in, gssx_ctx *out);
uint32_t gp_import_gssx_to_ctx_id(uint32_t *min, int type,
gssx_ctx *in, gss_ctx_id_t *out);
diff --git a/proxy/src/gp_rpc_accept_sec_context.c b/proxy/src/gp_rpc_accept_sec_context.c
index 40370aa..efbf07a 100644
--- a/proxy/src/gp_rpc_accept_sec_context.c
+++ b/proxy/src/gp_rpc_accept_sec_context.c
@@ -46,6 +46,8 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
gss_cred_id_t *pdch = NULL;
int exp_ctx_type;
int exp_creds_type;
+ uint32_t acpt_maj;
+ uint32_t acpt_min;
int ret;
asca = &arg->accept_sec_context;
@@ -109,17 +111,25 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
&ret_flags,
NULL,
pdch);
- if (ret_maj) {
+ if (ret_maj != GSS_S_COMPLETE &&
+ ret_maj != GSS_S_CONTINUE_NEEDED) {
goto done;
+ } else {
+ acpt_maj = ret_maj;
+ acpt_min = ret_min;
+ }
+ if (acpt_maj == GSS_S_CONTINUE_NEEDED) {
+ exp_ctx_type = gp_get_continue_needed_type();
}
+
ascr->context_handle = calloc(1, sizeof(gssx_ctx));
if (!ascr->context_handle) {
ret_maj = GSS_S_FAILURE;
ret_min = ENOMEM;
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, oid,
&ctx, ascr->context_handle);
if (ret_maj) {
goto done;
@@ -138,7 +148,7 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
goto done;
}
- if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred) {
+ if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred && dch) {
ascr->delegated_cred_handle = calloc(1, sizeof(gssx_cred));
if (!ascr->delegated_cred_handle) {
ret_maj = GSS_S_FAILURE;
@@ -159,6 +169,10 @@ int gp_accept_sec_context(struct gp_call_ctx *gpcall,
&ascr->options.options_val);
done:
+ if (ret_maj == GSS_S_COMPLETE) {
+ ret_maj = acpt_maj;
+ ret_min = acpt_min;
+ }
ret = gp_conv_status_to_gssx(&asca->call_ctx,
ret_maj, ret_min, oid,
&ascr->status);
diff --git a/proxy/src/gp_rpc_get_mic.c b/proxy/src/gp_rpc_get_mic.c
index ca60fe4..2db7d3f 100644
--- a/proxy/src/gp_rpc_get_mic.c
+++ b/proxy/src/gp_rpc_get_mic.c
@@ -73,7 +73,7 @@ int gp_get_mic(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
gmr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
index 944389c..2781238 100644
--- a/proxy/src/gp_rpc_init_sec_context.c
+++ b/proxy/src/gp_rpc_init_sec_context.c
@@ -45,6 +45,8 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
gss_buffer_desc obuf = GSS_C_EMPTY_BUFFER;
uint32_t ret_maj;
uint32_t ret_min;
+ uint32_t init_maj;
+ uint32_t init_min;
int exp_ctx_type;
int ret;
@@ -121,6 +123,12 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
if (ret_maj != GSS_S_COMPLETE &&
ret_maj != GSS_S_CONTINUE_NEEDED) {
goto done;
+ } else {
+ init_maj = ret_maj;
+ init_min = ret_min;
+ }
+ if (init_maj == GSS_S_CONTINUE_NEEDED) {
+ exp_ctx_type = gp_get_continue_needed_type();
}
iscr->context_handle = calloc(1, sizeof(gssx_ctx));
@@ -129,7 +137,7 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
ret_min = ENOMEM;
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, mech_type,
&ctx, iscr->context_handle);
if (ret_maj) {
goto done;
@@ -150,7 +158,13 @@ int gp_init_sec_context(struct gp_call_ctx *gpcall,
}
}
+ ret_maj = GSS_S_COMPLETE;
+
done:
+ if (ret_maj == GSS_S_COMPLETE) {
+ ret_maj = init_maj;
+ ret_min = init_min;
+ }
ret = gp_conv_status_to_gssx(&isca->call_ctx,
ret_maj, ret_min, mech_type,
&iscr->status);
diff --git a/proxy/src/gp_rpc_unwrap.c b/proxy/src/gp_rpc_unwrap.c
index a20b8ea..faffa82 100644
--- a/proxy/src/gp_rpc_unwrap.c
+++ b/proxy/src/gp_rpc_unwrap.c
@@ -85,7 +85,7 @@ int gp_unwrap(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
uwr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_verify_mic.c b/proxy/src/gp_rpc_verify_mic.c
index 68369a0..a2d3f7e 100644
--- a/proxy/src/gp_rpc_verify_mic.c
+++ b/proxy/src/gp_rpc_verify_mic.c
@@ -76,7 +76,7 @@ int gp_verify_mic(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle,
vmr->context_handle);
if (ret_maj) {
diff --git a/proxy/src/gp_rpc_wrap.c b/proxy/src/gp_rpc_wrap.c
index d17c292..c2da7ba 100644
--- a/proxy/src/gp_rpc_wrap.c
+++ b/proxy/src/gp_rpc_wrap.c
@@ -85,7 +85,7 @@ int gp_wrap(struct gp_call_ctx *gpcall,
goto done;
}
- ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type,
+ ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, GSS_C_NO_OID,
&context_handle, wr->context_handle);
if (ret_maj) {
goto done;