Annotation of embedaddon/strongswan/src/libcharon/plugins/whitelist/whitelist.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_msg.h"
17:
18: #include <sys/socket.h>
19: #include <sys/un.h>
20: #include <unistd.h>
21: #include <stdlib.h>
22: #include <stddef.h>
23: #include <stdio.h>
24: #include <string.h>
25: #include <errno.h>
26: #include <arpa/inet.h>
27: #include <netinet/in.h>
28:
29: /**
30: * Connect to the daemon, return FD
31: */
32: static int make_connection()
33: {
34: union {
35: struct sockaddr_un un;
36: struct sockaddr_in in;
37: struct sockaddr sa;
38: } addr;
39: int fd, len;
40:
41: if (getenv("TCP_PORT"))
42: {
43: addr.in.sin_family = AF_INET;
44: addr.in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
45: addr.in.sin_port = htons(atoi(getenv("TCP_PORT")));
46: len = sizeof(addr.in);
47: }
48: else
49: {
50: addr.un.sun_family = AF_UNIX;
51: strcpy(addr.un.sun_path, WHITELIST_SOCKET);
52:
53: len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.un.sun_path);
54: }
55: fd = socket(addr.sa.sa_family, SOCK_STREAM, 0);
56: if (fd < 0)
57: {
58: fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
59: return -1;
60: }
61: if (connect(fd, &addr.sa, len) < 0)
62: {
63: fprintf(stderr, "connecting failed: %s\n", strerror(errno));
64: close(fd);
65: return -1;
66: }
67: return fd;
68: }
69:
70: static int read_all(int fd, void *buf, size_t len)
71: {
72: ssize_t ret, done = 0;
73:
74: while (done < len)
75: {
76: ret = read(fd, buf, len - done);
77: if (ret == -1 && errno == EINTR)
78: { /* interrupted, try again */
79: continue;
80: }
81: if (ret < 0)
82: {
83: return -1;
84: }
85: done += ret;
86: buf += ret;
87: }
88: return len;
89: }
90:
91: static int write_all(int fd, void *buf, size_t len)
92: {
93: ssize_t ret, done = 0;
94:
95: while (done < len)
96: {
97: ret = write(fd, buf, len - done);
98: if (ret == -1 && errno == EINTR)
99: { /* interrupted, try again */
100: continue;
101: }
102: if (ret < 0)
103: {
104: return -1;
105: }
106: done += ret;
107: buf += ret;
108: }
109: return len;
110: }
111:
112: /**
113: * Send a single message
114: */
115: static int send_msg(int type, char *id)
116: {
117: whitelist_msg_t msg = {
118: .type = htonl(type),
119: };
120: int fd;
121:
122: fd = make_connection();
123: if (fd == -1)
124: {
125: return 2;
126: }
127: snprintf(msg.id, sizeof(msg.id), "%s", id);
128: if (write_all(fd, &msg, sizeof(msg)) != sizeof(msg))
129: {
130: fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
131: close(fd);
132: return 2;
133: }
134: if (type == WHITELIST_LIST)
135: {
136: while (1)
137: {
138: if (read_all(fd, &msg, sizeof(msg)) != sizeof(msg))
139: {
140: fprintf(stderr, "reading failed: %s\n", strerror(errno));
141: close(fd);
142: return 2;
143: }
144: if (ntohl(msg.type) != WHITELIST_LIST)
145: {
146: break;
147: }
148: msg.id[sizeof(msg.id) - 1] = '\0';
149: printf("%s\n", msg.id);
150: }
151: }
152: close(fd);
153: return 0;
154: }
155:
156: /**
157: * Send a batch of messages, reading identities from a file
158: */
159: static int send_batch(int type, char *file)
160: {
161: whitelist_msg_t msg = {
162: .type = htonl(type),
163: };
164: FILE *f = stdin;
165: int fd, len;
166:
167: fd = make_connection();
168: if (fd == -1)
169: {
170: return 2;
171: }
172: if (file)
173: {
174: f = fopen(file, "r");
175: if (f == NULL)
176: {
177: fprintf(stderr, "opening %s failed: %s\n", file, strerror(errno));
178: close(fd);
179: return 3;
180: }
181: }
182: while (fgets(msg.id, sizeof(msg.id), f))
183: {
184: len = strlen(msg.id);
185: if (len == 0)
186: {
187: continue;
188: }
189: if (msg.id[len-1] == '\n')
190: {
191: msg.id[len-1] = '\0';
192: }
193: if (write_all(fd, &msg, sizeof(msg)) != sizeof(msg))
194: {
195: fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
196: if (f != stdin)
197: {
198: fclose(f);
199: }
200: close(fd);
201: return 2;
202: }
203: }
204: if (f != stdin)
205: {
206: fclose(f);
207: }
208: close(fd);
209: return 0;
210: }
211:
212: int main(int argc, char *argv[])
213: {
214: if (argc == 3 && strcmp(argv[1], "add") == 0)
215: {
216: return send_msg(WHITELIST_ADD, argv[2]);
217: }
218: if (argc == 3 && strcmp(argv[1], "remove") == 0)
219: {
220: return send_msg(WHITELIST_REMOVE, argv[2]);
221: }
222: if ((argc == 2 || argc == 3) && strcmp(argv[1], "add-from") == 0)
223: {
224: return send_batch(WHITELIST_ADD, argc == 3 ? argv[2] : NULL);
225: }
226: if ((argc == 2 || argc == 3) && strcmp(argv[1], "remove-from") == 0)
227: {
228: return send_batch(WHITELIST_REMOVE, argc == 3 ? argv[2] : NULL);
229: }
230: if ((argc == 2 || argc == 3) && strcmp(argv[1], "flush") == 0)
231: {
232: return send_msg(WHITELIST_FLUSH, argc == 3 ? argv[2] : "%any");
233: }
234: if ((argc == 2 || argc == 3) && strcmp(argv[1], "list") == 0)
235: {
236: return send_msg(WHITELIST_LIST, argc == 3 ? argv[2] : "%any");
237: }
238: if (argc == 2 && strcmp(argv[1], "enable") == 0)
239: {
240: return send_msg(WHITELIST_ENABLE, "");
241: }
242: if (argc == 2 && strcmp(argv[1], "disable") == 0)
243: {
244: return send_msg(WHITELIST_DISABLE, "");
245: }
246: fprintf(stderr, "Usage:\n");
247: fprintf(stderr, " %s add <identity>\n", argv[0]);
248: fprintf(stderr, " %s remove <identity>\n", argv[0]);
249: fprintf(stderr, " %s add-from <file>\n", argv[0]);
250: fprintf(stderr, " %s remove-from <file>\n", argv[0]);
251: fprintf(stderr, " %s flush [<pattern>]\n", argv[0]);
252: fprintf(stderr, " %s list [<pattern>]\n", argv[0]);
253: fprintf(stderr, " %s enable\n", argv[0]);
254: fprintf(stderr, " %s disable\n", argv[0]);
255: return 1;
256: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>