Return to whitelist.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_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: }