File: globus_gram_protocol.c

package info (click to toggle)
globus-gram-protocol 9.7-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,720 kB
  • ctags: 444
  • sloc: sh: 8,749; ansic: 4,680; makefile: 352; perl: 233
file content (347 lines) | stat: -rw-r--r-- 10,961 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/*
 * Copyright 1999-2006 University of Chicago
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "globus_i_gram_protocol.h"
#include "version.h"

/**
 * @defgroup globus_gram_protocol_functions Functions
 */
gss_cred_id_t				globus_i_gram_protocol_credential;
globus_mutex_t				globus_i_gram_protocol_mutex;
globus_cond_t				globus_i_gram_protocol_cond;

globus_list_t *				globus_i_gram_protocol_listeners;
globus_list_t *				globus_i_gram_protocol_connections;
globus_list_t *				globus_i_gram_protocol_old_creds;
globus_bool_t 				globus_i_gram_protocol_shutdown_called;
globus_io_attr_t			globus_i_gram_protocol_default_attr;
int					globus_i_gram_protocol_num_connects;
int                                     globus_i_gram_protocol_max_concurrency;
globus_gram_protocol_handle_t		globus_i_gram_protocol_handle;
const int GLOBUS_GRAM_PROTOCOL_DEFAULT_MAX_CONCURRENCY = 10;

static int globus_l_gram_protocol_activate(void);
static int globus_l_gram_protocol_deactivate(void);

globus_module_descriptor_t globus_i_gram_protocol_module =
{
    "globus_gram_protocol",
    globus_l_gram_protocol_activate,
    globus_l_gram_protocol_deactivate,
    GLOBUS_NULL,
    GLOBUS_NULL,
    &local_version
};


static
int
globus_l_gram_protocol_activate(void)
{
    OM_uint32				major_status;
    OM_uint32				minor_status;
    int					result;
    char *				message;
    char *                              max_concurrency;

    result = globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE);
    if(result != GLOBUS_SUCCESS)
    {
        return GLOBUS_GRAM_PROTOCOL_ERROR_NO_RESOURCES;
    }

    result = globus_module_activate(GLOBUS_IO_MODULE);
    if(result != GLOBUS_SUCCESS)
    {
	return GLOBUS_GRAM_PROTOCOL_ERROR_NO_RESOURCES;
    }

    globus_thread_key_create(
            &globus_i_gram_protocol_error_key,
            globus_i_gram_protocol_error_destroy);

    max_concurrency = globus_module_getenv("GLOBUS_GRAM_PROTOCOL_MAX_CONCURRENCY");
    if (max_concurrency)
    {
        globus_i_gram_protocol_max_concurrency = atoi(max_concurrency);
    }
    if (globus_i_gram_protocol_max_concurrency <= 0)
    {
        globus_i_gram_protocol_max_concurrency =
            GLOBUS_GRAM_PROTOCOL_DEFAULT_MAX_CONCURRENCY;
    }
    /*
     * Get the GSSAPI security credential for this process.
     * we save it in static storage, since it is only
     * done once and can be shared by many threads.
     * with some GSSAPI implementations a prompt to the user
     * may be done from this routine.
     *
     * we will use the assist version of acquire_cred
     */

    major_status = globus_gss_assist_acquire_cred(&minor_status,
                        GSS_C_BOTH,
                        &globus_i_gram_protocol_credential);

    if (major_status != GSS_S_COMPLETE)
    {
        globus_gss_assist_display_status_str(
		&message,
                "gram_init failure:",
                major_status,
                minor_status,
                0);
	globus_gram_protocol_error_7_hack_replace_message(message);

	globus_module_deactivate(GLOBUS_IO_MODULE);

        return GLOBUS_GRAM_PROTOCOL_ERROR_AUTHORIZATION; /* need better return code */
    }

    globus_i_gram_protocol_listeners = GLOBUS_NULL;
    globus_i_gram_protocol_connections = GLOBUS_NULL;
    globus_i_gram_protocol_old_creds = GLOBUS_NULL;
    globus_i_gram_protocol_shutdown_called = GLOBUS_FALSE;
    globus_i_gram_protocol_num_connects = 0;
    globus_mutex_init(&globus_i_gram_protocol_mutex, GLOBUS_NULL);
    globus_cond_init(&globus_i_gram_protocol_cond, GLOBUS_NULL);
    globus_gram_protocol_setup_attr(&globus_i_gram_protocol_default_attr);

    return GLOBUS_SUCCESS;
}


static int
globus_l_gram_protocol_deactivate(void)
{
    globus_i_gram_protocol_listener_t *  listener;

    /*
     * wait for in-progress commands to complete
     */
    globus_mutex_lock( &globus_i_gram_protocol_mutex );
    {
	globus_i_gram_protocol_shutdown_called = GLOBUS_TRUE;

	/* finish all outstanding accepts */
	while (!globus_list_empty(globus_i_gram_protocol_listeners))
	{
	    listener = (globus_i_gram_protocol_listener_t *)
		globus_list_first(globus_i_gram_protocol_listeners);

	    globus_i_gram_protocol_callback_disallow(listener);
	}

	/* wait for all outgoing connections to get replies */
	while (globus_i_gram_protocol_num_connects != 0)
	{
	    globus_cond_wait(&globus_i_gram_protocol_cond,
			     &globus_i_gram_protocol_mutex);
	}
    }
    globus_mutex_unlock(&globus_i_gram_protocol_mutex);
    globus_io_tcpattr_destroy(&globus_i_gram_protocol_default_attr);
    globus_mutex_destroy(&globus_i_gram_protocol_mutex);

    globus_module_deactivate(GLOBUS_GSI_GSS_ASSIST_MODULE);
    globus_module_deactivate(GLOBUS_IO_MODULE);
    /*
     * GSSAPI - cleanup of the credential
     * don't really care about returned status
     */
    if (globus_i_gram_protocol_credential != GSS_C_NO_CREDENTIAL)
    {
        OM_uint32 minor_status;
        gss_release_cred(&minor_status,
                         &globus_i_gram_protocol_credential);
	globus_i_gram_protocol_credential = GSS_C_NO_CREDENTIAL;
    }

    globus_i_gram_protocol_listeners = GLOBUS_NULL;
    return GLOBUS_SUCCESS;
}

/************************* help function *********************************/

/**
 * @brief Create default I/O attribute for GRAM
 * @ingroup globus_gram_protocol_io
 *
 * @details
 * The @a globus_gram_protocol_setup_attr() function creates a new
 * globus_io attribute containing the default set of values needed for
 * communication between a GRAM client and a job manager. These attributes
 * include:
 * - SO_KEEPALIVE
 * - GSSAPI Mutual Authentication
 * - GSSAPI Self Authorization
 * - SSL-compatible message wrapping
 *
 * @param attr
 *     A pointer to a @a globus_io_attr_t structure which will be initialized
 *     by this function.
 *
 * @return
 *     Upon success, globus_gram_protocol_setup_attr() modifies the @a attr
 *     parameter to point to a new attribute and returns the value
 *     @a GLOBUS_SUCCESS. When this occurs, the caller must destroy
 *     the attribute when no longer needed by calling
 *     globus_io_tcpattr_destroy(). If an error occurs, its value will be
 *     returned and the attribute pointed to by the @a attr parameter will be
 *     set to an uninitialized state.
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 * @retval GLOBUS_GRAM_PROTOCOL_ERROR_CONNECTION_FAILED
 *     Error initializing attribute
 */
int
globus_gram_protocol_setup_attr(globus_io_attr_t *  attr)
{
    globus_result_t                        res;
    globus_io_secure_authorization_data_t  auth_data;

    /* acquire mutex */
    res = globus_io_secure_authorization_data_initialize(&auth_data);
    if (res != GLOBUS_SUCCESS)
    {
        goto error_exit;
    }
    res = globus_io_tcpattr_init(attr);
    if (res != GLOBUS_SUCCESS)
    {
        goto destroy_1;
    }
    res = globus_io_attr_set_socket_keepalive(attr, GLOBUS_TRUE);
    if (res != GLOBUS_SUCCESS)
    {
        goto destroy_2;
    }
    res = globus_io_attr_set_secure_authentication_mode(
        attr,
        GLOBUS_IO_SECURE_AUTHENTICATION_MODE_MUTUAL,
        globus_i_gram_protocol_credential);
    if (res != GLOBUS_SUCCESS)
    {
        goto destroy_2;
    }
    res = globus_io_attr_set_secure_authorization_mode(
        attr,
        GLOBUS_IO_SECURE_AUTHORIZATION_MODE_SELF,
        &auth_data);
    if (res != GLOBUS_SUCCESS)
    {
        goto destroy_2;
    }
    res = globus_io_attr_set_secure_channel_mode(
        attr,
        GLOBUS_IO_SECURE_CHANNEL_MODE_SSL_WRAP);
    if (res != GLOBUS_SUCCESS)
    {
        goto destroy_2;
    }

    globus_io_secure_authorization_data_destroy(&auth_data);
    return GLOBUS_SUCCESS;

destroy_2:
    globus_io_tcpattr_destroy(attr);
destroy_1:
    globus_io_secure_authorization_data_destroy(&auth_data);
error_exit:
    globus_object_free(globus_error_get(res));

    /* release mutex */
    return GLOBUS_GRAM_PROTOCOL_ERROR_CONNECTION_FAILED;
}

/**
 * @brief Determine if a GSSAPI context has the same source and target identities
 * @ingroup globus_gram_protocol_io
 *
 * @details
 * The @a globus_gram_protocol_authorize_self() function implements a predicate
 * which returns true if the source and destination identities used to
 * establish the GSSAPI security context are the same.
 *
 * @param context
 *     A GSSAPI security context which has been previously established. The
 *     source and target names of this context will be inspected by this 
 *     function.
 * 
 * @return
 *     If the source and target identiies are the same, then
 *     @a #globus_gram_protocol_authorize_self() returns @a GLOBUS_TRUE,
 *     otherwise, this function returns @a GLOBUS_FALSE.
 *
 * @retval GLOBUS_TRUE
 *     The source and target identities are the same.
 * @retval GLOBUS_FALSE
 *     The source and target identities are not the same or this function is
 *     unabled to inspect the security context.
 */
globus_bool_t
globus_gram_protocol_authorize_self(
    gss_ctx_id_t                        context)
{
    OM_uint32                           major_status;
    OM_uint32                           minor_status;
    gss_name_t                          source_name;
    gss_name_t                          target_name;
    int                                 equal;
    globus_bool_t                       result = GLOBUS_FALSE;
    
    major_status = gss_inquire_context(&minor_status,
                                       context,
                                       &source_name,
                                       &target_name,
                                       NULL,
                                       NULL,
                                       NULL,
                                       NULL,
                                       NULL);
    if(GSS_ERROR(major_status))
    {
        goto exit;
    }

    major_status = gss_compare_name(&minor_status,
                                    source_name,
                                    target_name,
                                    &equal);
    if(GSS_ERROR(major_status))
    {
        goto free_names;
    }

    if(equal)
    {
        result = GLOBUS_TRUE;
    }
    
 free_names:
    gss_release_name(&minor_status,
                     &source_name);
    gss_release_name(&minor_status,
                     &target_name);
 exit:

    return result;
    
}
/* globus_gram_protocol_authorize_self */