source: web/old/remctl-2.14/util/gss-tokens.c @ f6f3e91

web
Last change on this file since f6f3e91 was f6f3e91, checked in by Jessica B. Hamrick <jhamrick@…>, 15 years ago

Preserve directory hierarchy (not sure what happened to it)

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * GSS token handling routines.
3 *
4 * Higher-level wrappers around the low-level token handling routines that
5 * apply integrity and privacy protection to the token data before sending.
6 * token_send_priv and token_recv_priv are similar to token_send and
7 * token_recv except that they also take a GSS-API context and a GSS-API major
8 * and minor status to report errors.
9 *
10 * Originally written by Anton Ushakov
11 * Extensive modifications by Russ Allbery <rra@stanford.edu>
12 * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008
13 *     Board of Trustees, Leland Stanford Jr. University
14 *
15 * See README for licensing terms.
16 */
17
18#include <config.h>
19#include <portable/system.h>
20#include <portable/gssapi.h>
21
22#include <util/util.h>
23
24/*
25 * If we're running the test suite, call testing versions of the token
26 * functions.
27 */
28#if TESTING
29# define token_send fake_token_send
30# define token_recv fake_token_recv
31enum token_status token_send(int, int, gss_buffer_t);
32enum token_status token_recv(int, int *, gss_buffer_t, size_t);
33#endif
34
35
36/*
37 * Wraps, encrypts, and sends a data payload token.  Takes the file descriptor
38 * to send to, the GSS-API context, the flags to send with the token, the
39 * token, and the status variables.  Returns TOKEN_OK on success and
40 * TOKEN_FAIL_SYSTEM or TOKEN_FAIL_GSSAPI on failure.  If the latter is
41 * returned, the major and minor status variables will be set to something
42 * useful.
43 *
44 * As a hack to support remctl v1, look to see if the flags includes
45 * TOKEN_SEND_MIC and don't include TOKEN_PROTOCOL.  If so, expect the remote
46 * side to reply with a MIC, which we then verify.
47*/
48enum token_status
49token_send_priv(int fd, gss_ctx_id_t ctx, int flags, gss_buffer_t tok,
50                OM_uint32 *major, OM_uint32 *minor)
51{
52    gss_buffer_desc out, mic;
53    int state, micflags;
54    enum token_status status;
55
56    if (tok->length > TOKEN_MAX_DATA)
57        return TOKEN_FAIL_LARGE;
58    *major = gss_wrap(minor, ctx, 1, GSS_C_QOP_DEFAULT, tok, &state, &out);
59    if (*major != GSS_S_COMPLETE)
60        return TOKEN_FAIL_GSSAPI;
61    status = token_send(fd, flags, &out);
62    gss_release_buffer(minor, &out);
63    if (status != TOKEN_OK)
64        return status;
65    if ((flags & TOKEN_SEND_MIC) && !(flags & TOKEN_PROTOCOL)) {
66        status = token_recv(fd, &micflags, &mic, 10 * 1024);
67        if (status != TOKEN_OK)
68            return status;
69        if (micflags != TOKEN_MIC) {
70            gss_release_buffer(minor, &mic);
71            return TOKEN_FAIL_INVALID;
72        }
73        *major = gss_verify_mic(minor, ctx, tok, &mic, NULL);
74        if (*major != GSS_S_COMPLETE) {
75            gss_release_buffer(minor, &mic);
76            return TOKEN_FAIL_GSSAPI;
77        }
78        gss_release_buffer(minor, &mic);
79    }
80    return TOKEN_OK;
81}
82
83
84/*
85 * Receives and unwraps a data payload token.  Takes the file descriptor,
86 * GSS-API context, a pointer into which to storge the flags, a buffer for the
87 * message, and a place to put GSS-API major and minor status.  Returns
88 * TOKEN_OK on success or one of the TOKEN_FAIL_* statuses on failure.  On
89 * success, tok will contain newly allocated memory and should be freed when
90 * no longer needed using gss_release_buffer.  On failure, any allocated
91 * memory will be freed.
92 *
93 * As a hack to support remctl v1, look to see if the flags includes
94 * TOKEN_SEND_MIC and do not include TOKEN_PROTOCOL.  If so, calculate a MIC
95 * and send it back.
96 */
97enum token_status
98token_recv_priv(int fd, gss_ctx_id_t ctx, int *flags, gss_buffer_t tok,
99                size_t max, OM_uint32 *major, OM_uint32 *minor)
100{
101    gss_buffer_desc in, mic;
102    int state;
103    enum token_status status;
104
105    status = token_recv(fd, flags, &in, max);
106    if (status != TOKEN_OK)
107        return status;
108    *major = gss_unwrap(minor, ctx, &in, tok, &state, NULL);
109    free(in.value);
110    if (*major != GSS_S_COMPLETE)
111        return TOKEN_FAIL_GSSAPI;
112    if ((*flags & TOKEN_SEND_MIC) && !(*flags & TOKEN_PROTOCOL)) {
113        *major = gss_get_mic(minor, ctx, GSS_C_QOP_DEFAULT, tok, &mic);
114        if (*major != GSS_S_COMPLETE) {
115            gss_release_buffer(minor, tok);
116            return TOKEN_FAIL_GSSAPI;
117        }
118        status = token_send(fd, TOKEN_MIC, &mic);
119        if (status != TOKEN_OK) {
120            gss_release_buffer(minor, tok);
121            gss_release_buffer(minor, &mic);
122            return status;
123        }
124        gss_release_buffer(minor, &mic);
125        *flags = (*flags) & ~TOKEN_SEND_MIC;
126    }
127    return TOKEN_OK;
128}
Note: See TracBrowser for help on using the repository browser.