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>