5f511f2c546f90e1845b8db53fa5ced8df09f472
[strongswan.git] / src / libcharon / plugins / whitelist / whitelist.c
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 <stddef.h>
22 #include <stdio.h>
23 #include <errno.h>
24
25 /**
26 * Connect to the daemon, return FD
27 */
28 static int make_connection()
29 {
30 struct sockaddr_un addr;
31 int fd;
32
33 addr.sun_family = AF_UNIX;
34 strcpy(addr.sun_path, WHITELIST_SOCKET);
35
36 fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
37 if (fd < 0)
38 {
39 fprintf(stderr, "opening socket failed: %s\n", strerror(errno));
40 return -1;
41 }
42 if (connect(fd, (struct sockaddr *)&addr,
43 offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0)
44 {
45 fprintf(stderr, "connecting to %s failed: %s\n",
46 WHITELIST_SOCKET, strerror(errno));
47 close(fd);
48 return -1;
49 }
50 return fd;
51 }
52
53 /**
54 * Send a single message
55 */
56 static int send_msg(int type, char *id)
57 {
58 whitelist_msg_t msg = {
59 .type = type,
60 };
61 int fd;
62
63 fd = make_connection();
64 if (fd == -1)
65 {
66 return 2;
67 }
68 snprintf(msg.id, sizeof(msg.id), "%s", id);
69 if (send(fd, &msg, sizeof(msg), 0) != sizeof(msg))
70 {
71 fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
72 close(fd);
73 return 2;
74 }
75 if (type == WHITELIST_LIST)
76 {
77 while (recv(fd, &msg, sizeof(msg), 0) == sizeof(msg))
78 {
79 if (msg.type != WHITELIST_LIST)
80 {
81 break;
82 }
83 printf("%s\n", msg.id);
84 }
85 }
86 close(fd);
87 return 0;
88 }
89
90 /**
91 * Send a batch of messages, reading identities from a file
92 */
93 static int send_batch(int type, char *file)
94 {
95 whitelist_msg_t msg = {
96 .type = type,
97 };
98 FILE *f = stdin;
99 int fd, len;
100
101 fd = make_connection();
102 if (fd == -1)
103 {
104 return 2;
105 }
106 if (file)
107 {
108 f = fopen(file, "r");
109 if (f == NULL)
110 {
111 fprintf(stderr, "opening %s failed: %s\n", file, strerror(errno));
112 close(fd);
113 return 3;
114 }
115 }
116 while (fgets(msg.id, sizeof(msg.id), f))
117 {
118 len = strlen(msg.id);
119 if (len == 0)
120 {
121 continue;
122 }
123 if (msg.id[len-1] == '\n')
124 {
125 msg.id[len-1] = '\0';
126 }
127 if (send(fd, &msg, sizeof(msg), 0) != sizeof(msg))
128 {
129 fprintf(stderr, "writing to socket failed: %s\n", strerror(errno));
130 if (f != stdin)
131 {
132 fclose(f);
133 }
134 close(fd);
135 return 2;
136 }
137 }
138 if (f != stdin)
139 {
140 fclose(f);
141 }
142 close(fd);
143 return 0;
144 }
145
146 int main(int argc, char *argv[])
147 {
148 if (argc == 3 && strcmp(argv[1], "add") == 0)
149 {
150 return send_msg(WHITELIST_ADD, argv[2]);
151 }
152 if (argc == 3 && strcmp(argv[1], "remove") == 0)
153 {
154 return send_msg(WHITELIST_REMOVE, argv[2]);
155 }
156 if ((argc == 2 || argc == 3) && strcmp(argv[1], "add-from") == 0)
157 {
158 return send_batch(WHITELIST_ADD, argc == 3 ? argv[2] : NULL);
159 }
160 if ((argc == 2 || argc == 3) && strcmp(argv[1], "remove-from") == 0)
161 {
162 return send_batch(WHITELIST_REMOVE, argc == 3 ? argv[2] : NULL);
163 }
164 if ((argc == 2 || argc == 3) && strcmp(argv[1], "flush") == 0)
165 {
166 return send_msg(WHITELIST_FLUSH, argc == 3 ? argv[2] : "%any");
167 }
168 if ((argc == 2 || argc == 3) && strcmp(argv[1], "list") == 0)
169 {
170 return send_msg(WHITELIST_LIST, argc == 3 ? argv[2] : "%any");
171 }
172 if (argc == 2 && strcmp(argv[1], "enable") == 0)
173 {
174 return send_msg(WHITELIST_ENABLE, "");
175 }
176 if (argc == 2 && strcmp(argv[1], "disable") == 0)
177 {
178 return send_msg(WHITELIST_DISABLE, "");
179 }
180 fprintf(stderr, "Usage:\n");
181 fprintf(stderr, " %s add <identity>\n", argv[0]);
182 fprintf(stderr, " %s remove <identity>\n", argv[0]);
183 fprintf(stderr, " %s add-from <file>\n", argv[0]);
184 fprintf(stderr, " %s remove-from <file>\n", argv[0]);
185 fprintf(stderr, " %s flush [<pattern>]\n", argv[0]);
186 fprintf(stderr, " %s list [<pattern>]\n", argv[0]);
187 fprintf(stderr, " %s enable\n", argv[0]);
188 fprintf(stderr, " %s disable\n", argv[0]);
189 return 1;
190 }