Return to whitelist_control.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / whitelist |
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, ¤t)) 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**)¤t) == 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: }