~ubuntu-branches/ubuntu/oneiric/jabberd2/oneiric-security

« back to all changes in this revision

Viewing changes to sm/sm.c

  • Committer: Bazaar Package Importer
  • Author(s): Nicolai Spohrer
  • Date: 2008-08-12 16:13:43 UTC
  • mfrom: (1.1.3 upstream) (0.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20080812161343-6trz3r97dtevxd17
Tags: 2.2.1-1ubuntu1
* Merge with Debian unstable (LP: #257130), remaining changes:
  - debian/control:
    + Modify Maintainer field as per spec
    + Depend on libdb4.6-dev instead of libdb4.4-dev
    + Added Conflicts and Replaces: ..., jabber for jabberd2
  - debian/rules: Added libtoolize call (jabberd2 ships with
     an older ltmain.sh version that conflicts with the
     current libtool version)
  - debian/init: create /var/run/jabber directory with correct
     permissions
* Dropped changes:
  - Debian already depends on libpq-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
/** @file sm/sm.c
24
24
  * @brief stream / io callbacks
25
25
  * @author Robert Norris
26
 
  * $Date: 2005/01/07 11:46:52 $
27
 
  * $Revision: 1.41.2.5 $
 
26
  * $Date: 2005/08/17 07:48:28 $
 
27
  * $Revision: 1.51 $
28
28
  */
29
29
 
 
30
sig_atomic_t sm_lost_router = 0;
 
31
 
30
32
/** our master callback */
31
33
int sm_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
32
34
    sm_t sm = (sm_t) arg;
48
50
            break;
49
51
 
50
52
        case event_READ:
51
 
            log_debug(ZONE, "reading from %d", sm->fd);
 
53
            log_debug(ZONE, "reading from %d", sm->fd->fd);
52
54
 
53
55
            /* do the read */
54
 
            len = recv(sm->fd, buf->data, buf->len, 0);
 
56
            len = recv(sm->fd->fd, buf->data, buf->len, 0);
55
57
 
56
 
            if(len < 0) {
57
 
                if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN) {
 
58
            if (len < 0) {
 
59
                if (MIO_WOULDBLOCK) {
58
60
                    buf->len = 0;
59
61
                    return 0;
60
62
                }
61
63
 
62
 
                log_write(sm->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", sm->fd, strerror(errno), errno);
 
64
                log_write(sm->log, LOG_NOTICE, "[%d] [router] read error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
63
65
 
64
66
                sx_kill(s);
65
67
                
66
68
                return -1;
67
69
            }
68
70
 
69
 
            else if(len == 0) {
 
71
            else if (len == 0) {
70
72
                /* they went away */
71
73
                sx_kill(s);
72
74
 
80
82
            return len;
81
83
 
82
84
        case event_WRITE:
83
 
            log_debug(ZONE, "writing to %d", sm->fd);
 
85
            log_debug(ZONE, "writing to %d", sm->fd->fd);
84
86
 
85
 
            len = send(sm->fd, buf->data, buf->len, 0);
86
 
            if(len >= 0) {
 
87
            len = send(sm->fd->fd, buf->data, buf->len, 0);
 
88
            if (len >= 0) {
87
89
                log_debug(ZONE, "%d bytes written", len);
88
90
                return len;
89
91
            }
90
92
 
91
 
            if(errno == EWOULDBLOCK || errno == EINTR || errno == EAGAIN)
 
93
            if (MIO_WOULDBLOCK)
92
94
                return 0;
93
95
 
94
 
            log_write(sm->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", sm->fd, strerror(errno), errno);
 
96
            log_write(sm->log, LOG_NOTICE, "[%d] [router] write error: %s (%d)", sm->fd->fd, MIO_STRERROR(MIO_ERROR), MIO_ERROR);
95
97
 
96
98
            sx_kill(s);
97
99
 
130
132
            nad = (nad_t) data;
131
133
 
132
134
            /* drop unqualified packets */
133
 
            if(NAD_ENS(nad, 0) < 0) {
 
135
            if (NAD_ENS(nad, 0) < 0) {
134
136
                nad_free(nad);
135
137
                return 0;
136
138
            }
137
139
            /* watch for the features packet */
138
 
            if(s->state == state_STREAM) {
139
 
                if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_STREAMS) || strncmp(uri_STREAMS, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_STREAMS)) != 0 || NAD_ENAME_L(nad, 0) != 8 || strncmp("features", NAD_ENAME(nad, 0), 8) != 0) {
 
140
            if (s->state == state_STREAM) {
 
141
                if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_STREAMS)
 
142
                    || strncmp(uri_STREAMS, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_STREAMS)) != 0
 
143
                    || NAD_ENAME_L(nad, 0) != 8 || strncmp("features", NAD_ENAME(nad, 0), 8) != 0) {
140
144
                    log_debug(ZONE, "got a non-features packet on an unauth'd stream, dropping");
141
145
                    nad_free(nad);
142
146
                    return 0;
144
148
 
145
149
#ifdef HAVE_SSL
146
150
                /* starttls if we can */
147
 
                if(sm->sx_ssl != NULL && s->ssf == 0) {
 
151
                if (sm->sx_ssl != NULL && s->ssf == 0) {
148
152
                    ns = nad_find_scoped_namespace(nad, uri_TLS, NULL);
149
 
                    if(ns >= 0) {
 
153
                    if (ns >= 0) {
150
154
                        elem = nad_find_elem(nad, 0, ns, "starttls", 1);
151
 
                        if(elem >= 0) {
152
 
                            if(sx_ssl_client_starttls(sm->sx_ssl, s, NULL) == 0) {
 
155
                        if (elem >= 0) {
 
156
                            if (sx_ssl_client_starttls(sm->sx_ssl, s, NULL) == 0) {
153
157
                                nad_free(nad);
154
158
                                return 0;
155
159
                            }
163
167
                 *     if there isn't an appropriate one, error and bail */
164
168
 
165
169
                /* authenticate */
166
 
                sx_sasl_auth(sm->sx_sasl, s, "DIGEST-MD5", sm->router_user, sm->router_pass, NULL);
 
170
                sx_sasl_auth(sm->sx_sasl, s, "jabberd-router", "DIGEST-MD5", sm->router_user, sm->router_pass);
167
171
 
168
172
                nad_free(nad);
169
173
                return 0;
170
174
            }
171
175
 
172
176
            /* watch for the bind response */
173
 
            if(s->state == state_OPEN && !sm->online) {
174
 
                if(NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT) || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0 || NAD_ENAME_L(nad, 0) != 4 || strncmp("bind", NAD_ENAME(nad, 0), 4)) {
 
177
            if (s->state == state_OPEN && !sm->online) {
 
178
                if (NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT)
 
179
                    || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0
 
180
                    || NAD_ENAME_L(nad, 0) != 4 || strncmp("bind", NAD_ENAME(nad, 0), 4)) {
175
181
                    log_debug(ZONE, "got a packet from router, but we're not online, dropping");
176
182
                    nad_free(nad);
177
183
                    return 0;
197
203
            log_debug(ZONE, "got a packet");
198
204
 
199
205
            pkt = pkt_new(sm, (nad_t) data);
200
 
            if(pkt == NULL) {
 
206
            if (pkt == NULL) {
201
207
                log_debug(ZONE, "invalid packet, dropping");
202
208
 
203
209
                nad_free(nad);
211
217
 
212
218
        case event_CLOSED:
213
219
            mio_close(sm->mio, sm->fd);
214
 
            break;
 
220
            return -1;
215
221
    }
216
222
 
217
223
    return 0;
218
224
}
219
225
 
220
 
int sm_mio_callback(mio_t m, mio_action_t a, int fd, void *data, void *arg) {
 
226
int sm_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) {
221
227
    sm_t sm = (sm_t) arg;
222
228
    int nbytes;
223
229
 
224
 
    switch(a) {
 
230
    switch (a) {
225
231
        case action_READ:
226
 
            log_debug(ZONE, "read action on fd %d", fd);
 
232
            log_debug(ZONE, "read action on fd %d", fd->fd);
227
233
 
228
 
            ioctl(fd, FIONREAD, &nbytes);
 
234
            ioctl(fd->fd, FIONREAD, &nbytes);
229
235
            if(nbytes == 0) {
230
236
                sx_kill(sm->router);
231
237
                return 0;
234
240
            return sx_can_read(sm->router);
235
241
 
236
242
        case action_WRITE:
237
 
            log_debug(ZONE, "write action on fd %d", fd);
 
243
            log_debug(ZONE, "write action on fd %d", fd->fd);
238
244
            return sx_can_write(sm->router);
239
245
 
240
246
        case action_CLOSE:
241
 
            log_debug(ZONE, "close action on fd %d", fd);
 
247
            log_debug(ZONE, "close action on fd %d", fd->fd);
242
248
            log_write(sm->log, LOG_NOTICE, "connection to router closed");
243
249
 
244
250
            sm_lost_router = 1;
255
261
    return 0;
256
262
}
257
263
 
258
 
/** this was jutil_timestamp in a former life */
259
 
void sm_timestamp(time_t t, char timestamp[18])
260
 
{
261
 
    struct tm *gm = gmtime(&t);
262
 
 
263
 
    snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900 + gm->tm_year,
264
 
             gm->tm_mon + 1, gm->tm_mday, gm->tm_hour, gm->tm_min, gm->tm_sec);
265
 
 
266
 
    return;
267
 
}
268
 
 
269
264
/** send a new action route */
270
265
void sm_c2s_action(sess_t dest, char *action, char *target) {
271
266
    nad_t nad;
282
277
    sns = nad_add_namespace(nad, uri_SESSION, "sc");
283
278
    nad_append_elem(nad, sns, "session", 1);
284
279
 
285
 
    if(dest->c2s_id[0] != '\0')
 
280
    if (dest->c2s_id[0] != '\0')
286
281
        nad_append_attr(nad, sns, "c2s", dest->c2s_id);
287
 
    if(dest->sm_id[0] != '\0')
 
282
    if (dest->sm_id[0] != '\0')
288
283
        nad_append_attr(nad, sns, "sm", dest->sm_id);
289
284
 
290
285
    nad_append_attr(nad, -1, "action", action);
291
 
    if(target != NULL)
 
286
    if (target != NULL)
292
287
        nad_append_attr(nad, -1, "target", target);
293
288
 
294
 
    log_debug(ZONE, "routing nad to %s from %s c2s %s s2s %s action %s target %s", dest->c2s, dest->user->sm->id, dest->c2s_id, dest->sm_id, action, target);
 
289
    log_debug(ZONE,
 
290
              "routing nad to %s from %s c2s %s s2s %s action %s target %s",
 
291
              dest->c2s, dest->user->sm->id, dest->c2s_id, dest->sm_id,
 
292
              action, target);
295
293
 
296
294
    sx_nad_write(dest->user->sm->router, nad);
297
295
}
298
296
 
299
297
/** this is gratuitous, but apache gets one, so why not? */
300
298
void sm_signature(sm_t sm, char *str) {
301
 
    if(sm->siglen == 0) {
 
299
    if (sm->siglen == 0) {
302
300
        snprintf(&sm->signature[sm->siglen], 2048 - sm->siglen, "%s", str);
303
301
        sm->siglen += strlen(str);
304
302
    } else {
306
304
        sm->siglen += strlen(str) + 1;
307
305
    }
308
306
}
 
307
 
 
308
/** register a new global ns */
 
309
int sm_register_ns(sm_t sm, char *uri) {
 
310
    int ns_idx;
 
311
 
 
312
    ns_idx = (int) xhash_get(sm->xmlns, uri);
 
313
    if (ns_idx == 0) {
 
314
        ns_idx = xhash_count(sm->xmlns) + 2;
 
315
        xhash_put(sm->xmlns, pstrdup(xhash_pool(sm->xmlns), uri), (void *) ns_idx);
 
316
    }
 
317
    xhash_put(sm->xmlns_refcount, uri, (void *) ((int) xhash_get(sm->xmlns_refcount, uri) + 1));
 
318
 
 
319
    return ns_idx;
 
320
}
 
321
 
 
322
/** unregister a global ns */
 
323
void sm_unregister_ns(sm_t sm, char *uri) {
 
324
    int refcount = (int) xhash_get(sm->xmlns_refcount, uri);
 
325
    if (refcount == 1) {
 
326
        xhash_zap(sm->xmlns, uri);
 
327
        xhash_zap(sm->xmlns_refcount, uri);
 
328
    } else if (refcount > 1) {
 
329
        xhash_put(sm->xmlns_refcount, uri, (void *) ((int) xhash_get(sm->xmlns_refcount, uri) - 1));
 
330
    }
 
331
}
 
332
 
 
333
/** get a globally registered ns */
 
334
int sm_get_ns(sm_t sm, char *uri) {
 
335
    return (int) xhash_get(sm->xmlns, uri);
 
336
}
 
337