summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@anytun.org>2014-06-29 21:57:52 +0000
committerChristian Pointner <equinox@anytun.org>2014-06-29 21:57:52 +0000
commit77808f3fb99ef32830eaa6c2e636b549c1e3dfe0 (patch)
tree9853db1074e6892c06202a2dcddcf35147e4f3ad
parentdropped plans to set permissions inside generic unixdomain sockets (diff)
added keyexchange subsystem
-rw-r--r--src/Makefile1
-rw-r--r--src/keyexchange.c122
-rw-r--r--src/keyexchange.h66
-rw-r--r--src/uanytun.c69
4 files changed, 207 insertions, 51 deletions
diff --git a/src/Makefile b/src/Makefile
index 1a639ac..fe28bf1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -66,6 +66,7 @@ OBJ := log.o \
seq_window.o \
cipher.o \
unixdomain.o \
+ keyexchange.o \
uanytun.o
diff --git a/src/keyexchange.c b/src/keyexchange.c
new file mode 100644
index 0000000..0302b52
--- /dev/null
+++ b/src/keyexchange.c
@@ -0,0 +1,122 @@
+/*
+ * uAnytun
+ *
+ * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
+ * featured implementation uAnytun has no support for multiple connections
+ * or synchronisation. It is a small single threaded implementation intended
+ * to act as a client on small platforms.
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methods used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
+ *
+ * This file is part of uAnytun.
+ *
+ * uAnytun 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 3 of the License, or
+ * any later version.
+ *
+ * uAnytun 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 uAnytun. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#define _GNU_SOURCE
+#include "datatypes.h"
+
+#include "keyexchange.h"
+
+#include "log.h"
+
+int keyexchange_init(keyexchange_t* kx, const char* path_control, const char* path_data)
+{
+ if(!kx)
+ return -1;
+
+ int ret = unixdomain_init(&(kx->control_interface_), path_control);
+ if(ret) return ret;
+
+ ret = unixdomain_init(&(kx->data_interface_), path_data);
+ if(ret)
+ unixdomain_close(&(kx->control_interface_));
+
+ return ret;
+}
+
+int keyexchange_fill_fd_set(keyexchange_t* kx, fd_set* read, fd_set* write)
+{
+ return unixdomain_fill_fd_set(&(kx->data_interface_), read);
+ // ignoreing writes and control interface for now
+}
+
+void keyexchange_close(keyexchange_t* kx)
+{
+ unixdomain_close(&(kx->control_interface_));
+ unixdomain_close(&(kx->data_interface_));
+}
+
+static int keyexchange_handle_read(keyexchange_t* kx, fd_set* readyfds)
+{
+ if(FD_ISSET(kx->data_interface_.server_fd_, readyfds)) {
+ int old_fd = kx->data_interface_.client_fd_;
+ if(unixdomain_accept(&(kx->data_interface_))) {
+ return -1;
+ }
+ if(old_fd != kx->data_interface_.client_fd_) {
+ log_printf(INFO, "key exchange: new client");
+ }
+ }
+ if(FD_ISSET(kx->data_interface_.client_fd_, readyfds)) {
+ u_int8_t buf[100];
+ int len = unixdomain_read(&(kx->data_interface_), buf, sizeof(buf));
+ if(len < 0) {
+ log_printf(ERROR, "key exchange: client error!!!!!");
+ } if(!len) {
+ log_printf(INFO, "key exchange: client disconnected");
+ kx->data_interface_.client_fd_ = -1;
+ } else {
+ buf[len] = 0;
+ log_printf(DEBUG, "key exchange: received string '%s'", buf);
+ unixdomain_write(&(kx->data_interface_), buf, len);
+ }
+ }
+
+ return 0;
+}
+
+/* static int keyexchange_handle_write(keyexchange_t* kx, fd_set* readyfds) */
+/* { */
+/* // TODO: implement this */
+/* return 0; */
+/* } */
+
+int keyexchange_handle(keyexchange_t* kx, fd_set* rreadyfds, fd_set* wreadyfds)
+{
+ return keyexchange_handle_read(kx, rreadyfds);
+ // ignoreing writes for now
+}
diff --git a/src/keyexchange.h b/src/keyexchange.h
new file mode 100644
index 0000000..f1d686f
--- /dev/null
+++ b/src/keyexchange.h
@@ -0,0 +1,66 @@
+/*
+ * uAnytun
+ *
+ * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full
+ * featured implementation uAnytun has no support for multiple connections
+ * or synchronisation. It is a small single threaded implementation intended
+ * to act as a client on small platforms.
+ * The secure anycast tunneling protocol (satp) defines a protocol used
+ * for communication between any combination of unicast and anycast
+ * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel
+ * mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ * ethernet, ip, arp ...). satp directly includes cryptography and
+ * message authentication based on the methods used by SRTP. It is
+ * intended to deliver a generic, scaleable and secure solution for
+ * tunneling and relaying of packets of any protocol.
+ *
+ *
+ * Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
+ *
+ * This file is part of uAnytun.
+ *
+ * uAnytun 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 3 of the License, or
+ * any later version.
+ *
+ * uAnytun 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 uAnytun. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef UANYTUN_keyexchange_h_INCLUDED
+#define UANYTUN_keyexchange_h_INCLUDED
+
+#include "unixdomain.h"
+
+struct keyexchange_struct {
+ unixdomain_t data_interface_;
+ unixdomain_t control_interface_;
+};
+typedef struct keyexchange_struct keyexchange_t;
+
+int keyexchange_init(keyexchange_t* kx, const char* path_control, const char* path_data);
+int keyexchange_fill_fd_set(keyexchange_t* kx, fd_set* read, fd_set* write);
+void keyexchange_close(keyexchange_t* kx);
+
+int keyexchange_handle(keyexchange_t* kx, fd_set* rreadyfds, fd_set* wreadyfds);
+
+#endif
diff --git a/src/uanytun.c b/src/uanytun.c
index b95996f..da7dc3d 100644
--- a/src/uanytun.c
+++ b/src/uanytun.c
@@ -65,6 +65,7 @@
#include "seq_window.h"
+#include "keyexchange.h"
#include "cipher.h"
#ifndef NO_CRYPT
#include "key_derivation.h"
@@ -77,14 +78,19 @@ typedef u_int8_t auth_algo_t;
#include "daemon.h"
#include "sysexec.h"
-#include "unixdomain.h"
-
-int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
+int init_main_loop(options_t* opt, keyexchange_t* kx, cipher_t* c, auth_algo_t* aa, key_derivation_t* kd, seq_win_t* seq_win)
{
- int ret = cipher_init(c, opt->cipher_);
+ int ret = keyexchange_init(kx, opt->kx_control_interface_, opt->kx_data_interface_);
+ if(ret) {
+ log_printf(ERROR, "could not initialize key exchange interface");
+ return ret;
+ }
+
+ ret = cipher_init(c, opt->cipher_);
if(ret) {
log_printf(ERROR, "could not initialize cipher of type %s", opt->cipher_);
+ keyexchange_close(kx);
return ret;
}
@@ -92,6 +98,7 @@ int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_
ret = auth_algo_init(aa, opt->auth_algo_);
if(ret) {
log_printf(ERROR, "could not initialize auth algo of type %s", opt->auth_algo_);
+ keyexchange_close(kx);
cipher_close(c);
return ret;
}
@@ -99,6 +106,7 @@ int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_
ret = key_derivation_init(kd, opt->kd_prf_, opt->role_, opt->passphrase_, opt->key_.buf_, opt->key_.length_, opt->salt_.buf_, opt->salt_.length_);
if(ret) {
log_printf(ERROR, "could not initialize key derivation of type %s", opt->kd_prf_);
+ keyexchange_close(kx);
cipher_close(c);
auth_algo_close(aa);
return ret;
@@ -108,6 +116,7 @@ int init_main_loop(options_t* opt, cipher_t* c, auth_algo_t* aa, key_derivation_
ret = seq_win_init(seq_win, opt->seq_window_size_);
if(ret) {
printf("could not initialize sequence window");
+ keyexchange_close(kx);
cipher_close(c);
#ifndef NO_CRYPT
auth_algo_close(aa);
@@ -214,38 +223,6 @@ int process_sock_data(tun_device_t* dev, int fd, udp_t* sock, options_t* opt, pl
}
-
-int process_key_exchange(unixdomain_t* sock, fd_set* readyfds)
-{
- if(FD_ISSET(sock->server_fd_, readyfds)) {
- int old_fd = sock->client_fd_;
- if(unixdomain_accept(sock)) {
- return -1;
- }
- if(old_fd != sock->client_fd_) {
- log_printf(INFO, "key exchange: new client");
- }
- }
- if(FD_ISSET(sock->client_fd_, readyfds)) {
- u_int8_t buf[100];
- int len = unixdomain_read(sock, buf, sizeof(buf));
- if(len < 0) {
- log_printf(ERROR, "key exchange: client error!!!!!");
- } if(!len) {
- log_printf(INFO, "key exchange: client disconnected");
- sock->client_fd_ = -1;
- } else {
- buf[len] = 0;
- log_printf(DEBUG, "key exchange: received string '%s'", buf);
- unixdomain_write(sock, buf, len);
- }
- }
-
- return 0;
-}
-
-
-
int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
{
log_printf(INFO, "entering main loop");
@@ -257,20 +234,16 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
seq_nr_t seq_nr = 0;
fd_set readfds, readyfds;
+ keyexchange_t kx;
cipher_t c;
auth_algo_t aa;
key_derivation_t kd;
seq_win_t seq_win;
- int ret = init_main_loop(opt, &c, &aa, &kd, &seq_win);
+ int ret = init_main_loop(opt, &kx, &c, &aa, &kd, &seq_win);
if(ret)
return ret;
-
- unixdomain_t kx_data;
- unixdomain_init(&kx_data, opt->kx_data_interface_);
-
-
FD_ZERO(&readfds);
FD_SET(dev->fd_, &readfds);
int nfds = udp_fill_fd_set(sock, &readfds);
@@ -286,7 +259,7 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
while(!return_value) {
memcpy(&readyfds, &readfds, sizeof(readyfds));
- int kx_max_fd = unixdomain_fill_fd_set(&kx_data, &readyfds);
+ int kx_max_fd = keyexchange_fill_fd_set(&kx, &readyfds, NULL);
int tmp = (nfds < kx_max_fd) ? kx_max_fd : nfds;
int ret = select(tmp + 1, &readyfds, NULL, NULL, NULL);
if(ret == -1 && errno != EINTR) {
@@ -317,12 +290,7 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
break;
}
- if(FD_ISSET(kx_data.server_fd_, &readyfds) || FD_ISSET(kx_data.server_fd_, &readyfds) ||
- FD_ISSET(kx_data.client_fd_, &readyfds) || FD_ISSET(kx_data.client_fd_, &readyfds)) {
- return_value = process_key_exchange(&kx_data, &readyfds);
- if(return_value)
- break;
- }
+ keyexchange_handle(&kx, &readyfds, NULL);
udp_socket_t* s = sock->socks_;
while(s) {
@@ -335,8 +303,7 @@ int main_loop(tun_device_t* dev, udp_t* sock, options_t* opt)
}
}
- unixdomain_close(&kx_data);
-
+ keyexchange_close(&kx);
cipher_close(&c);
#ifndef NO_CRYPT
auth_algo_close(&aa);