~ubuntu-branches/ubuntu/vivid/heimdal/vivid

« back to all changes in this revision

Viewing changes to .pc/051_bug746486-memleak/kdc/process.c

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij, Jelmer Vernooij, Andreas Beckmann
  • Date: 2014-08-25 13:52:44 UTC
  • mfrom: (48.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140825135244-fe8tmm2lf8zskslw
Tags: 1.6~rc2+dfsg-9
[ Jelmer Vernooij ]
* Add 051_bug746486-memleak: cherry-pick memory leak fix in KDC from
  upstream. Thanks GALAMBOS Daniel. Closes: #746486
* Add Turkish debconf translation. Thanks Mert Dirik. Closes: #759877

[ Andreas Beckmann ]
* heimdal-clients.postinst: Cleanup obsolete telnet, rsh and pop
  alternatives.  (Closes: #768243)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
 
3
 * (Royal Institute of Technology, Stockholm, Sweden).
 
4
 *
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions
 
9
 * are met:
 
10
 *
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *    notice, this list of conditions and the following disclaimer.
 
13
 *
 
14
 * 2. Redistributions in binary form must reproduce the above copyright
 
15
 *    notice, this list of conditions and the following disclaimer in the
 
16
 *    documentation and/or other materials provided with the distribution.
 
17
 *
 
18
 * 3. Neither the name of the Institute nor the names of its contributors
 
19
 *    may be used to endorse or promote products derived from this software
 
20
 *    without specific prior written permission.
 
21
 *
 
22
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
32
 * SUCH DAMAGE.
 
33
 */
 
34
 
 
35
#include "kdc_locl.h"
 
36
 
 
37
/*
 
38
 *
 
39
 */
 
40
 
 
41
void
 
42
krb5_kdc_update_time(struct timeval *tv)
 
43
{
 
44
    if (tv == NULL)
 
45
        gettimeofday(&_kdc_now, NULL);
 
46
    else
 
47
        _kdc_now = *tv;
 
48
}
 
49
 
 
50
static krb5_error_code
 
51
kdc_as_req(krb5_context context,
 
52
           krb5_kdc_configuration *config,
 
53
           krb5_data *req_buffer,
 
54
           krb5_data *reply,
 
55
           const char *from,
 
56
           struct sockaddr *addr,
 
57
           int datagram_reply,
 
58
           int *claim)
 
59
{
 
60
    struct kdc_request_desc r;
 
61
    krb5_error_code ret;
 
62
    size_t len;
 
63
 
 
64
    memset(&r, 0, sizeof(r));
 
65
 
 
66
    ret = decode_AS_REQ(req_buffer->data, req_buffer->length, &r.req, &len);
 
67
    if (ret)
 
68
        return ret;
 
69
 
 
70
    r.context = context;
 
71
    r.config = config;
 
72
    r.request.data = req_buffer->data;
 
73
    r.request.length = req_buffer->length;
 
74
 
 
75
    *claim = 1;
 
76
 
 
77
    ret = _kdc_as_rep(&r, reply, from, addr, datagram_reply);
 
78
    free_AS_REQ(&r.req);
 
79
    return ret;
 
80
}
 
81
 
 
82
 
 
83
static krb5_error_code
 
84
kdc_tgs_req(krb5_context context,
 
85
            krb5_kdc_configuration *config,
 
86
            krb5_data *req_buffer,
 
87
            krb5_data *reply,
 
88
            const char *from,
 
89
            struct sockaddr *addr,
 
90
            int datagram_reply,
 
91
            int *claim)
 
92
{
 
93
    krb5_error_code ret;
 
94
    KDC_REQ req;
 
95
    size_t len;
 
96
 
 
97
    ret = decode_TGS_REQ(req_buffer->data, req_buffer->length, &req, &len);
 
98
    if (ret)
 
99
        return ret;
 
100
 
 
101
    *claim = 1;
 
102
 
 
103
    ret = _kdc_tgs_rep(context, config, &req, reply,
 
104
                       from, addr, datagram_reply);
 
105
    free_TGS_REQ(&req);
 
106
    return ret;
 
107
}
 
108
 
 
109
#ifdef DIGEST
 
110
 
 
111
static krb5_error_code
 
112
kdc_digest(krb5_context context,
 
113
           krb5_kdc_configuration *config,
 
114
           krb5_data *req_buffer,
 
115
           krb5_data *reply,
 
116
           const char *from,
 
117
           struct sockaddr *addr,
 
118
           int datagram_reply,
 
119
           int *claim)
 
120
{
 
121
    DigestREQ digestreq;
 
122
    krb5_error_code ret;
 
123
    size_t len;
 
124
 
 
125
    ret = decode_DigestREQ(req_buffer->data, req_buffer->length,
 
126
                           &digestreq, &len);
 
127
    if (ret)
 
128
        return ret;
 
129
 
 
130
    *claim = 1;
 
131
 
 
132
    ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
 
133
    free_DigestREQ(&digestreq);
 
134
    return ret;
 
135
}
 
136
 
 
137
#endif
 
138
 
 
139
#ifdef KX509
 
140
 
 
141
static krb5_error_code
 
142
kdc_kx509(krb5_context context,
 
143
          krb5_kdc_configuration *config,
 
144
          krb5_data *req_buffer,
 
145
          krb5_data *reply,
 
146
          const char *from,
 
147
          struct sockaddr *addr,
 
148
          int datagram_reply,
 
149
          int *claim)
 
150
{
 
151
    Kx509Request kx509req;
 
152
    krb5_error_code ret;
 
153
    size_t len;
 
154
 
 
155
    ret = _kdc_try_kx509_request(req_buffer->data, req_buffer->length,
 
156
                                 &kx509req, &len);
 
157
    if (ret)
 
158
        return ret;
 
159
 
 
160
    *claim = 1;
 
161
 
 
162
    ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
 
163
    free_Kx509Request(&kx509req);
 
164
    return ret;
 
165
}
 
166
 
 
167
#endif
 
168
 
 
169
 
 
170
static struct krb5_kdc_service services[] =  {
 
171
    { KS_KRB5,          kdc_as_req },
 
172
    { KS_KRB5,          kdc_tgs_req },
 
173
#ifdef DIGEST
 
174
    { 0,                kdc_digest },
 
175
#endif
 
176
#ifdef KX509
 
177
    { 0,                kdc_kx509 },
 
178
#endif
 
179
    { 0, NULL }
 
180
};
 
181
 
 
182
/*
 
183
 * handle the request in `buf, len', from `addr' (or `from' as a string),
 
184
 * sending a reply in `reply'.
 
185
 */
 
186
 
 
187
int
 
188
krb5_kdc_process_request(krb5_context context,
 
189
                         krb5_kdc_configuration *config,
 
190
                         unsigned char *buf,
 
191
                         size_t len,
 
192
                         krb5_data *reply,
 
193
                         krb5_boolean *prependlength,
 
194
                         const char *from,
 
195
                         struct sockaddr *addr,
 
196
                         int datagram_reply)
 
197
{
 
198
    krb5_error_code ret;
 
199
    unsigned int i;
 
200
    krb5_data req_buffer;
 
201
    int claim = 0;
 
202
    heim_auto_release_t pool = heim_auto_release_create();
 
203
 
 
204
    req_buffer.data = buf;
 
205
    req_buffer.length = len;
 
206
 
 
207
    for (i = 0; services[i].process != NULL; i++) {
 
208
        ret = (*services[i].process)(context, config, &req_buffer,
 
209
                                     reply, from, addr, datagram_reply,
 
210
                                     &claim);
 
211
        if (claim) {
 
212
            if (services[i].flags & KS_NO_LENGTH)
 
213
                *prependlength = 0;
 
214
 
 
215
            heim_auto_release_drain(pool);
 
216
            return ret;
 
217
        }
 
218
    }
 
219
 
 
220
    heim_auto_release_drain(pool);
 
221
 
 
222
    return -1;
 
223
}
 
224
 
 
225
/*
 
226
 * handle the request in `buf, len', from `addr' (or `from' as a string),
 
227
 * sending a reply in `reply'.
 
228
 *
 
229
 * This only processes krb5 requests
 
230
 */
 
231
 
 
232
int
 
233
krb5_kdc_process_krb5_request(krb5_context context,
 
234
                              krb5_kdc_configuration *config,
 
235
                              unsigned char *buf,
 
236
                              size_t len,
 
237
                              krb5_data *reply,
 
238
                              const char *from,
 
239
                              struct sockaddr *addr,
 
240
                              int datagram_reply)
 
241
{
 
242
    krb5_error_code ret;
 
243
    unsigned int i;
 
244
    krb5_data req_buffer;
 
245
    int claim = 0;
 
246
 
 
247
    req_buffer.data = buf;
 
248
    req_buffer.length = len;
 
249
 
 
250
    for (i = 0; services[i].process != NULL; i++) {
 
251
        if ((services[i].flags & KS_KRB5) == 0)
 
252
            continue;
 
253
        ret = (*services[i].process)(context, config, &req_buffer,
 
254
                                     reply, from, addr, datagram_reply,
 
255
                                     &claim);
 
256
        if (claim)
 
257
            return ret;
 
258
    }
 
259
 
 
260
    return -1;
 
261
}
 
262
 
 
263
/*
 
264
 *
 
265
 */
 
266
 
 
267
int
 
268
krb5_kdc_save_request(krb5_context context,
 
269
                      const char *fn,
 
270
                      const unsigned char *buf,
 
271
                      size_t len,
 
272
                      const krb5_data *reply,
 
273
                      const struct sockaddr *sa)
 
274
{
 
275
    krb5_storage *sp;
 
276
    krb5_address a;
 
277
    int fd, ret;
 
278
    uint32_t t;
 
279
    krb5_data d;
 
280
 
 
281
    memset(&a, 0, sizeof(a));
 
282
 
 
283
    d.data = rk_UNCONST(buf);
 
284
    d.length = len;
 
285
    t = _kdc_now.tv_sec;
 
286
 
 
287
    fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600);
 
288
    if (fd < 0) {
 
289
        int saved_errno = errno;
 
290
        krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn);
 
291
        return saved_errno;
 
292
    }
 
293
 
 
294
    sp = krb5_storage_from_fd(fd);
 
295
    close(fd);
 
296
    if (sp == NULL) {
 
297
        krb5_set_error_message(context, ENOMEM, "Storage failed to open fd");
 
298
        return ENOMEM;
 
299
    }
 
300
 
 
301
    ret = krb5_sockaddr2address(context, sa, &a);
 
302
    if (ret)
 
303
        goto out;
 
304
 
 
305
    krb5_store_uint32(sp, 1);
 
306
    krb5_store_uint32(sp, t);
 
307
    krb5_store_address(sp, a);
 
308
    krb5_store_data(sp, d);
 
309
    {
 
310
        Der_class cl;
 
311
        Der_type ty;
 
312
        unsigned int tag;
 
313
        ret = der_get_tag (reply->data, reply->length,
 
314
                           &cl, &ty, &tag, NULL);
 
315
        if (ret) {
 
316
            krb5_store_uint32(sp, 0xffffffff);
 
317
            krb5_store_uint32(sp, 0xffffffff);
 
318
        } else {
 
319
            krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0));
 
320
            krb5_store_uint32(sp, tag);
 
321
        }
 
322
    }
 
323
 
 
324
    krb5_free_address(context, &a);
 
325
out:
 
326
    krb5_storage_free(sp);
 
327
 
 
328
    return 0;
 
329
}