Annotation of embedaddon/strongswan/src/libcharon/plugins/whitelist/whitelist_control.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2011 Martin Willi
                      3:  * Copyright (C) 2011 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "whitelist_control.h"
                     17: 
                     18: #include <sys/types.h>
                     19: #include <sys/stat.h>
                     20: #include <sys/socket.h>
                     21: #include <sys/un.h>
                     22: #include <unistd.h>
                     23: #include <errno.h>
                     24: 
                     25: #include <daemon.h>
                     26: #include <collections/linked_list.h>
                     27: 
                     28: #include "whitelist_msg.h"
                     29: 
                     30: typedef struct private_whitelist_control_t private_whitelist_control_t;
                     31: 
                     32: /**
                     33:  * Private data of an whitelist_control_t object.
                     34:  */
                     35: struct private_whitelist_control_t {
                     36: 
                     37:        /**
                     38:         * Public whitelist_control_t interface.
                     39:         */
                     40:        whitelist_control_t public;
                     41: 
                     42:        /**
                     43:         * Whitelist
                     44:         */
                     45:        whitelist_listener_t *listener;
                     46: 
                     47:        /**
                     48:         * Whitelist stream service
                     49:         */
                     50:        stream_service_t *service;
                     51: };
                     52: 
                     53: /*
                     54:  * List whitelist entries using a read-copy
                     55:  */
                     56: static void list(private_whitelist_control_t *this,
                     57:                                 stream_t *stream, identification_t *id)
                     58: {
                     59:        identification_t *current;
                     60:        enumerator_t *enumerator;
                     61:        linked_list_t *list;
                     62:        whitelist_msg_t msg = {
                     63:                .type = htonl(WHITELIST_LIST),
                     64:        };
                     65: 
                     66:        list = linked_list_create();
                     67:        enumerator = this->listener->create_enumerator(this->listener);
                     68:        while (enumerator->enumerate(enumerator, &current))
                     69:        {
                     70:                if (current->matches(current, id))
                     71:                {
                     72:                        list->insert_last(list, current->clone(current));
                     73:                }
                     74:        }
                     75:        enumerator->destroy(enumerator);
                     76: 
                     77:        while (list->remove_first(list, (void**)&current) == SUCCESS)
                     78:        {
                     79:                snprintf(msg.id, sizeof(msg.id), "%Y", current);
                     80:                current->destroy(current);
                     81:                if (!stream->write_all(stream, &msg, sizeof(msg)))
                     82:                {
                     83:                        DBG1(DBG_CFG, "listing whitelist failed: %s", strerror(errno));
                     84:                        break;
                     85:                }
                     86:        }
                     87:        list->destroy_offset(list, offsetof(identification_t, destroy));
                     88: 
                     89:        msg.type = htonl(WHITELIST_END);
                     90:        memset(msg.id, 0, sizeof(msg.id));
                     91:        stream->write_all(stream, &msg, sizeof(msg));
                     92: }
                     93: 
                     94: /**
                     95:  * Dispatch a received message
                     96:  */
                     97: static bool on_accept(private_whitelist_control_t *this, stream_t *stream)
                     98: {
                     99:        identification_t *id;
                    100:        whitelist_msg_t msg;
                    101: 
                    102:        while (stream->read_all(stream, &msg, sizeof(msg)))
                    103:        {
                    104:                msg.id[sizeof(msg.id) - 1] = 0;
                    105:                id = identification_create_from_string(msg.id);
                    106:                switch (ntohl(msg.type))
                    107:                {
                    108:                        case WHITELIST_ADD:
                    109:                                this->listener->add(this->listener, id);
                    110:                                break;
                    111:                        case WHITELIST_REMOVE:
                    112:                                this->listener->remove(this->listener, id);
                    113:                                break;
                    114:                        case WHITELIST_LIST:
                    115:                                list(this, stream, id);
                    116:                                break;
                    117:                        case WHITELIST_FLUSH:
                    118:                                this->listener->flush(this->listener, id);
                    119:                                break;
                    120:                        case WHITELIST_ENABLE:
                    121:                                this->listener->set_active(this->listener, TRUE);
                    122:                                break;
                    123:                        case WHITELIST_DISABLE:
                    124:                                this->listener->set_active(this->listener, FALSE);
                    125:                                break;
                    126:                        default:
                    127:                                DBG1(DBG_CFG, "received unknown whitelist command");
                    128:                                break;
                    129:                }
                    130:                id->destroy(id);
                    131:        }
                    132: 
                    133:        return FALSE;
                    134: }
                    135: 
                    136: METHOD(whitelist_control_t, destroy, void,
                    137:        private_whitelist_control_t *this)
                    138: {
                    139:        this->service->destroy(this->service);
                    140:        free(this);
                    141: }
                    142: 
                    143: /**
                    144:  * See header
                    145:  */
                    146: whitelist_control_t *whitelist_control_create(whitelist_listener_t *listener)
                    147: {
                    148:        private_whitelist_control_t *this;
                    149:        char *uri;
                    150: 
                    151:        INIT(this,
                    152:                .public = {
                    153:                        .destroy = _destroy,
                    154:                },
                    155:                .listener = listener,
                    156:        );
                    157: 
                    158:        uri = lib->settings->get_str(lib->settings,
                    159:                                "%s.plugins.whitelist.socket", "unix://" WHITELIST_SOCKET,
                    160:                                lib->ns);
                    161:        this->service = lib->streams->create_service(lib->streams, uri, 10);
                    162:        if (!this->service)
                    163:        {
                    164:                DBG1(DBG_CFG, "creating whitelist socket failed");
                    165:                free(this);
                    166:                return NULL;
                    167:        }
                    168: 
                    169:        this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
                    170:                                                         this, JOB_PRIO_CRITICAL, 0);
                    171: 
                    172:        return &this->public;
                    173: }

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