[PATCH] openconnect: add initial support for openconnect ssl vpn.

openconnect at lakedaemon.net openconnect at lakedaemon.net
Thu Jul 14 21:38:47 EDT 2011


From: Jason Cooper <cyanogen at lakedaemon.net>


Signed-off-by: Jason Cooper <cyanogen at lakedaemon.net>
---
 Android.mk    |    2 +-
 mtpd.c        |   52 ++++++++++++++++++++++++++++++++-
 mtpd.h        |    1 +
 openconnect.c |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 139 insertions(+), 3 deletions(-)
 create mode 100644 openconnect.c

diff --git a/Android.mk b/Android.mk
index b74e13d..344e438 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,7 +19,7 @@ ifneq ($(TARGET_SIMULATOR),true)
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := mtpd.c l2tp.c pptp.c openvpn.c
+LOCAL_SRC_FILES := mtpd.c l2tp.c pptp.c openvpn.c openconnect.c
 LOCAL_SHARED_LIBRARIES := libcutils libcrypto
 LOCAL_CFLAGS := -DANDROID_CHANGES
 LOCAL_C_INCLUDES := external/openssl/include frameworks/base/cmds/keystore
diff --git a/mtpd.c b/mtpd.c
index fdeb887..d886799 100644
--- a/mtpd.c
+++ b/mtpd.c
@@ -43,7 +43,8 @@ int the_socket = -1;
 extern struct protocol l2tp;
 extern struct protocol pptp;
 extern struct protocol openvpn;
-static struct protocol *protocols[] = {&l2tp, &pptp, &openvpn, NULL};
+extern struct protocol openconnect;
+static struct protocol *protocols[] = {&l2tp, &pptp, &openvpn, &openconnect, NULL};
 static struct protocol *the_protocol;
 
 static int pppd_argc;
@@ -316,6 +317,53 @@ void create_socket(int family, int type, char *server, char *port)
     log_print(INFO, "Connection established (socket = %d)", the_socket);
 }
 
+void start_daemon_pipe(char *name, char *args[], char *data, int datalen)
+{
+  int fd[2];
+
+    if (pppd_pid) {
+        log_print(WARNING, "%s is already started (pid = %d)", name, pppd_pid);
+        return;
+    }
+
+    log_print(INFO, "Starting %s", name);
+
+    pipe(fd);
+
+    pppd_pid = fork();
+    if (pppd_pid < 0) {
+        log_print(FATAL, "Fork() %s", strerror(errno));
+        exit(SYSTEM_ERROR);
+    }
+
+    if (pppd_pid == 0) {
+        /* child, receiver of data on stdin */
+        close(fd[1]);
+        dup2(fd[0], 0);
+
+        int fdc = open("/dev/null",O_RDWR|O_CREAT|O_TRUNC);
+        dup2(fdc, 1);
+        dup2(fdc, 2);
+
+        execvp(name, args);
+
+        log_print(FATAL, "Exec() %s", strerror(errno));
+        close(fd[0]);
+        exit(1); /* Pretending a fatal error in pppd. */
+    } else {
+        /* parent, transmitter of data */
+        close(fd[0]);
+
+        if(data != NULL && datalen >= 0) {
+            write(fd[1], data, datalen);
+            free(data);
+        }
+        close(fd[1]);
+    }
+
+    log_print(INFO, "%s started (pid = %d)", name, pppd_pid);
+}
+
 void start_daemon(char *name, char *args[], int pppox)
 {
   int i;
@@ -338,7 +386,7 @@ void start_daemon(char *name, char *args[], int pppox)
 	dup2(fd, 0);
 	dup2(fd, 1);
 	dup2(fd, 2);
-      
+
         execvp(name, args);
         log_print(FATAL, "Exec() %s", strerror(errno));
         exit(1); /* Pretending a fatal error in pppd. */
diff --git a/mtpd.h b/mtpd.h
index 0cdc509..7cab37c 100644
--- a/mtpd.h
+++ b/mtpd.h
@@ -49,6 +49,7 @@ void log_print(int level, char *format, ...);
 void create_socket(int family, int type, char *server, char *port);
 void start_pppd(int pppox);
 void start_daemon(char *name, char *args[], int pppox);
+void start_daemon_pipe(char *name, char *args[], char *data, int datalen);
 
 /* Each protocol must implement everything defined in this structure. Note that
  * timeout intervals are in milliseconds, where zero means forever. To indicate
diff --git a/openconnect.c b/openconnect.c
new file mode 100644
index 0000000..c5364b1
--- /dev/null
+++ b/openconnect.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 Jason Cooper <cyanogen at lakedaemon.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* copied from openvpn.c which was (same license):
+ *
+ * Copyright (C) 2010 James Bottomley <James.Bottomley at suse.de>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "mtpd.h"
+
+static int openconnect_connect(int argc, char **argv)
+{
+    char *args[argc + 10];
+    char *data;
+    int i, j;
+
+    /* blank it out */
+    for (i=0; i < (argc + 10); i++)
+        args[i] = NULL;
+
+    args[0] = "openconnect";
+    /* for privilege separation, drop to user vpn */
+    args[1] = "-U";
+    args[2] = "vpn";
+    /* use this script to configure routes/dns */
+    args[3] = "-s";
+    args[4] = "su -c /system/xbin/openconnect-up.sh";
+
+
+    for (i = 0, j = 5; i < argc; i++, j++) {
+        args[j] = argv[i];
+
+        if(strcmp("--passwd-on-stdin", argv[i]) == 0) {
+            data = strdup(argv[i + 1]);
+            i++;
+        } else if(strcmp("--cookie-on-stdin", argv[i]) == 0) {
+            data = strdup(argv[i + 1]);
+            i++;
+        }
+    }
+
+    start_daemon_pipe("openconnect", args, data, strlen(data));
+
+    return 0;
+}
+
+static void openconnect_shutdown(void)
+{
+}
+
+struct protocol openconnect = {
+    .name = "openconnect",
+    .usage = "[openconnect args]",
+    .connect = openconnect_connect,
+    .process = NULL,
+    .timeout = NULL,
+    .shutdown = openconnect_shutdown,
+};
-- 
1.7.0.4




More information about the openconnect-devel mailing list