1 /**********************************************************
2 SixXS - Automatic IPv6 Connectivity Configuration Utility
3 ***********************************************************
4 Copyright 2003-2005 SixXS - http://www.sixxs.net
5 ***********************************************************
6 common/aiccu.c - AICCU Abstracted functions
7 ***********************************************************
9 $Id: aiccu.c,v 1.20 2007-01-15 12:02:10 jeroen Exp $
10 $Date: 2007-01-15 12:02:10 $
11 **********************************************************/
15 struct AICCU_conf
*g_aiccu
= NULL
;
18 struct pl_rule aiccu_conf_rules
[] =
21 {"username", PLRT_STRING
, offsetof(struct AICCU_conf
, username
)},
22 {"password", PLRT_STRING
, offsetof(struct AICCU_conf
, password
)},
23 {"protocol", PLRT_STRING
, offsetof(struct AICCU_conf
, protocol
)},
24 {"server", PLRT_STRING
, offsetof(struct AICCU_conf
, server
)},
25 {"ipv6_interface", PLRT_STRING
, offsetof(struct AICCU_conf
, ipv6_interface
)},
26 {"tunnel_id", PLRT_STRING
, offsetof(struct AICCU_conf
, tunnel_id
)},
27 {"local_ipv4_override", PLRT_STRING
, offsetof(struct AICCU_conf
, local_ipv4_override
)},
29 /* Post Setup script path */
30 {"setupscript", PLRT_STRING
, offsetof(struct AICCU_conf
, setupscript
)},
33 {"automatic", PLRT_BOOL
, offsetof(struct AICCU_conf
, automatic
)},
35 /* Operational options */
36 {"daemonize", PLRT_BOOL
, offsetof(struct AICCU_conf
, daemonize
)},
37 {"verbose", PLRT_BOOL
, offsetof(struct AICCU_conf
, verbose
)},
38 {"behindnat", PLRT_BOOL
, offsetof(struct AICCU_conf
, behindnat
)},
39 {"requiretls", PLRT_BOOL
, offsetof(struct AICCU_conf
, requiretls
)},
40 {"noconfigure", PLRT_BOOL
, offsetof(struct AICCU_conf
, noconfigure
)},
41 {"makebeats", PLRT_BOOL
, offsetof(struct AICCU_conf
, makebeats
)},
42 {"defaultroute", PLRT_BOOL
, offsetof(struct AICCU_conf
, defaultroute
)},
43 {"pidfile", PLRT_STRING
, offsetof(struct AICCU_conf
, pidfile
)},
48 void aiccu_tls_log(int level
, const char *message
);
49 void aiccu_tls_log(int level
, const char *message
)
51 dolog(level
, "[GNUTLS] %s\n", message
);
55 bool aiccu_InitConfig()
59 #define CAFILE "ca.pem"
61 /* Allocate & Initialize */
62 g_aiccu
= (struct AICCU_conf
*)malloc(sizeof(*g_aiccu
));
63 if (!g_aiccu
) return false;
64 memset(g_aiccu
, 0, sizeof(*g_aiccu
));
65 g_aiccu
->tic
= (struct TIC_conf
*)malloc(sizeof(*g_aiccu
->tic
));
66 memset(g_aiccu
->tic
, 0, sizeof(*g_aiccu
->tic
));
68 /* Initialize config to defaults */
69 g_aiccu
->running
= true;
70 g_aiccu
->tunrunning
= false;
71 g_aiccu
->daemonize
= 0;
72 g_aiccu
->verbose
= false;
73 g_aiccu
->requiretls
= false; /* Not mandatory yet */
74 g_aiccu
->noconfigure
= false;
75 g_aiccu
->makebeats
= true;
76 g_aiccu
->defaultroute
= true;
77 g_aiccu
->ipv6_interface
= strdup("aiccu");
78 if (!g_aiccu
->ipv6_interface
) return false;
79 g_aiccu
->protocol
= strdup("tic");
80 if (!g_aiccu
->protocol
) return false;
81 g_aiccu
->server
= strdup("tic.sixxs.net");
82 if (!g_aiccu
->server
) return false;
83 g_aiccu
->pidfile
= strdup(AICCU_PID
);
84 if (!g_aiccu
->pidfile
) return false;
87 /* Initialize GNUTLS */
88 ret
= gnutls_global_init();
91 dolog(LOG_ERR
, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret
), ret
);
95 /* X509 credentials */
96 ret
= gnutls_certificate_allocate_credentials(&g_aiccu
->tls_cred
);
99 dolog(LOG_ERR
, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret
), ret
);
103 /* For the time being don't load the PEM as it is not there... */
106 /* Sets the trusted cas file */
107 ret
= gnutls_certificate_set_x509_trust_file(g_aiccu
->tls_cred
, CAFILE
, GNUTLS_X509_FMT_PEM
);
110 dolog(LOG_ERR
, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret
), ret
);
115 /* Configure GNUTLS logging to happen using our own logging interface */
116 gnutls_global_set_log_function(aiccu_tls_log
);
119 /* Show some GNUTLS debugging information */
120 gnutls_global_set_log_level(5);
123 #endif /* AICCU_GNUTLS */
128 /* Locate where the configfile is stored */
129 void aiccu_LocateFile(const char *what
, char *filename
, unsigned int length
);
130 void aiccu_LocateFile(const char *what
, char *filename
, unsigned int length
)
132 memset(filename
, 0, length
);
134 /* Figure out the "C:\Windows" location */
135 /* as that is where we store our configuration */
136 GetWindowsDirectory(filename
, length
);
137 strncat(filename
, "\\", length
);
138 strncat(filename
, what
, length
);
140 /* Use the default location */
141 strncat(filename
, what
, length
);
145 /* configure this client */
146 bool aiccu_LoadConfig(const char *filename
)
151 unsigned int line
= 0;
155 aiccu_LocateFile(AICCU_CONFIG
, filenames
, sizeof(filenames
));
156 filename
= filenames
;
159 f
= fopen(filename
, "r");
162 dolog(LOG_ERR
, "Could not open config file \"%s\"\n", filename
);
166 while (fgets(buf
, sizeof(buf
), f
))
169 if (parseline(buf
, " ", aiccu_conf_rules
, g_aiccu
)) continue;
171 dolog(LOG_WARNING
, "Unknown configuration statement on line %u of %s: \"%s\"\n", line
, filename
, buf
);
178 /* Save the configuration */
179 bool aiccu_SaveConfig(const char *filename
)
186 aiccu_LocateFile(AICCU_CONFIG
, filenames
, sizeof(filenames
));
187 filename
= filenames
;
190 f
= fopen(filename
, "w");
193 dolog(LOG_ERR
, "Could not open config file \"%s\" for writing\n", filename
);
197 fprintf(f
, "# AICCU Configuration (Saved by AICCU %s)\n", AICCU_VER
);
199 fprintf(f
, "# Login information\n");
200 fprintf(f
, "username %s\n", g_aiccu
->username
);
201 fprintf(f
, "password %s\n", g_aiccu
->password
);
202 fprintf(f
, "protocol %s\n", g_aiccu
->protocol
);
203 fprintf(f
, "server %s\n", g_aiccu
->server
);
205 fprintf(f
, "# Interface names to use\n");
206 fprintf(f
, "ipv6_interface %s\n", g_aiccu
->ipv6_interface
);
208 fprintf(f
, "# The tunnel_id to use\n");
209 fprintf(f
, "# (only required when there are multiple tunnels in the list)\n");
210 fprintf(f
, "tunnel_id %s\n", g_aiccu
->tunnel_id
);
212 fprintf(f
, "# Try to automatically login and setup the tunnel?\n");
213 fprintf(f
, "automatic %s\n", g_aiccu
->automatic
? "true" : "false");
215 fprintf(f
, "# Script to run after setting up the interfaces (default: none)\n");
216 fprintf(f
, "%ssetupscript %s\n", g_aiccu
->setupscript
? "" : "#", g_aiccu
->setupscript
? g_aiccu
->setupscript
: "<path>");
218 fprintf(f
, "# TLS Required?\n");
219 fprintf(f
, "requiretls %s\n", g_aiccu
->requiretls
? "true" : "false");
221 fprintf(f
, "# Be verbose?\n");
222 fprintf(f
, "verbose %s\n", g_aiccu
->verbose
? "true" : "false");
224 fprintf(f
, "# Daemonize?\n");
225 fprintf(f
, "daemonize %s\n", g_aiccu
->daemonize
? "true" : "false");
227 fprintf(f
, "# Behind NAT (default: false)\n");
228 fprintf(f
, "# Notify the user that a NAT-kind network is detected\n");
229 fprintf(f
, "behindnat %s\n", g_aiccu
->behindnat
? "true" : "false");
231 fprintf(f
, "# PID File\n");
232 fprintf(f
, "pidfile %s\n", g_aiccu
->pidfile
);
234 fprintf(f
, "# Make heartbeats (default true)\n");
235 fprintf(f
, "# In general you don't want to turn this off\n");
236 fprintf(f
, "# Of course only applies to AYIYA and heartbeat tunnels not to static ones\n");
237 fprintf(f
, "makebeats %s\n", g_aiccu
->makebeats
? "true" : "false");
239 fprintf(f
, "# Add a default route (default: true)\n");
240 fprintf(f
, "defaultroute %s\n", g_aiccu
->defaultroute
? "true" : "false");
242 fprintf(f
, "# Don't configure anything (default: false)\n");
243 fprintf(f
, "noconfigure %s\n", g_aiccu
->noconfigure
? "true" : "false");
248 void aiccu_FreeConfig()
250 if (!g_aiccu
) return;
253 gnutls_certificate_free_credentials(g_aiccu
->tls_cred
);
254 gnutls_global_deinit();
257 if (g_aiccu
->username
) { free(g_aiccu
->username
); g_aiccu
->username
= NULL
; }
258 if (g_aiccu
->password
) { free(g_aiccu
->password
); g_aiccu
->password
= NULL
; }
259 if (g_aiccu
->ipv6_interface
) { free(g_aiccu
->ipv6_interface
);g_aiccu
->ipv6_interface
= NULL
; }
260 if (g_aiccu
->tunnel_id
) { free(g_aiccu
->tunnel_id
); g_aiccu
->tunnel_id
= NULL
; }
261 if (g_aiccu
->tic
) { free(g_aiccu
->tic
); g_aiccu
->tic
= NULL
; }
262 if (g_aiccu
->setupscript
) { free(g_aiccu
->setupscript
); g_aiccu
->setupscript
= NULL
; }
263 if (g_aiccu
->pidfile
) { free(g_aiccu
->pidfile
); g_aiccu
->pidfile
= NULL
; }
269 /* Make sure the OS understands IPv6 */
270 void aiccu_install(void)
272 D(dolog(LOG_DEBUG
, "aiccu_install()\n");)
276 bool aiccu_setup(struct TIC_Tunnel
*hTunnel
, bool firstrun
)
280 D(dolog(LOG_DEBUG
, "aiccu_setup(%s, %s)\n", hTunnel
->sIPv6_Local
, firstrun
? "first" : "other");)
282 /* AYIYA calls aiccu_setup(hTunnel,false) after preparing the tunnel interface */
283 if (firstrun
&& strcasecmp(hTunnel
->sType
, "ayiya") == 0)
285 ret
= ayiya(hTunnel
);
287 #ifdef NEWSTUFF_TEEPEE
288 else if (firstrun
&& strcasecmp(hTunnel
->sType
, "l2tp") == 0)
290 ret
= teepee(hTunnel
);
295 ret
= aiccu_os_setup(hTunnel
);
298 /* Beat for the first time */
299 if (ret
) aiccu_beat(hTunnel
);
304 void aiccu_beat(struct TIC_Tunnel
*hTunnel
)
306 if (!g_aiccu
->makebeats
)
308 D(dolog(LOG_DEBUG
, "aiccu_beat() - Beating disabled\n"));
312 D(dolog(LOG_DEBUG
, "aiccu_beat() - Beating %s...\n", hTunnel
->sType
));
314 if (strcasecmp(hTunnel
->sType
, "6in4-heartbeat") == 0)
316 heartbeat_beat(hTunnel
);
318 else if (strcasecmp(hTunnel
->sType
, "ayiya") == 0)
324 D(dolog(LOG_DEBUG
, "aiccu_beat() - No beat for %s!?\n", hTunnel
->sType
));
327 /* L2TP Hello's are handled inside TeePee */
330 void aiccu_reconfig(struct TIC_Tunnel
*hTunnel
)
332 D(dolog(LOG_DEBUG
, "aiccu_reconfig(%s)\n", hTunnel
->sIPv6_Local
);)
333 if (!g_aiccu
->noconfigure
) aiccu_os_reconfig(hTunnel
);
336 void aiccu_delete(struct TIC_Tunnel
*hTunnel
)
338 D(dolog(LOG_DEBUG
, "aiccu_delete(%s)\n", hTunnel
->sIPv6_Local
);)
339 if (!g_aiccu
->noconfigure
) aiccu_os_delete(hTunnel
);
342 void aiccu_test(struct TIC_Tunnel
*hTunnel
, bool automatic
)
344 D(dolog(LOG_DEBUG
, "aiccu_test()\n"));
345 aiccu_os_test(hTunnel
, automatic
);
348 bool aiccu_exec(const char *fmt
, ...)
356 vsnprintf(buf
,sizeof(buf
),fmt
,ap
);
357 D(dolog(LOG_DEBUG
, "aiccu_os_exec(\"%s\")\n", buf
));
359 if (ret
== -1) dolog(LOG_WARNING
, "Execution of \"%s\" failed!? (Please check if the command is available)\n", buf
);
365 #define SIXXS_LICENSE_PART1 "\
366 The SixXS License - http://www.sixxs.net/\n\
368 Copyright (C) SixXS Staff <info@sixxs.net>\n\
369 All rights reserved.\n\
371 Redistribution and use in source and binary forms, with or without\n\
372 modification, are permitted provided that the following conditions\n\
374 1. Redistributions of source code must retain the above copyright\n\
375 notice, this list of conditions and the following disclaimer.\n"
377 #define SIXXS_LICENSE_PART2 "\
378 2. Redistributions in binary form must reproduce the above copyright\n\
379 notice, this list of conditions and the following disclaimer in the\n\
380 documentation and/or other materials provided with the distribution.\n\
381 3. Neither the name of SixXS nor the names of its contributors\n\
382 may be used to endorse or promote products derived from this software\n\
383 without specific prior permission.\n\
387 #define SIXXS_LICENSE_PART3 "\
388 THIS SOFTWARE IS PROVIDED BY SIXXS AND CONTRIBUTORS ``AS IS'' AND\n\
389 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
390 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
391 ARE DISCLAIMED. IN NO EVENT SHALL SIXXS OR CONTRIBUTORS BE LIABLE\n\
392 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
393 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
395 #define SIXXS_LICENSE_PART4 "\
396 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
397 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
398 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
399 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
402 const char *aiccu_license()
406 * Pedantic doesn't allow this long strings, thus we will
407 * play nice and malloc it, copy them in separately and
408 * then return the buffer.
409 * What we don't do for compliancy....
411 static char *license
= NULL
;
415 * Make one big block out of it
416 * too bad that the \0's get inserted,
417 * remove them and tada one big text...
420 l1
[] = SIXXS_LICENSE_PART1
,
421 l2
[] = SIXXS_LICENSE_PART2
,
422 l3
[] = SIXXS_LICENSE_PART3
,
423 l4
[] = SIXXS_LICENSE_PART4
;
430 /* Create the 'long' string our selves then */
431 license
= (char *)malloc(a
+b
+c
+d
+1);
432 if (!license
) return NULL
;
434 memset(license
, 0, a
+b
+c
+d
+1);
435 memcpy(license
, l1
, a
);
436 memcpy(license
+ a
, l2
, b
);
437 memcpy(license
+ a
+ b
, l3
, c
);
438 memcpy(license
+ a
+ b
+ c
, l4
, d
);
442 return SIXXS_LICENSE_PART1 SIXXS_LICENSE_PART2 SIXXS_LICENSE_PART3 SIXXS_LICENSE_PART4
;