summaryrefslogtreecommitdiffstats
path: root/src/aeswepd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aeswepd.c')
-rw-r--r--src/aeswepd.c599
1 files changed, 0 insertions, 599 deletions
diff --git a/src/aeswepd.c b/src/aeswepd.c
deleted file mode 100644
index d144977..0000000
--- a/src/aeswepd.c
+++ /dev/null
@@ -1,599 +0,0 @@
-/* $Id$ */
-
-/*
- * This file is part of waproamd.
- *
- * waproamd is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * waproamd is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with waproamd; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#define _GNU_SOURCE
-
-#include <assert.h>
-#include <sys/select.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <stdio.h>
-#include <signal.h>
-#include <getopt.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <libdaemon/dlog.h>
-#include <libdaemon/dpid.h>
-#include <libdaemon/dsignal.h>
-#include <libdaemon/dfork.h>
-
-#include "aes.h"
-#include "aeswepd.h"
-#include "iwkey.h"
-#include "interface.h"
-#include "util.h"
-
-uint8_t aes_key[AES_KEY_LEN];
-int rekey_time = 15*60;
-int n_max_keys = 3;
-int key_map[MAX_WEP_KEYS];
-char *interface_name = NULL;
-int daemonize = 1, use_syslog = 1, wait_on_fork = 0, use_status_file = 1;
-char log_ident[32], pid_ident[32];
-
-FILE *status_file = NULL;
-
-const char *get_status_file_name(void) {
- static int init = 0;
- static char path[PATH_MAX];
-
- if (!init) {
- snprintf(path, sizeof(path), "%s/status.%s", VARLIBAESWEPD, interface_name);
- init = 1;
- }
-
- return path;
-}
-
-
-int do_list_keys(void) {
- FILE *f;
- char ln[256];
-
- if (!(f = fopen(get_status_file_name(), "r"))) {
- daemon_log(LOG_ERR, "Failed to open '%s': %s", get_status_file_name(), strerror(errno));
- return -1;
- }
-
- while (fgets(ln, sizeof(ln), f))
- fputs(ln, stdout);
-
- fclose(f);
- return 0;
-}
-
-int wep_key_calc(uint32_t t, uint8_t w[WEP_KEY_LEN]) {
- uint8_t data[AES_KEY_LEN], result[AES_KEY_LEN];
- uint32_t v = t;
- int i, shift;
-
- for (i = 0, shift = 0; i < AES_KEY_LEN; i++) {
- data[i] = (uint8_t) (v >> shift);
-
- if ((shift += 8) >= sizeof(v)*8)
- shift = 0;
- }
-
- if (aes_crypt(aes_key, data, result) < 0) {
- daemon_log(LOG_ERR, "aes_crypt() failed!");
- return -1;
- }
-
- memset(w, 0, WEP_KEY_LEN);
- memcpy(w, result, MIN(WEP_KEY_LEN, AES_KEY_LEN));
-
- return 0;
-}
-
-int print_wep_key(FILE *f, int t, uint8_t wep[WEP_KEY_LEN]) {
- time_t rt = t*rekey_time;
- fprintf(f, "%10i: Starting %s\t WEP: ", t, ctime(&rt));
- print_hex(f, wep, WEP_KEY_LEN);
- fprintf(f, "\n");
- return 0;
-}
-
-
-int rekey(struct interface *i, time_t now, time_t *next_rekey) {
- uint8_t w[WEP_KEY_LEN];
- uint32_t t;
-
- assert(i && n_max_keys >= 1 && next_rekey);
-
- t = now/rekey_time;
-
- daemon_log(LOG_ERR, "Rekeying for %i", t);
-
- if (status_file) {
- rewind(status_file);
- ftruncate(fileno(status_file), 0);
- }
-
- if (wep_key_calc(t, w) < 0)
- return -1;
-
- if (wep_key_add(i, w) < 0)
- return -1;
-
- if (status_file)
- print_wep_key(status_file, t, w);
-
- if (n_max_keys >= 3) {
- if (wep_key_calc(t-1, w) < 0)
- return -1;
-
- if (wep_key_add(i, w) < 0)
- return -1;
-
- if (status_file)
- print_wep_key(status_file, t-1, w);
-
- if (wep_key_calc(t+1, w) < 0)
- return -1;
-
- if (wep_key_add(i, w) < 0)
- return -1;
-
- if (status_file)
- print_wep_key(status_file, t+1, w);
- }
-
- if (status_file)
- fflush(status_file);
-
- if (wep_key_finish(i) < 0)
- return -1;
-
- *next_rekey = (t+1)*rekey_time;
-
- return 0;
-}
-
-int go(struct interface *i) {
- time_t next_rekey = 0;
- int send_retval = 1;
- fd_set fds;
- time_t now = time(NULL);
- int sigfd, r = -1;
-
- daemon_log(LOG_INFO, "aeswepd "VERSION" initializing. (rekey_time=%i)", rekey_time);
-
- if (daemon_pid_file_create() < 0) {
- daemon_log(LOG_ERR, "Could not create PID file %s.", daemon_pid_file_proc());
- goto finish;
- }
-
- if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, -1) < 0) {
- daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno));
- goto finish;
- }
-
- if (use_status_file) {
- mode_t u;
-
- u = umask(077);
- status_file = fopen(get_status_file_name(), "w");
- umask(u);
-
- if (!status_file) {
- daemon_log(LOG_WARNING, "Failed to open status file '%s', doing without: %s", get_status_file_name(), strerror(errno));
- use_status_file = 0;
- }
- }
-
- if (rekey(i, now, &next_rekey) < 0)
- goto finish;
-
- daemon_log(LOG_INFO, "aeswepd successfully initialized.");
-
- if (daemonize && wait_on_fork) {
- daemon_retval_send(0);
- send_retval = 0;
- }
-
- FD_ZERO(&fds);
- FD_SET(sigfd = daemon_signal_fd(), &fds);
-
- for (;;) {
- fd_set qfds;
- struct timeval tv;
- now = time(NULL);
-
- if (next_rekey < now) {
- if (rekey(i, now, &next_rekey) < 0)
- return -1;
- }
-
- qfds = fds;
-
- now = time(NULL);
- tv.tv_sec = next_rekey > now ? next_rekey - now : 0;
- tv.tv_usec = 0;
-
- if (select(sigfd+1, &qfds, NULL, NULL, &tv) < 0) {
- if (errno == EINTR)
- continue;
-
- daemon_log(LOG_ERR, "select() failed: %s\n", strerror(errno));
- return -1;
- }
-
-
- if (FD_ISSET(sigfd, &qfds)) {
- int sig;
-
- if ((sig = daemon_signal_next()) < 0) {
- daemon_log(LOG_ERR, "daemon_signal_next(): %s", strerror(errno));
- goto finish;
- }
-
-
- switch (sig) {
-
- case SIGINT:
- case SIGTERM:
- case SIGQUIT:
- r = 0;
- goto finish;
-
- case SIGHUP:
- next_rekey = 0;
- break;
-
- default:
- daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig));
- break;
-
- }
- }
- }
-
- r = 0;
-
-finish:
-
- if (status_file) {
- fclose(status_file);
- unlink(get_status_file_name());
- }
-
- if (send_retval && daemonize && wait_on_fork)
- daemon_retval_send(1);
-
- daemon_pid_file_remove();
- daemon_signal_done();
-
- daemon_log(LOG_INFO, "Exiting.");
-
- return r;
-}
-
-void usage(char *p) {
- if (strrchr(p, '/'))
- p = strchr(p, '/')+1;
-
- printf("%s -- AES Rekeying Daemon for IEEE 802.11b WEP\n\n"
- "Usage: %s [options]\n\n"
- "Options:\n"
- " -n --no-daemon Do not daemonize (for debugging) (%s)\n"
- " -s --no-syslog Do not use syslog, use stderr instead (for debugging) (%s)\n"
- " -i --iface=IFACE Specify network interface (%s)\n"
- " -t --rekey-time=SECS Specify rekeying interval in seconds (%i)\n"
- " -K --key=KEY Specify AES key (don't use this!)\n"
- " -F --key-file=KEYFILE File to read key from\n"
- " -E --key-env=KEYENV Specify environment variable to read key from\n"
- " -m --max-keys=NR Specify the number of keys to use concurrently (%i)\n"
- " -w --wait-on-fork Wait until daemon fork finished (%s)\n"
- " -l --list-keys Show keys of running daemon\n"
- " -h --help Show this help\n"
- " -k --kill Kill a running daemon\n"
- " -c --check-running Check if a daemon is currently running\n"
- " -v --version Show version\n\n"
- " <KEY>: A %i byte AES key as hexadecimal string\n",
- p, p,
- !daemonize ? "on" : "off",
- !use_syslog ? "on" : "off",
- interface_name,
- rekey_time,
- n_max_keys,
- wait_on_fork ? "on" : "off",
- AES_KEY_LEN);
-}
-
-void parse_args(int argc, char *argv[]) {
- static struct option long_options[] = {
- {"no-daemon", no_argument, 0, 'n'},
- {"no-syslog", no_argument, 0, 's'},
- {"iface", required_argument, 0, 'i'},
- {"rekey-time", required_argument, 0, 't'},
- {"max-keys", required_argument, 0, 'm'},
- {"wait-on-fork", no_argument, 0, 'w'},
- {"help", no_argument, 0, 'h'},
- {"kill", no_argument, 0, 'k'},
- {"check-running", no_argument, 0, 'c'},
- {"version", no_argument, 0, 'v'},
- {"list-keys", no_argument, 0, 'l'},
- {"key", no_argument, 0, 'K'},
- {"key-file", no_argument, 0, 'F'},
- {"key-env", no_argument, 0, 'E'},
- {0, 0, 0, 0}
- };
- int option_index = 0;
- int _help = 0, _kill = 0, _check = 0, _version = 0, r, _list_keys = 0, _key_set = 0;
- char ln[64];
- char *b;
-
- if ((b = strrchr(argv[0], '/')))
- b++;
- else
- b = argv[0];
-
-
- if (strcmp(b, "aeswepls") == 0)
- _list_keys = 1;
-
- memset(aes_key, sizeof(aes_key), 0);
-
- for (;;) {
- int c;
-
- if ((c = getopt_long(argc, argv, "nsi:t:m:whkcvlK:F:E:", long_options, &option_index)) < 0)
- break;
-
- switch (c) {
- case 'n' :
- daemonize = !daemonize;
- break;
- case 's' :
- use_syslog = !use_syslog;
- break;
- case 'i' :
- if (interface_name)
- free(interface_name);
-
- interface_name = strdup(optarg);
- break;
- case 't':
- if ((rekey_time = atoi(optarg)) <= 0) {
- daemon_log(LOG_ERR, "Rekey time too short.\n");
- exit(1);
- }
- break;
- case 'm':
- n_max_keys = atoi(optarg);
- if (n_max_keys <= 0 || n_max_keys > 4) {
- daemon_log(LOG_ERR, "--max-keys has to be between 1 and 4\n");
- exit(1);
- }
- break;
- case 'w':
- wait_on_fork = !wait_on_fork;
- break;
- case 'h':
- _help = 1;
- break;
- case 'k':
- _kill = 1;
- break;
- case 'c':
- _check = 1;
- break;
- case 'v':
- _version = 1;
- break;
- case 'l':
- _list_keys = 1;
- break;
-
- case 'K':
- daemon_log(LOG_WARNING, "WARNING: Don't use the --key option, other local users might peek on 'ps'. Proceeding");
- strncpy(ln, optarg, sizeof(ln)-1);
- ln[sizeof(ln)-1] = 0;
- _key_set = 1;
- memset(optarg, 'X', strlen(optarg));
- break;
-
- case 'E':
- if (!getenv(optarg)) {
- daemon_log(LOG_ERR, "Environment variable for key '%s' not existent.", optarg);
- exit(1);
- }
-
- strncpy(ln, getenv(optarg), sizeof(ln)-1);
- ln[sizeof(ln)-1] = 0;
- _key_set = 1;
- unsetenv(optarg);
- break;
-
- case 'F':{
- FILE *f;
- struct stat st;
-
- if (!(f = fopen(optarg, "r"))) {
- daemon_log(LOG_ERR, "Could not open key file '%s': %s", optarg, strerror(errno));
- exit(1);
- }
-
- if (fstat(fileno(f), &st) < 0) {
- daemon_log(LOG_ERR, "Failed to stat file '%s': %s", optarg, strerror(errno));
- exit(1);
- }
-
- if (st.st_mode & 077 || st.st_uid != 0) {
- daemon_log(LOG_ERR, "Key file '%s' must be owned by root and have an access mode of 0700 or less.", optarg);
- exit(1);
- }
-
- ln[0] = 0;
- fgets(ln, sizeof(ln), f);
- fclose(f);
- ln[strcspn(ln, " \n\r\t")] = 0;
- _key_set = 1;
- break;
- }
-
- default:
- daemon_log(LOG_ERR, "Unknown parameter.\n");
- exit(1);
- }
- }
-
- if (!interface_name)
- interface_name = strdup("wlan0");
-
- snprintf(pid_ident, sizeof(pid_ident), "aeswepd.%s", interface_name);
- daemon_pid_file_ident = pid_ident;
- snprintf(log_ident, sizeof(log_ident), "aeswepd(%s)", interface_name);
- daemon_log_ident = log_ident;
-
-
- if (_help) {
- usage(argv[0]);
- exit(0);
- }
-
- if (_kill) {
- if (daemon_pid_file_kill(SIGINT) < 0) {
- daemon_log(LOG_ERR, "Failed to kill daemon. (%s)", strerror(errno));
- exit(6);
- }
-
- exit(0);
- }
-
- if (_version) {
- printf("aeswepd "VERSION"\n");
- exit(0);
- }
-
- if (_check) {
- pid_t pid = daemon_pid_file_is_running();
-
- if (pid == (pid_t) -1)
- printf("aeswepd not running.\n");
- else
- printf("aeswepd process for device %s running as pid %u.\n", interface_name, pid);
-
- exit(pid == 0 ? 255 : 0);
- }
-
- if (_list_keys) {
- if (daemon_pid_file_is_running() == (pid_t) -1) {
- daemon_log(LOG_ERR, "Daemon not running!");
- exit(1);
- }
-
- do_list_keys();
- exit(0);
- }
-
- if (!_key_set) {
- daemon_log(LOG_ERR, "Not AES key specified!");
- exit(1);
- }
-
- if ((r = parse_hex(ln, aes_key, sizeof(aes_key))) < 0) {
- daemon_log(LOG_ERR, "Failed to parse AES key at position %i!", -r-1);
- exit(1);
- }
-
- if (r != 16) {
- daemon_log(LOG_ERR, "AES key to short: 16 bytes required, %i bytes read", r);
- exit(1);
- }
-
- if (!use_syslog)
- daemon_log_use = DAEMON_LOG_STDERR;
-}
-
-int main(int argc, char *argv[]) {
- struct interface *i = NULL;
- int r = 1, j;
- pid_t pid;
-
- daemon_pid_file_ident = daemon_log_ident = daemon_ident_from_argv0(argv[0]);
-
- parse_args(argc, argv);
-
- if (geteuid() != 0) {
- daemon_log(LOG_ERR, "Sorry, you need to be root to run this binary.");
- goto finish;
- }
-
- if ((pid = daemon_pid_file_is_running()) >= 0) {
- daemon_log(LOG_ERR, "Daemon already running on PID file %u", pid);
- goto finish;
-
- }
-
- if (daemonize) {
- pid_t pid;
-
- if (wait_on_fork)
- if (daemon_retval_init() < 0) {
- daemon_log(LOG_ERR, "Sorry, could not create pipe: %s", strerror(errno));
- goto finish;
- }
-
- if ((pid = daemon_fork()) < 0)
- goto finish;
-
- if (pid) {
- int c = 0;
-
- // Parent process
-
- if (wait_on_fork)
- if ((c = daemon_retval_wait(60)) < 0) {
- daemon_log(LOG_WARNING, "Killing background process.");
- kill(pid, SIGTERM);
- }
-
- r = c;
- goto finish;
- }
- }
-
-
- for (j = 0; j < MAX_WEP_KEYS; j++)
- key_map[j] = j;
-
- if (!(i = interface_open(interface_name)) < 0)
- goto finish;
-
- if (go(i) < 0)
- goto finish;
-
- r = 0;
-
-finish:
-
- if (i)
- interface_close(i);
-
- if (interface_name)
- free(interface_name);
-
- return r;
-}