@@ -168,3 +168,142 @@ int gp_find_cred(gssx_cred *cred, gss_cred_id_t *out)
168168{
169169 return gp_import_gssx_cred (& cred -> cred_handle_reference , out );
170170}
171+
172+
173+ /* Exported Contexts */
174+
175+ #define EXP_CTX_TYPE_OPTION "exported_contex_type"
176+ #define LINUX_LUCID_V1 "linux_lucid_v1"
177+
178+ enum exp_ctx_types {
179+ EXP_CTX_DEFAULT = 0 ,
180+ EXP_CTX_LINUX_LUCID_V1 = 1 ,
181+ };
182+
183+ int gp_get_exported_context_type (struct gssx_call_ctx * ctx )
184+ {
185+
186+ struct gssx_option * val ;
187+ int i ;
188+
189+ for (i = 0 ; i < ctx -> options .options_len ; i ++ ) {
190+ val = & ctx -> options .options_val [i ];
191+ if (val -> option .octet_string_len == sizeof (EXP_CTX_TYPE_OPTION ) &&
192+ strncmp (EXP_CTX_TYPE_OPTION ,
193+ val -> option .octet_string_val ,
194+ val -> option .octet_string_len ) == 0 ) {
195+ if (strncmp (LINUX_LUCID_V1 ,
196+ val -> value .octet_string_val ,
197+ val -> value .octet_string_len ) == 0 ) {
198+ return EXP_CTX_LINUX_LUCID_V1 ;
199+ }
200+ return -1 ;
201+ }
202+ }
203+
204+ return EXP_CTX_DEFAULT ;
205+ }
206+
207+ uint32_t gp_export_ctx_id_to_gssx (uint32_t * min , int type ,
208+ gss_ctx_id_t * in , gssx_ctx * out )
209+ {
210+ uint32_t ret_maj ;
211+ uint32_t ret_min ;
212+ gss_name_t src_name = GSS_C_NO_NAME ;
213+ gss_name_t targ_name = GSS_C_NO_NAME ;
214+ gss_buffer_desc export_buffer = GSS_C_EMPTY_BUFFER ;
215+ uint32_t lifetime_rec ;
216+ gss_OID mech_type ;
217+ uint32_t ctx_flags ;
218+ int is_locally_initiated ;
219+ int is_open ;
220+ int ret ;
221+
222+ /* TODO: For mechs that need multiple roundtrips to complete */
223+ /* out->state; */
224+
225+ /* we do not need the client to release anything until we handle state */
226+ out -> needs_release = false;
227+
228+ ret_maj = gss_inquire_context (& ret_min , * in , & src_name , & targ_name ,
229+ & lifetime_rec , & mech_type , & ctx_flags ,
230+ & is_locally_initiated , & is_open );
231+ if (ret_maj ) {
232+ goto done ;
233+ }
234+
235+ ret = gp_conv_oid_to_gssx (mech_type , & out -> mech );
236+ if (ret ) {
237+ ret_maj = GSS_S_FAILURE ;
238+ ret_min = ret ;
239+ goto done ;
240+ }
241+
242+ ret_maj = gp_conv_name_to_gssx (& ret_min , src_name , & out -> src_name );
243+ if (ret_maj ) {
244+ goto done ;
245+ }
246+
247+ ret_maj = gp_conv_name_to_gssx (& ret_min , targ_name , & out -> targ_name );
248+ if (ret_maj ) {
249+ goto done ;
250+ }
251+
252+ out -> lifetime = lifetime_rec ;
253+
254+ out -> ctx_flags = ctx_flags ;
255+
256+ if (is_locally_initiated ) {
257+ out -> locally_initiated = true;
258+ }
259+
260+ if (is_open ) {
261+ out -> open = true;
262+ }
263+
264+ /* note: once converted the original context token is not usable anymore,
265+ * so this must be the last call to use it */
266+ ret_maj = gss_export_sec_context (& ret_min , in , & export_buffer );
267+ if (ret_maj ) {
268+ ret_maj = GSS_S_FAILURE ;
269+ ret_min = ENOMEM ;
270+ goto done ;
271+ }
272+ ret = gp_conv_buffer_to_gssx (& export_buffer , & out -> exported_context_token );
273+ if (ret ) {
274+ ret_maj = GSS_S_FAILURE ;
275+ ret_min = ret ;
276+ goto done ;
277+ }
278+
279+ /* Leave this empty, used only on the way in for init_sec_context */
280+ /* out->gssx_option */
281+
282+ done :
283+ * min = ret_min ;
284+ gss_release_name (& ret_min , & src_name );
285+ gss_release_name (& ret_min , & targ_name );
286+ gss_release_buffer (& ret_min , & export_buffer );
287+ if (ret_maj ) {
288+ xdr_free ((xdrproc_t )xdr_gssx_OID , (char * )& out -> mech );
289+ xdr_free ((xdrproc_t )xdr_gssx_name , (char * )& out -> src_name );
290+ xdr_free ((xdrproc_t )xdr_gssx_name , (char * )& out -> targ_name );
291+ }
292+ return ret_maj ;
293+ }
294+
295+ uint32_t gp_import_gssx_to_ctx_id (uint32_t * min , int type ,
296+ gssx_ctx * in , gss_ctx_id_t * out )
297+ {
298+ gss_buffer_desc export_buffer = GSS_C_EMPTY_BUFFER ;
299+
300+ if (type != EXP_CTX_DEFAULT ) {
301+ * min = EINVAL ;
302+ return GSS_S_FAILURE ;
303+ }
304+
305+ gp_conv_gssx_to_buffer (& in -> exported_context_token , & export_buffer );
306+
307+ return gss_import_sec_context (min , & export_buffer , out );
308+ }
309+
0 commit comments