~ubuntu-branches/ubuntu/vivid/globus-gss-assist/vivid

« back to all changes in this revision

Viewing changes to tokens_n.c

  • Committer: Bazaar Package Importer
  • Author(s): Mattias Ellert
  • Date: 2009-04-18 20:17:33 UTC
  • Revision ID: james.westby@ubuntu.com-20090418201733-xl4r26mgda1shx4q
Tags: upstream-4.0
ImportĀ upstreamĀ versionĀ 4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 1999-2006 University of Chicago
 
3
 * 
 
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
 
7
 * 
 
8
 * http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
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.
 
15
 */
 
16
 
 
17
#ifndef GLOBUS_DONT_DOCUMENT_INTERNAL
 
18
/**
 
19
 * @file tokens_n.c
 
20
 * @author Sam Lang, Sam Meder
 
21
 * 
 
22
 * $RCSfile: tokens_n.c,v $
 
23
 * $Revision: 1.7 $
 
24
 * $Date: 2007/08/09 14:24:23 $
 
25
 */
 
26
#endif
 
27
 
 
28
#include "globus_io.h"
 
29
#include "assist_config.h"
 
30
#include "globus_gss_assist.h"
 
31
 
 
32
/**
 
33
 * @name Token Get Nexus
 
34
 */
 
35
/* @{ */
 
36
/**
 
37
 * Use a nexus socket to get the tokens
 
38
 * @ingroup globus_gsi_gss_assist_tokens
 
39
 *
 
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. 
 
45
 *
 
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.
 
49
 *
 
50
 * @param arg
 
51
 *        the globus_io_handle_t to get the token from
 
52
 * @param bufp
 
53
 *        the buffer to read the token into
 
54
 * @param the size of what gets read
 
55
 *
 
56
 * @return 
 
57
 *        0 on success
 
58
 *        > 0 is internal return
 
59
 *        < 0 is the -errno returned from nexus
 
60
 */
 
61
int
 
62
globus_gss_assist_token_get_nexus(
 
63
    void *                              arg, 
 
64
    void **                             bufp, 
 
65
    size_t *                            sizep)
 
66
{
 
67
    unsigned char                       int_buf[5];
 
68
    unsigned char *                     pp;
 
69
    unsigned char *                     bp = NULL;
 
70
    int                                 bsize;
 
71
    int                                 dsize;
 
72
    int                                 size;
 
73
    void *                              cp;
 
74
    int                                 err = 0;
 
75
    int                                 rc;
 
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;
 
80
        
 
81
    if ((rc = _nx_read_blocking(handle, int_buf, 4)) != 0)
 
82
    {
 
83
        return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
 
84
        goto exit;
 
85
    }
 
86
    /*
 
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 
 
92
     * or a TLS  3 1
 
93
     */
 
94
 
 
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))
 
99
    {
 
100
        /* looks like a SSL token read rest of length */
 
101
 
 
102
        if ((rc = _nx_read_blocking(handle, &int_buf[4], 1)) != 0)
 
103
        {
 
104
            return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
 
105
            goto exit;
 
106
        }
 
107
 
 
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]));
 
112
 
 
113
        if ((int_buf[0] & 0x80)) 
 
114
        {
 
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
 
119
             */
 
120
            dsize = ( ((unsigned int) int_buf[0] & 0x7f)<<8 
 
121
                      | (unsigned int) int_buf[1]) - 3;
 
122
        } else {
 
123
            dsize = (  ( ((unsigned int) int_buf[3]) << 8)
 
124
                       |   ((unsigned int) int_buf[4]) );
 
125
        }
 
126
 
 
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
 
132
         * these as well.
 
133
         */
 
134
        
 
135
        if (int_buf[0] == 26)
 
136
        {
 
137
            bsize = dsize + 12;  /* MD, seq, data-length */
 
138
            bp = (void *)malloc(bsize);
 
139
            if (!bp)
 
140
            {
 
141
                return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
 
142
                goto exit;
 
143
            }
 
144
            if ((rc = _nx_read_blocking(handle, bp, bsize)) != 0)
 
145
            {
 
146
                return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
 
147
                goto exit;
 
148
            }
 
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]) );
 
153
            
 
154
            size = bsize + dsize + 5;
 
155
        }
 
156
        else
 
157
        {
 
158
            size = dsize + 5;
 
159
        }
 
160
        cp = (void *)malloc(size);
 
161
        if (!cp)
 
162
        {
 
163
            return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
 
164
            goto exit;
 
165
        }
 
166
        /* reassemble token header from int_buf and bp */
 
167
 
 
168
        pp = cp;
 
169
        memcpy(pp,int_buf,5);
 
170
        pp += 5;
 
171
        if (bp)
 
172
        {
 
173
            memcpy(pp,bp,bsize);
 
174
            pp += bsize;
 
175
            free(bp);
 
176
            bp = NULL;
 
177
        }
 
178
        if ((rc = _nx_read_blocking(handle, pp, dsize)) != 0)
 
179
        {
 
180
            return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
 
181
            goto exit;
 
182
        }
 
183
    }
 
184
    else
 
185
    {
 
186
 
 
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]) );
 
191
        
 
192
        
 
193
        if (size > 1<<24 || size < 0) 
 
194
        {
 
195
            size = 80;
 
196
            err = 1;
 
197
        }
 
198
 
 
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)));
 
202
 
 
203
        cp = (char *) malloc(size);
 
204
        if (!cp) 
 
205
        {
 
206
            return_value = GLOBUS_GSS_ASSIST_TOKEN_ERR_MALLOC;
 
207
            goto exit;
 
208
        }
 
209
        
 
210
        if ((rc = _nx_read_blocking(handle, (char *) cp, size)) != 0)
 
211
        {
 
212
            return_value = rc == -1 ? GLOBUS_GSS_ASSIST_TOKEN_EOF : -rc;
 
213
            goto exit;
 
214
        } 
 
215
 
 
216
        if (err)
 
217
        {
 
218
            /* 
 
219
             * bad formed token size, attempt to print first 80 bytes 
 
220
             * as it may be readable
 
221
             */
 
222
            
 
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;
 
229
            goto exit;
 
230
        }
 
231
    }
 
232
    *bufp = cp;
 
233
    *sizep = size;
 
234
 
 
235
 exit:
 
236
 
 
237
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
238
    return return_value;
 
239
}
 
240
/* @} */
 
241
 
 
242
/**
 
243
 * @name Token Send Nexus
 
244
 */
 
245
/* @{ */
 
246
/**
 
247
 * @ingroup globus_gsi_gss_assist_tokens
 
248
 * Write a token to the nexus io handle. 
 
249
 * This function provides parameter types that allow 
 
250
 * it to be passed to
 
251
 * @ref globus_gss_assist_init_sec_context and 
 
252
 * @ref globus_gss_assist_accept_sec_context
 
253
 * 
 
254
 * @param arg
 
255
 *        nexus io handle to send the token on
 
256
 * @param buf
 
257
 *        the token as a buffer
 
258
 * @param size
 
259
 *        the size of the buffer
 
260
 *
 
261
 * @return
 
262
 *        0 on success
 
263
 *        >0 on error
 
264
 *        <0 on errno error (-errno)
 
265
 */
 
266
int
 
267
globus_gss_assist_token_send_nexus(
 
268
    void *                              arg,  
 
269
    void *                              buf, 
 
270
    size_t                              size)
 
271
 
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;
 
277
 
 
278
    ex.arg = arg;
 
279
    ex.flags = 0;
 
280
 
 
281
    return_value = 
 
282
        globus_gss_assist_token_send_nexus_ex((void *)&ex, buf, size);
 
283
 
 
284
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
285
    return return_value;
 
286
}
 
287
/* @} */
 
288
 
 
289
/**
 
290
 * @name Token Send Nexus Without Length
 
291
 */
 
292
/* @{ */
 
293
/**
 
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.
 
298
 */
 
299
int
 
300
globus_gss_assist_token_send_nexus_without_length(
 
301
    void *                              arg,  
 
302
    void *                              buf, 
 
303
    size_t                              size)
 
304
{
 
305
    int                                 return_value;
 
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;
 
310
 
 
311
    ex.arg  = arg;
 
312
    ex.flags = GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH;
 
313
 
 
314
    return_value = globus_gss_assist_token_send_nexus_ex((void *)&ex, 
 
315
                                                         buf, size);
 
316
 
 
317
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
318
    return return_value;
 
319
}
 
320
/* @} */
 
321
 
 
322
/**
 
323
 * @name Token Send Nexus EX
 
324
 */
 
325
/* @{ */
 
326
/**
 
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
 
330
 * to be written.
 
331
 *
 
332
 * @param exp
 
333
 *        The globus_gss_assist_ex that the wraps the nexus IO
 
334
 *        handle to send the token on
 
335
 * @param buf
 
336
 *        the buffer holding the token
 
337
 * @param size
 
338
 *        the size of the buffer
 
339
 *
 
340
 * @return
 
341
 *        0 on success
 
342
 *        >0 on error
 
343
 *        <0 on errno error (-errno)
 
344
 */
 
345
int
 
346
globus_gss_assist_token_send_nexus_ex(
 
347
    void *                              exp,  
 
348
    void *                              buf, 
 
349
    size_t                              size)
 
350
{
 
351
    unsigned char                       int_buf[4];
 
352
    char *                              header = (char *) buf;
 
353
    int                                 rc;
 
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;
 
359
 
 
360
    ex = (globus_gss_assist_ex *) exp;
 
361
    handle = (globus_io_handle_t *) ex->arg;
 
362
 
 
363
    /*
 
364
     * Will always send SSL type tokens without a length
 
365
     */
 
366
 
 
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))))
 
370
    {
 
371
        if (!(ex->flags & GLOBUS_GSS_ASSIST_EX_SEND_WITHOUT_LENGTH)) 
 
372
        {
 
373
            int_buf[0] =  size >> 24;
 
374
            int_buf[1] =  size >> 16;
 
375
            int_buf[2] =  size >>  8;
 
376
            int_buf[3] =  size;
 
377
            
 
378
            if ((rc = _nx_write_blocking(handle, int_buf, 4)) != 0) 
 
379
            {
 
380
                return_value = rc;
 
381
                goto exit;
 
382
            }
 
383
        }
 
384
    }
 
385
 
 
386
    if ((rc = _nx_write_blocking(handle, (char *) buf, size)) != 0)
 
387
    {
 
388
        return_value = rc;
 
389
        goto exit;
 
390
    }
 
391
 
 
392
 exit:
 
393
 
 
394
    GLOBUS_I_GSI_GSS_ASSIST_DEBUG_EXIT;
 
395
    return return_value;
 
396
}
 
397
/* @} */