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, ¤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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>