Annotation of embedaddon/strongswan/src/libcharon/plugins/whitelist/whitelist.c, revision 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>