Fix continuation processing for not yet fully established contexts.
- resolves: https://fedorahosted.org/gss-proxy/ticket/108
This commit is contained in:
		
							parent
							
								
									349bd3c1c3
								
							
						
					
					
						commit
						e2e2fe48c7
					
				
							
								
								
									
										331
									
								
								gssproxy-0.3.0-continuations.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										331
									
								
								gssproxy-0.3.0-continuations.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,331 @@ | |||||||
|  | From 556ea844a5783f9876ee748e1c686bb268f54e8a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Simo Sorce <simo@redhat.com> | ||||||
|  | Date: Fri, 15 Nov 2013 10:33:52 -0500 | ||||||
|  | Subject: [PATCH] Fix continuations in context establishment calls | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  | 
 | ||||||
|  | Properly support continuations, including returning the rigth error code | ||||||
|  | and exporting partial contexts. | ||||||
|  | 
 | ||||||
|  | Fixes multistep authentications in particular for the initialization case | ||||||
|  | which always uses continuations. | ||||||
|  | 
 | ||||||
|  | Resolves: https://fedorahosted.org/gss-proxy/ticket/108 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Günther Deschner <gdeschner@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  proxy/src/client/gpm_init_sec_context.c | 21 ++++++++++----------- | ||||||
|  |  proxy/src/gp_export.c                   | 33 +++++++++++++++++++++++++++++---- | ||||||
|  |  proxy/src/gp_export.h                   |  3 ++- | ||||||
|  |  proxy/src/gp_rpc_accept_sec_context.c   | 20 +++++++++++++++++--- | ||||||
|  |  proxy/src/gp_rpc_get_mic.c              |  2 +- | ||||||
|  |  proxy/src/gp_rpc_init_sec_context.c     | 16 +++++++++++++++- | ||||||
|  |  proxy/src/gp_rpc_unwrap.c               |  2 +- | ||||||
|  |  proxy/src/gp_rpc_verify_mic.c           |  2 +- | ||||||
|  |  proxy/src/gp_rpc_wrap.c                 |  2 +- | ||||||
|  |  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; | ||||||
|  | -- 
 | ||||||
|  | 1.8.3.1 | ||||||
|  | 
 | ||||||
| @ -10,6 +10,7 @@ Source0:	http://fedorahosted.org/released/gss-proxy/%{name}-%{version}.tar.gz | |||||||
| BuildRoot:	%(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) | BuildRoot:	%(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) | ||||||
| Patch0:		gssproxy-0.3.0-gss_init_sec_context.patch | Patch0:		gssproxy-0.3.0-gss_init_sec_context.patch | ||||||
| Patch1:		gssproxy-0.3.0-gss_inquire_cred_by_mech.patch | Patch1:		gssproxy-0.3.0-gss_inquire_cred_by_mech.patch | ||||||
|  | Patch2:		gssproxy-0.3.0-continuations.patch | ||||||
| 
 | 
 | ||||||
| %global servicename gssproxy | %global servicename gssproxy | ||||||
| %global pubconfpath %{_sysconfdir}/gssproxy | %global pubconfpath %{_sysconfdir}/gssproxy | ||||||
| @ -56,6 +57,7 @@ A proxy for GSSAPI credential handling | |||||||
| 
 | 
 | ||||||
| %patch0 -p2 -b .gss_init_sec_context | %patch0 -p2 -b .gss_init_sec_context | ||||||
| %patch1 -p2 -b .gss_inquire_cred_by_mech | %patch1 -p2 -b .gss_inquire_cred_by_mech | ||||||
|  | %patch2 -p2 -b .continuations | ||||||
| 
 | 
 | ||||||
| %build | %build | ||||||
| autoreconf -f -i | autoreconf -f -i | ||||||
| @ -113,6 +115,8 @@ rm -rf %{buildroot} | |||||||
| - resolves: https://fedorahosted.org/gss-proxy/ticket/106 | - resolves: https://fedorahosted.org/gss-proxy/ticket/106 | ||||||
| - Fix OID handling in gss_inquire_cred_by_mech() | - Fix OID handling in gss_inquire_cred_by_mech() | ||||||
| - resolves: https://fedorahosted.org/gss-proxy/ticket/107 | - resolves: https://fedorahosted.org/gss-proxy/ticket/107 | ||||||
|  | - Fix continuation processing for not yet fully established contexts. | ||||||
|  | - resolves: https://fedorahosted.org/gss-proxy/ticket/108 | ||||||
| 
 | 
 | ||||||
| * Wed Oct 23 2013 Guenther Deschner <gdeschner@redhat.com> 0.3.0-0 | * Wed Oct 23 2013 Guenther Deschner <gdeschner@redhat.com> 0.3.0-0 | ||||||
| - New upstream release 0.3.0: | - New upstream release 0.3.0: | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user