2
* Copyright 1999-2006 University of Chicago
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
20
* @author Sam Lang, Sam Meder
22
* $RCSfile: tokens_n.c,v $
24
* $Date: 2007/08/09 14:24:23 $
28
#include "globus_io.h"
29
#include "assist_config.h"
30
#include "globus_gss_assist.h"
33
* @name Token Get Nexus
37
* Use a nexus socket to get the tokens
38
* @ingroup globus_gsi_gss_assist_tokens
40
* Additional code has been added to detect tokens which
41
* are sent without a length field. These can currently be
42
* only SSL tokens. This does require some knowledge of the
43
* underlying GSSAPI, by the application, but is within the
44
* guidelines of the GSSAPI specifications.
46
* The get routine will automaticly attempt this test,
47
* while a new send routine will check a flag. The old send
48
* routine will work as before, sending a 4-byte length.
51
* the globus_io_handle_t to get the token from
53
* the buffer to read the token into
54
* @param the size of what gets read
58
* > 0 is internal return
59
* < 0 is the -errno returned from nexus
62
globus_gss_assist_token_get_nexus(
67
unsigned char int_buf[5];
69
unsigned char * bp = NULL;
76
globus_io_handle_t * handle = (globus_io_handle_t *)arg;
77
static char * _function_name_ =
78
"globus_gss_assist_token_get_nexus";
79
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
81
if ((rc = _nx_read_blocking(handle, int_buf, 4)) != 0)
83
return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
87
* check if the length is missing, and we are receiving
88
* a SSL token directly.
89
* SSLv3 will start with a flag byte in the twenties
90
* followed by major version 3 minor version 0
91
* Will also accept a SSLv2 hello 2 0
95
if (int_buf[0] >= 20 && int_buf[0] <= 26
96
&& (((int_buf[1] == 3 && (int_buf[2] == 0) || int_buf[2] == 1))
97
|| (int_buf[1] == 2 && int_buf[2] == 0))
98
|| ((int_buf[0] & 0x80) && int_buf[2] == 1))
100
/* looks like a SSL token read rest of length */
102
if ((rc = _nx_read_blocking(handle, &int_buf[4], 1)) != 0)
104
return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
108
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
109
3, (globus_i_gsi_gss_assist_debug_fstream,
110
_GASL("reading SSL token %.2x%.2x%.2x%.2x%.2x\n"),
111
int_buf[0],int_buf[1],int_buf[2],int_buf[3],int_buf[4]));
113
if ((int_buf[0] & 0x80))
115
/* Looks like a sslv2 hello.
116
* Length is of following bytes in header.
117
* we read in 5, 2 length and 3 extra,
118
* so only need next dsize -3
120
dsize = ( ((unsigned int) int_buf[0] & 0x7f)<<8
121
| (unsigned int) int_buf[1]) - 3;
123
dsize = ( ( ((unsigned int) int_buf[3]) << 8)
124
| ((unsigned int) int_buf[4]) );
127
/* If we are using the globus_ssleay, with
128
* international version, we may be using the
129
* "26" type, where the length is really the hash
130
* length, and there is a hash, 8 byte seq andi
131
* 4 byte data length following. We need to get
135
if (int_buf[0] == 26)
137
bsize = dsize + 12; /* MD, seq, data-length */
138
bp = (void *)malloc(bsize);
141
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
144
if ((rc = _nx_read_blocking(handle, bp, bsize)) != 0)
146
return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
149
dsize = ( ( ((unsigned int) bp[bsize-4]) << 24)
150
| ( ((unsigned int) bp[bsize-3]) << 16)
151
| ( ((unsigned int) bp[bsize-2]) << 8)
152
| ((unsigned int) bp[bsize-1]) );
154
size = bsize + dsize + 5;
160
cp = (void *)malloc(size);
163
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
166
/* reassemble token header from int_buf and bp */
169
memcpy(pp,int_buf,5);
178
if ((rc = _nx_read_blocking(handle, pp, dsize)) != 0)
180
return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
187
size = ( ( ((unsigned int) int_buf[0]) << 24)
188
| ( ((unsigned int) int_buf[1]) << 16)
189
| ( ((unsigned int) int_buf[2]) << 8)
190
| ((unsigned int) int_buf[3]) );
193
if (size > 1<<24 || size < 0)
199
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
200
3, (globus_i_gsi_gss_assist_debug_fstream,
201
_GASL("reading token of size=%d\n", size)));
203
cp = (char *) malloc(size);
206
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
210
if ((rc = _nx_read_blocking(handle, (char *) cp, size)) != 0)
212
return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
219
* bad formed token size, attempt to print first 80 bytes
220
* as it may be readable
223
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
224
3, (globus_i_gsi_gss_assist_debug_fstream,
225
_GASL(" bad token %c%c%c%c%s\n"),
226
int_buf[0], int_buf[1],
227
int_buf[2], int_buf[3], (char *) cp));
228
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_BAD_SIZE;
237
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
243
* @name Token Send Nexus
247
* @ingroup globus_gsi_gss_assist_tokens
248
* Write a token to the nexus io handle.
249
* This function provides parameter types that allow
251
* @ref globus_gss_assist_init_sec_context and
252
* @ref globus_gss_assist_accept_sec_context
255
* nexus io handle to send the token on
257
* the token as a buffer
259
* the size of the buffer
264
* <0 on errno error (-errno)
267
globus_gss_assist_token_send_nexus(
272
int return_value = 0;
273
globus_gss_assist_ex ex;
274
static char * _function_name_ =
275
"globus_gss_assist_token_send_nexus";
276
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
282
globus_gss_assist_token_send_nexus_ex((void *)&ex, buf, size);
284
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
290
* @name Token Send Nexus Without Length
294
* @ingroup globus_gsi_gss_assist_tokens
295
* Send a token on a nexus IO handle. Using this function
296
* the length is not sent.
297
* @see globus_gss_assist_token_get_nexus() for further info.
300
globus_gss_assist_token_send_nexus_without_length(
306
globus_gss_assist_ex ex;
307
static char * _function_name_ =
308
"globus_gss_assist_token_send_nexus_without_length";
309
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
312
ex.flags = GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH;
314
return_value = globus_gss_assist_token_send_nexus_ex((void *)&ex,
317
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
323
* @name Token Send Nexus EX
327
* @ingroup globus_gsi_gss_assist_tokens
328
* Write a token to the open file descripter.
329
* will look at the flag to determine if the length field need
333
* The globus_gss_assist_ex that the wraps the nexus IO
334
* handle to send the token on
336
* the buffer holding the token
338
* the size of the buffer
343
* <0 on errno error (-errno)
346
globus_gss_assist_token_send_nexus_ex(
351
unsigned char int_buf[4];
352
char * header = (char *) buf;
354
globus_io_handle_t * handle;
355
globus_gss_assist_ex * ex;
356
static char * _function_name_ =
357
"globus_gss_assist_token_send_nexus_ex";
358
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
360
ex = (globus_gss_assist_ex *) exp;
361
handle = (globus_io_handle_t *) ex->arg;
364
* Will always send SSL type tokens without a length
367
if (!(size > 5 && header[0] <= 26 && header[0] >= 20
368
&& ((header[1] == 3 && (header[2] == 0 || header[1] == 1))
369
|| (header[1] == 2 && header[2] == 0))))
371
if (!(ex->flags & GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH))
373
int_buf[0] = size >> 24;
374
int_buf[1] = size >> 16;
375
int_buf[2] = size >> 8;
378
if ((rc = _nx_write_blocking(handle, int_buf, 4)) != 0)
386
if ((rc = _nx_write_blocking(handle, (char *) buf, size)) != 0)
394
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;