~ubuntu-branches/ubuntu/karmic/rsyslog/karmic-200908151517

« back to all changes in this revision

Viewing changes to gss-misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2008-04-23 16:46:39 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080423164639-5acmt8a4vpxjgnxw
Tags: 3.14.2-3
* debian/rsyslog-doc.install
  - Fix a typo in the install path of the dia files. Closes: #477489
    Thanks to Justin B Rye for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gss-misc.c
 
2
 * This is a miscellaneous helper class for gss-api features.
 
3
 *
 
4
 * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
 
5
 *
 
6
 * This file is part of rsyslog.
 
7
 *
 
8
 * Rsyslog is free software: you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation, either version 3 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * Rsyslog is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with Rsyslog.  If not, see <http://www.gnu.org/licenses/>.
 
20
 *
 
21
 * A copy of the GPL can be found in the file "COPYING" in this distribution.
 
22
 */
 
23
#include "config.h"
 
24
#include "rsyslog.h"
 
25
#include <stdio.h>
 
26
#include <stdarg.h>
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <time.h>
 
30
#include <netinet/in.h>
 
31
#include <netdb.h>
 
32
#include <arpa/inet.h>
 
33
#include <fnmatch.h>
 
34
#include <assert.h>
 
35
#include <errno.h>
 
36
#include <ctype.h>
 
37
#include <unistd.h>
 
38
#ifdef USE_PTHREADS
 
39
#include <pthread.h>
 
40
#else
 
41
#include <fcntl.h>
 
42
#endif
 
43
#include <gssapi/gssapi.h>
 
44
#include "syslogd.h"
 
45
#include "syslogd-types.h"
 
46
#include "srUtils.h"
 
47
#include "net.h"
 
48
#include "omfwd.h"
 
49
#include "template.h"
 
50
#include "msg.h"
 
51
#include "tcpsyslog.h"
 
52
#include "module-template.h"
 
53
#include "obj.h"
 
54
#include "errmsg.h"
 
55
#include "gss-misc.h"
 
56
 
 
57
MODULE_TYPE_LIB
 
58
 
 
59
/* static data */
 
60
DEFobjStaticHelpers
 
61
DEFobjCurrIf(errmsg)
 
62
 
 
63
static void display_status_(char *m, OM_uint32 code, int type)
 
64
{
 
65
        OM_uint32 maj_stat, min_stat, msg_ctx = 0;
 
66
        gss_buffer_desc msg;
 
67
 
 
68
        do {
 
69
                maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NO_OID, &msg_ctx, &msg);
 
70
                if (maj_stat != GSS_S_COMPLETE) {
 
71
                        errmsg.LogError(NO_ERRCODE, "GSS-API error in gss_display_status called from <%s>\n", m);
 
72
                        break;
 
73
                } else {
 
74
                        char buf[1024];
 
75
                        snprintf(buf, sizeof(buf), "GSS-API error %s: %s\n", m, (char *) msg.value);
 
76
                        buf[sizeof(buf)/sizeof(char) - 1] = '\0';
 
77
                        errmsg.LogError(NO_ERRCODE, "%s", buf);
 
78
                }
 
79
                if (msg.length != 0)
 
80
                        gss_release_buffer(&min_stat, &msg);
 
81
        } while (msg_ctx);
 
82
}
 
83
 
 
84
 
 
85
static void display_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat)
 
86
{
 
87
        display_status_(m, maj_stat, GSS_C_GSS_CODE);
 
88
        display_status_(m, min_stat, GSS_C_MECH_CODE);
 
89
}
 
90
 
 
91
 
 
92
static void display_ctx_flags(OM_uint32 flags)
 
93
{
 
94
    if (flags & GSS_C_DELEG_FLAG)
 
95
        dbgprintf("GSS_C_DELEG_FLAG\n");
 
96
    if (flags & GSS_C_MUTUAL_FLAG)
 
97
        dbgprintf("GSS_C_MUTUAL_FLAG\n");
 
98
    if (flags & GSS_C_REPLAY_FLAG)
 
99
        dbgprintf("GSS_C_REPLAY_FLAG\n");
 
100
    if (flags & GSS_C_SEQUENCE_FLAG)
 
101
        dbgprintf("GSS_C_SEQUENCE_FLAG\n");
 
102
    if (flags & GSS_C_CONF_FLAG)
 
103
        dbgprintf("GSS_C_CONF_FLAG\n");
 
104
    if (flags & GSS_C_INTEG_FLAG)
 
105
        dbgprintf("GSS_C_INTEG_FLAG\n");
 
106
}
 
107
 
 
108
 
 
109
static int read_all(int fd, char *buf, unsigned int nbyte)
 
110
{
 
111
    int     ret;
 
112
    char   *ptr;
 
113
    fd_set  rfds;
 
114
    struct timeval tv;
 
115
 
 
116
    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
 
117
            FD_ZERO(&rfds);
 
118
            FD_SET(fd, &rfds);
 
119
            tv.tv_sec = 1;
 
120
            tv.tv_usec = 0;
 
121
 
 
122
            if ((ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) <= 0
 
123
                || !FD_ISSET(fd, &rfds))
 
124
                    return ret;
 
125
            ret = recv(fd, ptr, nbyte, 0);
 
126
            if (ret < 0) {
 
127
                    if (errno == EINTR)
 
128
                            continue;
 
129
                    return (ret);
 
130
            } else if (ret == 0) {
 
131
                    return (ptr - buf);
 
132
            }
 
133
    }
 
134
 
 
135
    return (ptr - buf);
 
136
}
 
137
 
 
138
 
 
139
static int write_all(int fd, char *buf, unsigned int nbyte)
 
140
{
 
141
    int     ret;
 
142
    char   *ptr;
 
143
 
 
144
    for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
 
145
        ret = send(fd, ptr, nbyte, 0);
 
146
        if (ret < 0) {
 
147
            if (errno == EINTR)
 
148
                continue;
 
149
            return (ret);
 
150
        } else if (ret == 0) {
 
151
            return (ptr - buf);
 
152
        }
 
153
    }
 
154
 
 
155
    return (ptr - buf);
 
156
}
 
157
 
 
158
 
 
159
static int recv_token(int s, gss_buffer_t tok)
 
160
{
 
161
        int ret;
 
162
        unsigned char lenbuf[4];
 
163
        unsigned int len;
 
164
 
 
165
        ret = read_all(s, (char *) lenbuf, 4);
 
166
        if (ret < 0) {
 
167
                errmsg.LogError(NO_ERRCODE, "GSS-API error reading token length");
 
168
                return -1;
 
169
        } else if (!ret) {
 
170
                return 0;
 
171
        } else if (ret != 4) {
 
172
                errmsg.LogError(NO_ERRCODE, "GSS-API error reading token length");
 
173
                return -1;
 
174
        }
 
175
 
 
176
        len = ((lenbuf[0] << 24)
 
177
               | (lenbuf[1] << 16)
 
178
               | (lenbuf[2] << 8)
 
179
               | lenbuf[3]);
 
180
        tok->length = ntohl(len);
 
181
 
 
182
        tok->value = (char *) malloc(tok->length ? tok->length : 1);
 
183
        if (tok->length && tok->value == NULL) {
 
184
                errmsg.LogError(NO_ERRCODE, "Out of memory allocating token data\n");
 
185
                return -1;
 
186
        }
 
187
 
 
188
        ret = read_all(s, (char *) tok->value, tok->length);
 
189
        if (ret < 0) {
 
190
                errmsg.LogError(NO_ERRCODE, "GSS-API error reading token data");
 
191
                free(tok->value);
 
192
                return -1;
 
193
        } else if (ret != (int) tok->length) {
 
194
                errmsg.LogError(NO_ERRCODE, "GSS-API error reading token data");
 
195
                free(tok->value);
 
196
                return -1;
 
197
        }
 
198
 
 
199
        return 1;
 
200
}
 
201
 
 
202
 
 
203
static int send_token(int s, gss_buffer_t tok)
 
204
{
 
205
        int     ret;
 
206
        unsigned char lenbuf[4];
 
207
        unsigned int len;
 
208
 
 
209
        if (tok->length > 0xffffffffUL)
 
210
                abort();  /* TODO: we need to reconsider this, abort() is not really a solution - degrade, but keep running */
 
211
        len = htonl(tok->length);
 
212
        lenbuf[0] = (len >> 24) & 0xff;
 
213
        lenbuf[1] = (len >> 16) & 0xff;
 
214
        lenbuf[2] = (len >> 8) & 0xff;
 
215
        lenbuf[3] = len & 0xff;
 
216
 
 
217
        ret = write_all(s, (char *) lenbuf, 4);
 
218
        if (ret < 0) {
 
219
                errmsg.LogError(NO_ERRCODE, "GSS-API error sending token length");
 
220
                return -1;
 
221
        } else if (ret != 4) {
 
222
                errmsg.LogError(NO_ERRCODE, "GSS-API error sending token length");
 
223
                return -1;
 
224
        }
 
225
 
 
226
        ret = write_all(s, tok->value, tok->length);
 
227
        if (ret < 0) {
 
228
                errmsg.LogError(NO_ERRCODE, "GSS-API error sending token data");
 
229
                return -1;
 
230
        } else if (ret != (int) tok->length) {
 
231
                errmsg.LogError(NO_ERRCODE, "GSS-API error sending token data");
 
232
                return -1;
 
233
        }
 
234
 
 
235
        return 0;
 
236
}
 
237
 
 
238
 
 
239
/* queryInterface function
 
240
 * rgerhards, 2008-02-29
 
241
 */
 
242
BEGINobjQueryInterface(gssutil)
 
243
CODESTARTobjQueryInterface(gssutil)
 
244
        if(pIf->ifVersion != gssutilCURR_IF_VERSION) { /* check for current version, increment on each change */
 
245
                ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
 
246
        }
 
247
 
 
248
        /* ok, we have the right interface, so let's fill it
 
249
         * Please note that we may also do some backwards-compatibility
 
250
         * work here (if we can support an older interface version - that,
 
251
         * of course, also affects the "if" above).
 
252
         */
 
253
        pIf->recv_token = recv_token;
 
254
        pIf->send_token = send_token;
 
255
        pIf->display_status = display_status;
 
256
        pIf->display_ctx_flags = display_ctx_flags;
 
257
 
 
258
finalize_it:
 
259
ENDobjQueryInterface(gssutil)
 
260
 
 
261
 
 
262
/* exit our class
 
263
 * rgerhards, 2008-03-10
 
264
 */
 
265
BEGINObjClassExit(gssutil, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
 
266
CODESTARTObjClassExit(gssutil)
 
267
        /* release objects we no longer need */
 
268
        objRelease(errmsg, CORE_COMPONENT);
 
269
ENDObjClassExit(gssutil)
 
270
 
 
271
 
 
272
/* Initialize our class. Must be called as the very first method
 
273
 * before anything else is called inside this class.
 
274
 * rgerhards, 2008-02-29
 
275
 */
 
276
BEGINAbstractObjClassInit(gssutil, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
 
277
        /* request objects we use */
 
278
        CHKiRet(objUse(errmsg, CORE_COMPONENT));
 
279
ENDObjClassInit(gssutil)
 
280
 
 
281
 
 
282
/* --------------- here now comes the plumbing that makes as a library module --------------- */
 
283
 
 
284
 
 
285
BEGINmodExit
 
286
CODESTARTmodExit
 
287
        gssutilClassExit();
 
288
ENDmodExit
 
289
 
 
290
 
 
291
BEGINqueryEtryPt
 
292
CODESTARTqueryEtryPt
 
293
CODEqueryEtryPt_STD_LIB_QUERIES
 
294
ENDqueryEtryPt
 
295
 
 
296
 
 
297
BEGINmodInit()
 
298
CODESTARTmodInit
 
299
        *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
 
300
 
 
301
        /* Initialize all classes that are in our module - this includes ourselfs */
 
302
        CHKiRet(gssutilClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
 
303
ENDmodInit