main.c revision bd5fa3c99638830d3fa1ae5b4fc4988de5ee0f4d
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <stdarg.h>
21#include <ctype.h>
22#include <signal.h>
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/socket.h>
26#include <sys/select.h>
27
28#ifdef ANDROID_CHANGES
29#include <fcntl.h>
30#include <android/log.h>
31#include <cutils/sockets.h>
32#include <private/android_filesystem_config.h>
33#include "keystore_get.h"
34#endif
35
36#include "config.h"
37#include "libpfkey.h"
38#include "ipsec_strerror.h"
39#include "gcmalloc.h"
40#include "vmbuf.h"
41#include "crypto_openssl.h"
42#include "oakley.h"
43#include "pfkey.h"
44#include "schedule.h"
45#include "isakmp_var.h"
46#include "nattraversal.h"
47#include "localconf.h"
48#include "sockmisc.h"
49#include "grabmyaddr.h"
50#include "plog.h"
51#include "admin.h"
52#include "privsep.h"
53#include "misc.h"
54
55extern int setup(int argc, char **argv);
56int f_local = 0;
57
58static void interrupt(int signal)
59{
60    exit(1);
61}
62
63#ifdef ANDROID_CHANGES
64
65static int get_control_and_arguments(int *argc, char ***argv)
66{
67    static char *args[256];
68    int control;
69    int i;
70
71    if ((i = android_get_control_socket("racoon")) == -1) {
72        return -1;
73    }
74    do_plog(LLV_DEBUG, "Waiting for control socket");
75    if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
76        do_plog(LLV_ERROR, "Cannot get control socket");
77        exit(-1);
78    }
79    close(i);
80    fcntl(control, F_SETFD, FD_CLOEXEC);
81
82    args[0] = (*argv)[0];
83    for (i = 1; i < 256; ++i) {
84        unsigned char length;
85        if (recv(control, &length, 1, 0) != 1) {
86            do_plog(LLV_ERROR, "Cannot get argument length");
87            exit(-1);
88        }
89        if (length == 0xFF) {
90            break;
91        } else {
92            int offset = 0;
93            args[i] = malloc(length + 1);
94            while (offset < length) {
95                int n = recv(control, &args[i][offset], length - offset, 0);
96                if (n > 0) {
97                    offset += n;
98                } else {
99                    do_plog(LLV_ERROR, "Cannot get argument value");
100                    exit(-1);
101                }
102            }
103            args[i][length] = 0;
104        }
105    }
106    do_plog(LLV_DEBUG, "Received %d arguments", i - 1);
107
108    *argc = i;
109    *argv = args;
110    return control;
111}
112
113#endif
114
115int main(int argc, char **argv)
116{
117    fd_set fdset;
118    int fdset_size;
119    struct myaddrs *p;
120#ifdef ANDROID_CHANGES
121    unsigned char code;
122    int control = get_control_and_arguments(&argc, &argv);
123#endif
124
125    do_plog(LLV_INFO, "ipsec-tools 0.7.2 (http://ipsec-tools.sf.net)\n");
126
127    signal(SIGHUP, interrupt);
128    signal(SIGINT, interrupt);
129    signal(SIGTERM, interrupt);
130    signal(SIGCHLD, interrupt);
131    signal(SIGPIPE, SIG_IGN);
132
133    eay_init();
134    oakley_dhinit();
135    compute_vendorids();
136    sched_init();
137
138    if (setup(argc, argv) < 0 || pfkey_init() < 0 || isakmp_init() < 0) {
139        exit(1);
140    }
141
142#ifdef ANDROID_CHANGES
143    code = argc - 1;
144    send(control, &code, 1, 0);
145    setuid(AID_VPN);
146#endif
147
148#ifdef ENABLE_NATT
149    natt_keepalive_init();
150#endif
151
152    FD_ZERO(&fdset);
153    FD_SET(lcconf->sock_pfkey, &fdset);
154    fdset_size = lcconf->sock_pfkey;
155    for (p = lcconf->myaddrs; p; p = p->next) {
156        FD_SET(p->sock, &fdset);
157        if (fdset_size < p->sock) {
158            fdset_size = p->sock;
159        }
160    }
161    ++fdset_size;
162
163    while (1) {
164        fd_set readset = fdset;
165        struct timeval *timeout = schedular();
166        if (select(fdset_size, &readset, NULL, NULL, timeout) < 0) {
167            exit(1);
168        }
169        if (FD_ISSET(lcconf->sock_pfkey, &readset)) {
170            pfkey_handler();
171        }
172        for (p = lcconf->myaddrs; p; p = p->next) {
173            if (FD_ISSET(p->sock, &readset)) {
174                isakmp_handler(p->sock);
175            }
176        }
177    }
178    return 0;
179}
180
181/* plog.h */
182
183void do_plog(int level, char *format, ...)
184{
185    if (level >= 0 && level <= 5) {
186#ifdef ANDROID_CHANGES
187        static int levels[6] = {
188            ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO,
189            ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE
190        };
191        va_list ap;
192        va_start(ap, format);
193        __android_log_vprint(levels[level], "racoon", format, ap);
194        va_end(ap);
195#else
196        static char *levels = "EWNIDV";
197        fprintf(stderr, "%c: ", levels[level]);
198        va_list ap;
199        va_start(ap, format);
200        vfprintf(stderr, format, ap);
201        va_end(ap);
202#endif
203    }
204}
205
206char *binsanitize(char *data, size_t length)
207{
208    char *output = racoon_malloc(length + 1);
209    if (output) {
210        size_t i;
211        for (i = 0; i < length; ++i) {
212            output[i] = isprint(data[i]) ? data[i] : '?';
213        }
214        output[length] = '\0';
215    }
216    return output;
217}
218
219/* libpfkey.h */
220
221ipsec_policy_t ipsec_set_policy(__ipsec_const char *message, int length)
222{
223    struct sadb_x_policy *p;
224    int direction;
225
226    if (!strcmp("in bypass", message)) {
227        direction = IPSEC_DIR_INBOUND;
228    } else if (!strcmp("out bypass", message)) {
229        direction = IPSEC_DIR_OUTBOUND;
230    } else {
231        __ipsec_errcode = EIPSEC_INVAL_POLICY;
232        return NULL;
233    }
234
235    p = calloc(1, sizeof(struct sadb_x_policy));
236    p->sadb_x_policy_len = PFKEY_UNIT64(sizeof(struct sadb_x_policy));
237    p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
238    p->sadb_x_policy_type = IPSEC_POLICY_BYPASS;
239    p->sadb_x_policy_dir = direction;
240#ifdef HAVE_PFKEY_POLICY_PRIORITY
241    p->sadb_x_policy_priority = PRIORITY_DEFAULT;
242#endif
243    __ipsec_errcode = EIPSEC_NO_ERROR;
244    return (ipsec_policy_t)p;
245}
246
247int ipsec_get_policylen(ipsec_policy_t policy)
248{
249    return policy ? PFKEY_EXTLEN(policy) : -1;
250}
251
252/* grabmyaddr.h */
253
254int getsockmyaddr(struct sockaddr *addr)
255{
256    struct myaddrs *p;
257    for (p = lcconf->myaddrs; p; p = p->next) {
258        if (cmpsaddrstrict(addr, p->addr) == 0) {
259            return p->sock;
260        }
261    }
262    return -1;
263}
264
265/* privsep.h */
266
267int privsep_pfkey_open()
268{
269    return pfkey_open();
270}
271
272void privsep_pfkey_close(int key)
273{
274    pfkey_close(key);
275}
276
277vchar_t *privsep_eay_get_pkcs1privkey(char *file)
278{
279    return eay_get_pkcs1privkey(file);
280}
281
282vchar_t *privsep_getpsk(const char *key, int size)
283{
284    vchar_t *p = NULL;
285#ifdef ANDROID_CHANGES
286    char *value = keystore_get(key, &size);
287    if (value) {
288        if ((p = vmalloc(size)) != NULL) {
289            memcpy(p->v, value, p->l);
290        }
291        free(value);
292    }
293#else
294    if (key && (p = vmalloc(size)) != NULL) {
295        memcpy(p->v, key, p->l);
296    }
297#endif
298    return p;
299}
300
301int privsep_script_exec(char *script, int name, char * const *environ)
302{
303    return 0;
304}
305
306/* misc.h */
307
308int racoon_hexdump(void *data, size_t length)
309{
310    return 0;
311}
312