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_f.c,v $
24
* $Date: 2007/08/09 14:24:23 $
29
* @defgroup globus_gsi_gss_assist_tokens Security Token Transport
30
* Token routines using fread and fwrite
32
* Additional code has been added to detect tokens which
33
* are sent without a length field. These can currently be
34
* only SSL tokens. This does require some knowledge of the
35
* underlying GSSAPI, by the application, but is within the
36
* guidelines of the GSSAPI specifications.
38
* The get routine will automaticly attempt this test,
39
* while a new send routine will check a flag. The old send
40
* routine will work as before, sending a 4-byte length.
43
#include "globus_i_gss_assist.h"
49
* @name Token Get File Descriptor
53
* @ingroup globus_gsi_gss_assist_tokens
54
* Use a open file discriptor to get a token. This function
55
* provides parameter types that allow it to be passed to
56
* @ref globus_gss_assist_init_sec_context and
57
* @ref globus_gss_assist_accept_sec_context
60
* the FILE * stream cast to a void pointer
64
* the size (number of bytes) read into bufp
67
* > 0 is internal return
71
globus_gss_assist_token_get_fd(
76
unsigned char int_buf[5];
78
unsigned char * bp = NULL;
86
static char * _function_name_ =
87
"globus_gss_assist_token_get_fd";
88
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
91
if ((bytesread = fread(int_buf, 1, 4, fd)) != 4)
93
fprintf(stderr,_GASL("Failed reading length %d\n"),bytesread);
94
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
98
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
99
4, (globus_i_gsi_gss_assist_debug_fstream,
100
_GASL("token read:%2.2x%2.2x%2.2x%2.2x\n"),
101
int_buf[0],int_buf[1],int_buf[2],int_buf[3]));
104
* check if the length is missing, and we are receiving
105
* a SSL token directly.
106
* SSLv3 will start with a flag byte in the twenties
107
* followed by major version 3 minor version 0
108
* Will also accept a SSLv2 hello 2 0
112
if (((int_buf[0] >= 20) && (int_buf[0] <= 26)
113
&& (((int_buf[1] == 3 && ((int_buf[2] == 0) || int_buf[2] == 1))
114
|| (int_buf[1] == 2 && int_buf[2] == 0))))
115
|| ((int_buf[0] & 0x80) && int_buf[2] == 1))
117
/* looks like a SSL token read rest of length */
119
if (fread(&int_buf[4], 1, 1, fd) != 1)
121
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
122
3, (globus_i_gsi_gss_assist_debug_fstream,
123
_GASL("FAILED READING EXTRA BYTE\n")));
124
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
128
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
129
4, (globus_i_gsi_gss_assist_debug_fstream,
130
_GASL("reading SSL token %.2x%.2x%.2x%.2x%.2x\n"),
131
int_buf[0], int_buf[1], int_buf[2], int_buf[3], int_buf[4]));
133
if ((int_buf[0] & 0x80)) {
134
/* looks like a sslv2 hello
135
* length is of following bytes in header.
136
* we read in 5, 2 length and 3 extra,
137
* so only need next dsize -3
139
dsize = ( ((unsigned int) int_buf[0] & 0x7f)<<8
140
| (unsigned int) int_buf[1]) - 3;
142
dsize = ( ( ((unsigned int) int_buf[3]) << 8)
143
| ((unsigned int) int_buf[4]) );
146
/* If we are using the globus_ssleay, with
147
* international version, we may be using the
148
* "26" type, where the length is really the hash
149
* length, and there is a hash, 8 byte seq andi
150
* 4 byte data length following. We need to get
154
if (int_buf[0] == 26 )
156
bsize = dsize + 12; /* MD, seq, data-length */
157
bp = (void *)malloc(bsize);
160
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
163
if (fread(bp, 1, bsize, fd) != bsize)
165
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
168
dsize = ( ( ((unsigned int) bp[bsize-4]) << 24)
169
| ( ((unsigned int) bp[bsize-3]) << 16)
170
| ( ((unsigned int) bp[bsize-2]) << 8)
171
| ((unsigned int) bp[bsize-1]) );
173
size = bsize + dsize + 5;
179
cp = (void *)malloc(size);
182
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
186
/* reassemble token header from in_buf and bp */
189
memcpy(pp,int_buf,5);
198
if ((bytesread=fread(pp, 1, dsize, fd)) != dsize)
200
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
201
3, (globus_i_gsi_gss_assist_debug_fstream,
202
_GASL("READ SHORT: %d, %d\n"), dsize, bytesread));
203
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
209
size = ( ( ((unsigned int) int_buf[0]) << 24)
210
| ( ((unsigned int) int_buf[1]) << 16)
211
| ( ((unsigned int) int_buf[2]) << 8)
212
| ((unsigned int) int_buf[3]) );
214
if (size > 1<<24 || size < 0) /* size may be garbage */
216
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_BAD_SIZE;
220
cp = (void *)malloc(size);
223
return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
225
if ((bytesread=fread(cp, 1, size, fd)) != size)
227
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
228
3, (globus_i_gsi_gss_assist_debug_fstream,
229
_GASL("read short: %d, %d\n"), size, bytesread));
230
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
240
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
246
* @name Token Send File Descriptor
250
* @ingroup globus_gsi_gss_assist_tokens
251
* Write a token to the open file descriptor. WIll write it with a 4 byte
252
* length. This function provides parameter types that allow
254
* @ref globus_gss_assist_init_sec_context and
255
* @ref globus_gss_assist_accept_sec_context
258
* the FILE * stream to send the token on
262
* the size of the token in bytes
270
globus_gss_assist_token_send_fd(
275
int return_value = 0;
276
globus_gss_assist_ex ex;
277
static char * _function_name_ =
278
"globus_gss_assist_token_send_fd";
279
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
284
return_value = globus_gss_assist_token_send_fd_ex((void *)&ex, buf, size);
286
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
292
* @name Token Send File Descriptor Without Length
296
* @ingroup globus_gsi_gss_assist_tokens
297
* Write a token to the open file descripter.
298
* Will write it without a length. so as to
301
globus_gss_assist_token_send_fd_without_length(
306
int return_value = 0;
307
globus_gss_assist_ex ex;
308
static char * _function_name_ =
309
"globus_gss_assist_token_send_fd_without_length";
310
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
313
ex.flags = GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH;
315
return_value = globus_gss_assist_token_send_fd_ex((void *)&ex, buf, size);
317
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
323
* @name Token Send File Descriptor Flag 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 variable that holds
334
* the FILE * stream and flags to bet set
336
* the token buffer to send
338
* size of the token buffer
343
* <0 on errno error (-errno)
346
globus_gss_assist_token_send_fd_ex(
351
int return_value = 0;
352
unsigned char int_buf[4];
353
char * header = (char *)buf;
355
globus_gss_assist_ex * ex;
357
static char * _function_name_ =
358
"globus_gss_assist_token_send_fd_ex";
359
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_ENTER;
361
ex = (globus_gss_assist_ex *) exp;
362
fd = (FILE *) ex->arg;
365
* Will always send SSL type tokens without a length
368
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
369
3, (globus_i_gsi_gss_assist_debug_fstream,
370
_GASL("send_token: flags: %d length: %u\n"),
373
if (!(size > 5 && header[0] <= 26 && header[0] >= 20
374
&& ((header[1] == 3 && (header[2] == 0 || header[2] == 1))
375
|| (header[1] == 2 && header[2] == 0))))
378
if (!(ex->flags & GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH))
380
int_buf[0] = size >> 24;
381
int_buf[1] = size >> 16;
382
int_buf[2] = size >> 8;
385
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_FPRINTF(
386
3, (globus_i_gsi_gss_assist_debug_fstream,
387
_GASL("with 4 byte length")));
389
if (fwrite(int_buf ,1 ,4 , fd) != 4)
391
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
397
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_PRINT(3, "\n");
399
if (fwrite(buf, 1, size, fd) != size)
401
return_value = GLOBUS_GSS_ASSIST_TOKEN_EOF;
406
GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;