Annotation of embedaddon/ipsec-tools/src/racoon/evt.c, revision 1.1.1.1.2.1

1.1       misho       1: /*     $NetBSD: evt.c,v 1.10 2010/10/21 06:15:28 tteras Exp $  */
                      2: 
                      3: /* Id: evt.c,v 1.5 2006/06/22 20:11:35 manubsd Exp */
                      4: 
                      5: /*
                      6:  * Copyright (C) 2004 Emmanuel Dreyfus
                      7:  * Copyright (C) 2008 Timo Teras
                      8:  * All rights reserved.
                      9:  * 
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the project 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 PROJECT 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 PROJECT 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 "config.h"
                     36: 
                     37: #include <errno.h>
                     38: #include <string.h>
                     39: #include <stdio.h>
                     40: #include <time.h>
                     41: #include <unistd.h>
                     42: #include <stdlib.h>
                     43: #include <sys/queue.h>
                     44: #include <sys/socket.h>
                     45: 
                     46: #include "vmbuf.h"
                     47: #include "plog.h"
                     48: #include "misc.h"
                     49: #include "admin.h"
                     50: #include "handler.h"
                     51: #include "session.h"
                     52: #include "gcmalloc.h"
                     53: #include "evt.h"
                     54: #include "var.h"
                     55: 
                     56: #ifdef ENABLE_ADMINPORT
                     57: 
                     58: static EVT_LISTENER_LIST(evt_listeners);
                     59: 
                     60: struct evt_message {
                     61:        struct admin_com adm;
                     62:        struct evt_async evt;
                     63: };
                     64: 
                     65: struct evt {
                     66:        struct evtdump *dump;
                     67:        TAILQ_ENTRY(evt) next;
                     68: };
                     69: 
                     70: TAILQ_HEAD(evtlist, evt);
                     71: 
                     72: #define EVTLIST_MAX    32
                     73: 
                     74: static struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
                     75: static int evtlist_len = 0;
                     76: static int evtlist_inuse = 0;
                     77: 
                     78: static struct {
                     79:        int newtype, oldtype;
                     80: } evttype_map[] = {
                     81:        { EVT_RACOON_QUIT,              EVTT_RACOON_QUIT },
                     82:        { EVT_PHASE1_UP,                EVTT_PHASE1_UP },
                     83:        { EVT_PHASE1_DOWN,              EVTT_PHASE1_DOWN },
                     84:        { EVT_PHASE1_NO_RESPONSE,       EVTT_PEER_NO_RESPONSE },
                     85:        { EVT_PHASE1_NO_PROPOSAL,       EVTT_PEERPH1_NOPROP },
                     86:        { EVT_PHASE1_AUTH_FAILED,       EVTT_PEERPH1AUTH_FAILED },
                     87:        { EVT_PHASE1_DPD_TIMEOUT,       EVTT_DPD_TIMEOUT },
                     88:        { EVT_PHASE1_PEER_DELETED,      EVTT_PEER_DELETE },
                     89:        { EVT_PHASE1_MODE_CFG,          EVTT_ISAKMP_CFG_DONE },
                     90:        { EVT_PHASE1_XAUTH_SUCCESS,     EVTT_XAUTH_SUCCESS },
                     91:        { EVT_PHASE1_XAUTH_FAILED,      EVTT_XAUTH_FAILED },
                     92:        { EVT_PHASE2_NO_PHASE1,         -1 },
                     93:        { EVT_PHASE2_UP,                EVTT_PHASE2_UP },
                     94:        { EVT_PHASE2_DOWN,              EVTT_PHASE2_DOWN },
                     95:        { EVT_PHASE2_NO_RESPONSE,       EVTT_PEER_NO_RESPONSE },
                     96: };
                     97: 
                     98: static void
                     99: evt_push(src, dst, type, optdata)
                    100:        struct sockaddr *src;
                    101:        struct sockaddr *dst;
                    102:        int type;
                    103:        vchar_t *optdata;
                    104: {
                    105:        struct evtdump *evtdump;
                    106:        struct evt *evt;
                    107:        size_t len;
                    108:        int i;
                    109: 
                    110:        /* If admin socket is disabled, silently discard anything */
                    111:        if (adminsock_path == NULL || !evtlist_inuse)
                    112:                return;
                    113: 
                    114:        /* Map the event type to old */
                    115:        for (i = 0; i < sizeof(evttype_map) / sizeof(evttype_map[0]); i++)
                    116:                if (evttype_map[i].newtype == type)
                    117:                        break;
                    118:        if (i >= sizeof(evttype_map) / sizeof(evttype_map[0]))
                    119:                return;
                    120: 
                    121:        type = evttype_map[i].oldtype;
                    122:        if (type < 0)
                    123:                return;
                    124: 
                    125:        /* If we are above the limit, don't record anything */
                    126:        if (evtlist_len > EVTLIST_MAX) {
                    127:                plog(LLV_DEBUG, LOCATION, NULL, 
                    128:                    "Cannot record event: event queue overflowed\n");
                    129:                return;
                    130:        }
                    131: 
                    132:        /* If we hit the limit, record an overflow event instead */
                    133:        if (evtlist_len == EVTLIST_MAX) {
                    134:                plog(LLV_ERROR, LOCATION, NULL, 
                    135:                    "Cannot record event: event queue overflow\n");
                    136:                src = NULL;
                    137:                dst = NULL;
                    138:                type = EVTT_OVERFLOW;
                    139:                optdata = NULL;
                    140:        }
                    141: 
                    142:        len = sizeof(*evtdump);
                    143:        if (optdata)
                    144:                len += optdata->l;
                    145: 
                    146:        if ((evtdump = racoon_malloc(len)) == NULL) {
                    147:                plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
                    148:                    strerror(errno));
                    149:                return;
                    150:        }
                    151: 
                    152:        if ((evt = racoon_malloc(sizeof(*evt))) == NULL) {
                    153:                plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
                    154:                    strerror(errno));
                    155:                racoon_free(evtdump);
                    156:                return;
                    157:        }
                    158: 
                    159:        if (src)
                    160:                memcpy(&evtdump->src, src, sysdep_sa_len(src));
                    161:        if (dst)
                    162:                memcpy(&evtdump->dst, dst, sysdep_sa_len(dst));
                    163:        evtdump->len = len;
                    164:        evtdump->type = type;
                    165:        time(&evtdump->timestamp);
                    166: 
                    167:        if (optdata)
                    168:                memcpy(evtdump + 1, optdata->v, optdata->l);
                    169: 
                    170:        evt->dump = evtdump;
                    171:        TAILQ_INSERT_TAIL(&evtlist, evt, next);
                    172: 
                    173:        evtlist_len++;
                    174: 
                    175:        return;
                    176: }
                    177: 
                    178: static struct evtdump *
                    179: evt_pop(void) {
                    180:        struct evtdump *evtdump;
                    181:        struct evt *evt;
                    182: 
                    183:        if ((evt = TAILQ_FIRST(&evtlist)) == NULL)
                    184:                return NULL;
                    185: 
                    186:        evtdump = evt->dump;
                    187:        TAILQ_REMOVE(&evtlist, evt, next);
                    188:        racoon_free(evt);
                    189:        evtlist_len--;
                    190: 
                    191:        return evtdump;
                    192: }
                    193: 
                    194: vchar_t *
                    195: evt_dump(void) {
                    196:        struct evtdump *evtdump;
                    197:        vchar_t *buf = NULL;
                    198: 
                    199:        if (!evtlist_inuse) {
                    200:                evtlist_inuse = 1;
                    201:                plog(LLV_ERROR, LOCATION, NULL,
                    202:                     "evt_dump: deprecated event polling used\n");
                    203:        }
                    204: 
                    205:        if ((evtdump = evt_pop()) != NULL) {
                    206:                if ((buf = vmalloc(evtdump->len)) == NULL) {
                    207:                        plog(LLV_ERROR, LOCATION, NULL, 
                    208:                            "evt_dump failed: %s\n", strerror(errno));
                    209:                        return NULL;
                    210:                }
                    211:                memcpy(buf->v, evtdump, evtdump->len);  
                    212:                racoon_free(evtdump);
                    213:        }
                    214: 
                    215:        return buf;
                    216: }
                    217: 
                    218: static struct evt_message *
                    219: evtmsg_create(type, optdata)
                    220:        int type;
                    221:        vchar_t *optdata;
                    222: {
                    223:        struct evt_message *e;
                    224:        size_t len;
                    225: 
                    226:        len = sizeof(struct evt_message);
                    227:        if (optdata != NULL)
                    228:                len += optdata->l;
                    229: 
                    230:        if ((e = racoon_malloc(len)) == NULL) {
                    231:                plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate event: %s\n",
                    232:                     strerror(errno));
                    233:                return NULL;
                    234:        }
                    235: 
                    236:        memset(e, 0, sizeof(struct evt_message));
                    237:        e->adm.ac_len = len;
                    238:        e->adm.ac_cmd = ADMIN_SHOW_EVT;
                    239:        e->adm.ac_errno = 0;
                    240:        e->adm.ac_proto = 0;
                    241:        e->evt.ec_type = type;
                    242:        time(&e->evt.ec_timestamp);
                    243:        if (optdata != NULL)
                    244:                memcpy(e + 1, optdata->v, optdata->l);
                    245: 
                    246:        return e;
                    247: }
                    248: 
                    249: static void
                    250: evt_unsubscribe(l)
                    251:        struct evt_listener *l;
                    252: {
                    253:        plog(LLV_DEBUG, LOCATION, NULL,
                    254:             "[%d] admin connection released\n", l->fd);
                    255: 
                    256:        LIST_REMOVE(l, ll_chain);
                    257:        unmonitor_fd(l->fd);
                    258:        close(l->fd);
                    259:        racoon_free(l);
                    260: }
                    261: 
                    262: static int
                    263: evt_unsubscribe_cb(ctx, fd)
                    264:        void *ctx;
                    265:        int fd;
                    266: {
                    267:        evt_unsubscribe((struct evt_listener *) ctx);
                    268:        return 0;
                    269: }
                    270: 
                    271: static void
                    272: evtmsg_broadcast(ll, e)
                    273:        const struct evt_listener_list *ll;
                    274:        struct evt_message *e;
                    275: {
                    276:        struct evt_listener *l, *nl;
                    277: 
                    278:        for (l = LIST_FIRST(ll); l != NULL; l = nl) {
                    279:                nl = LIST_NEXT(l, ll_chain);
                    280: 
                    281:                if (send(l->fd, e, e->adm.ac_len, MSG_DONTWAIT) < 0) {
                    282:                        plog(LLV_DEBUG, LOCATION, NULL, "Cannot send event to fd: %s\n",
                    283:                                strerror(errno));
                    284:                        evt_unsubscribe(l);
                    285:                }
                    286:        }
                    287: }
                    288: 
                    289: void
                    290: evt_generic(type, optdata)
                    291:        int type;
                    292:        vchar_t *optdata;
                    293: {
                    294:        struct evt_message *e;
                    295: 
                    296:        if ((e = evtmsg_create(type, optdata)) == NULL)
                    297:                return;
                    298: 
                    299:        evtmsg_broadcast(&evt_listeners, e);
1.1.1.1.2.1! misho     300:        evt_push((struct sockaddr*) &e->evt.ec_ph1src, (struct sockaddr*) &e->evt.ec_ph1dst, type, optdata);
1.1       misho     301: 
                    302:        racoon_free(e);
                    303: }
                    304: 
                    305: void
                    306: evt_phase1(ph1, type, optdata)
                    307:        const struct ph1handle *ph1;
                    308:        int type;
                    309:        vchar_t *optdata;
                    310: {
                    311:        struct evt_message *e;
                    312: 
                    313:        if ((e = evtmsg_create(type, optdata)) == NULL)
                    314:                return;
                    315: 
                    316:        if (ph1->local)
                    317:                memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
                    318:        if (ph1->remote)
                    319:                memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
                    320: 
                    321:        evtmsg_broadcast(&ph1->evt_listeners, e);
                    322:        evtmsg_broadcast(&evt_listeners, e);
1.1.1.1.2.1! misho     323:        evt_push((struct sockaddr*) &e->evt.ec_ph1src, (struct sockaddr*) &e->evt.ec_ph1dst, type, optdata);
1.1       misho     324: 
                    325:        racoon_free(e);
                    326: }
                    327: 
                    328: void
                    329: evt_phase2(ph2, type, optdata)
                    330:        const struct ph2handle *ph2;
                    331:        int type;
                    332:        vchar_t *optdata;
                    333: {
                    334:        struct evt_message *e;
                    335:        struct ph1handle *ph1 = ph2->ph1;
                    336: 
                    337:        if ((e = evtmsg_create(type, optdata)) == NULL)
                    338:                return;
                    339: 
                    340:        if (ph1) {
                    341:                if (ph1->local)
                    342:                        memcpy(&e->evt.ec_ph1src, ph1->local, sysdep_sa_len(ph1->local));
                    343:                if (ph1->remote)
                    344:                        memcpy(&e->evt.ec_ph1dst, ph1->remote, sysdep_sa_len(ph1->remote));
                    345:        }
                    346:        e->evt.ec_ph2msgid = ph2->msgid;
                    347: 
                    348:        evtmsg_broadcast(&ph2->evt_listeners, e);
                    349:        if (ph1)
                    350:                evtmsg_broadcast(&ph1->evt_listeners, e);
                    351:        evtmsg_broadcast(&evt_listeners, e);
1.1.1.1.2.1! misho     352:        evt_push((struct sockaddr*) &e->evt.ec_ph1src, (struct sockaddr*) &e->evt.ec_ph1dst, type, optdata);
1.1       misho     353: 
                    354:        racoon_free(e);
                    355: }
                    356: 
                    357: int
                    358: evt_subscribe(list, fd)
                    359:        struct evt_listener_list *list;
                    360:        int fd;
                    361: {
                    362:        struct evt_listener *l;
                    363: 
                    364:        if ((l = racoon_malloc(sizeof(*l))) == NULL) {
                    365:                plog(LLV_ERROR, LOCATION, NULL,
                    366:                     "Cannot allocate event listener: %s\n",
                    367:                     strerror(errno));
                    368:                return errno;
                    369:        }
                    370: 
                    371:        if (list == NULL)
                    372:                list = &evt_listeners;
                    373: 
                    374:        LIST_INSERT_HEAD(list, l, ll_chain);
                    375:        l->fd = fd;
                    376:        monitor_fd(l->fd, evt_unsubscribe_cb, l, 0);
                    377: 
                    378:        plog(LLV_DEBUG, LOCATION, NULL,
                    379:             "[%d] admin connection is polling events\n", fd);
                    380: 
                    381:        return -2;
                    382: }
                    383: 
                    384: void
                    385: evt_list_init(list)
                    386:        struct evt_listener_list *list;
                    387: {
                    388:        LIST_INIT(list);
                    389: }
                    390: 
                    391: void
                    392: evt_list_cleanup(list)
                    393:        struct evt_listener_list *list;
                    394: {
                    395:        while (!LIST_EMPTY(list))
                    396:                evt_unsubscribe(LIST_FIRST(list));
                    397: }
                    398: 
                    399: #endif /* ENABLE_ADMINPORT */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>