changeset 1384:6c8346ed1073

Introduce basic shared-secret-based authentication
author Jorge Arellano Cid <jcid@dillo.org>
date Sun, 01 Nov 2009 16:31:59 -0300
parents 3d555d64ae5e
children eb98997886ec
files dpi/bookmarks.c dpi/file.c dpid/dpid.c dpid/misc_new.c dpid/misc_new.h dpip/dpip.c dpip/dpip.h src/IO/dpi.c
diffstat 8 files changed, 117 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/dpi/bookmarks.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpi/bookmarks.c	Sun Nov 01 16:31:59 2009 -0300
@@ -1653,7 +1653,8 @@
       if (st != 0) {
          char *err =
             DOCTYPE
-            "<HTML><body id='dillo_bm'> Error on the bookmarks server...</body></html>";
+            "<HTML><body id='dillo_bm'> Error on the bookmarks server..."
+            "      </body></html>";
          if (sock_handler_write_str(sh, 1, err) != 0) {
             return 1;
          }
@@ -1686,7 +1687,7 @@
 /*
  * -- MAIN -------------------------------------------------------------------
  */
-int main (void) {
+int main(void) {
    struct sockaddr_un spun;
    int temp_sock_descriptor;
    socklen_t address_size;
--- a/dpi/file.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpi/file.c	Sun Nov 01 16:31:59 2009 -0300
@@ -844,14 +844,30 @@
  * Serve this client.
  * (this function runs on its own thread)
  */
-static void *File_serve_client(void *data)
+static void File_serve_client(void *data)
 {
-   char *dpip_tag, *cmd = NULL, *url = NULL, *path;
+   char *dpip_tag = NULL, *cmd = NULL, *url = NULL, *path, *auth, *p;
    ClientInfo *Client = data;
 
+   /* Authenticate our client... */
+   auth = sock_handler_read(Client->sh);
+   if ((p = strchr(auth, '<')) != NULL) {
+      /* auth and dpip's tag are in one chunk, separate them */
+      dpip_tag = dStrdup(p);
+      *p = 0;
+   }
+   MSG("auth={%s}\n", auth);
+   if (a_Dpip_check_auth(auth) == -1) {
+      dFree(dpip_tag);
+      dFree(auth);
+      return;
+   }
+   dFree(auth);
+
    /* Read the dpi command */
-   dpip_tag = sock_handler_read(Client->sh);
-   _MSG("dpip_tag={%s}\n", dpip_tag);
+   if (!dpip_tag)
+      dpip_tag = sock_handler_read(Client->sh);
+   MSG("dpip_tag={%s}\n", dpip_tag);
 
    if (dpip_tag) {
       cmd = a_Dpip_get_attr(dpip_tag, "cmd");
@@ -864,8 +880,8 @@
                MSG("file.dpi:: Failed to parse 'url'\n");
          }
       }
+      dFree(cmd);
    }
-   dFree(cmd);
    dFree(dpip_tag);
 
    if (!DPIBYE && url) {
@@ -886,8 +902,6 @@
 
    /* flag the the transfer finished */
    Client->done = 1;
-
-   return NULL;
 }
 
 /*
--- a/dpid/dpid.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpid/dpid.c	Sun Nov 01 16:31:59 2009 -0300
@@ -38,6 +38,7 @@
 #define QUEUE 5
 
 volatile sig_atomic_t caught_sigchld = 0;
+char *SharedKey = NULL;
 
 /*! Remove UDS filenames 
  */
@@ -562,14 +563,14 @@
    return ok ? sock_fd : -1;
 }
 
-/*! Save the current port in a file so dillo can find it.
+/*! Save the current port and a shared secret in a file so dillo can find it.
  * \Return:
  * \li -1 on failure
  */
 int save_comm_keys(int srs_port)
 {
    int fd;
-   char *fname, ret = -1, port_str[16];
+   char *fname, ret = -1, port_str[32];
 
    fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL);
    fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
@@ -577,7 +578,7 @@
    if (fd == -1) {
       MSG("save_comm_keys: open %s\n", dStrerror(errno));
    } else {
-      snprintf(port_str, 8, "%d\n", srs_port);
+      snprintf(port_str, 16, "%d %s\n", srs_port, SharedKey);
       if (CKD_WRITE(fd, port_str) != -1)
          ret = 1;
    }
@@ -597,7 +598,9 @@
    FD_ZERO(&sock_set);
 
    if ((srs_fd = bind_socket_fd(DPID_BASE_PORT, &srs_port)) != -1) {
-      /* save port number */
+      /* create the shared secret */
+      SharedKey = a_Misc_mksecret(8);
+      /* save port number and SharedKey */
       if (save_comm_keys(srs_port) != -1) {
          FD_SET(srs_fd, &sock_set);
          ret = 1;
@@ -725,9 +728,10 @@
       if (connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
          ERRMSG("stop_active_dpis", "connect", errno);
          MSG_ERR("%s\n", dpi_attr_list[i].path);
+      } else if (write(sock_fd, SharedKey, strlen(SharedKey)) == -1) {
+         ERRMSG("stop_active_dpis", "write", errno);
       } else if (write(sock_fd, DpiBye_cmd, strlen(DpiBye_cmd)) == -1) {
-         MSG("stop_active_dpis: Error on sending BYE command: %s\n",
-             dStrerror(errno));
+         ERRMSG("stop_active_dpis", "write", errno);
       }
       a_Misc_close_fd(sock_fd);
    }
--- a/dpid/misc_new.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpid/misc_new.c	Sun Nov 01 16:31:59 2009 -0300
@@ -191,3 +191,26 @@
       MSG_ERR("a_Misc_mkfname: another round for %s \n", template);
    }
 }
+
+/*
+ * Return a new, random hexadecimal string of 'nchar' characters.
+ */
+char *a_Misc_mksecret(int nchar)
+{
+   int i;
+   uint_t random;
+   char *secret = dNew(char, nchar + 1);
+
+   srand((uint_t)(time(0) ^ getpid()));
+   random = (unsigned) rand();
+   for (i = 0; i < nchar; ++i) {
+      int hexdigit = (random >> (i * 5)) & 0x0f;
+
+      secret[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
+   }
+   secret[i] = 0;
+   MSG("a_Misc_mksecret: %s\n", secret);
+
+   return secret;
+}
+
--- a/dpid/misc_new.h	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpid/misc_new.h	Sun Nov 01 16:31:59 2009 -0300
@@ -7,5 +7,6 @@
 char *a_Misc_readtag(int sock);
 char *a_Misc_mkdtemp(char *template);
 char *a_Misc_mkfname(char *template);
+char *a_Misc_mksecret(int nchar);
 
 #endif
--- a/dpip/dpip.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpip/dpip.c	Sun Nov 01 16:31:59 2009 -0300
@@ -10,16 +10,25 @@
  *
  */
 
+#include <errno.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "../dlib/dlib.h"
 #include "dpip.h"
 #include "d_size.h"
 
+#define MSG_ERR(...)  fprintf(stderr, "[dpip]: " __VA_ARGS__)
+
+/*
+ * Local variables
+ */
 static const char Quote = '\'';
 
+
 /*
  * Basically the syntax of a dpip tag is:
  *
@@ -174,5 +183,37 @@
    return (tag ? a_Dpip_get_attr_l(tag, strlen(tag), attrname) : NULL);
 }
 
+/*
+ * Check whether the given 'auth' string equals what dpid saved.
+ * Return value: 1 if equal, -1 otherwise
+ */
+int a_Dpip_check_auth(const char *auth)
+{
+   char SharedSecret[32];
+   FILE *In;
+   char *fname, *rcline = NULL, *tail;
+   int i, port, ret = -1;
+
+   dReturn_val_if (auth == NULL, -1);
+
+   fname = dStrconcat(dGethomedir(), "/.dillo/dpid_comm_keys", NULL);
+   if ((In = fopen(fname, "r")) == NULL) {
+      MSG_ERR("[a_Dpip_check_auth] %s\n", dStrerror(errno));
+   } else if ((rcline = dGetline(In)) == NULL) {
+      MSG_ERR("[a_Dpip_check_auth] empty file: %s\n", fname);
+   } else {
+      port = strtol(rcline, &tail, 10);
+      for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
+         SharedSecret[i] = tail[i+1];
+      SharedSecret[i] = 0;
+      if (strcmp(auth, SharedSecret) == 0)
+         ret = 1;
+   }
+   dFree(rcline);
+   dFree(fname);
+
+   return ret;
+}
+
 /* ------------------------------------------------------------------------- */
 
--- a/dpip/dpip.h	Sun Nov 01 16:31:59 2009 -0300
+++ b/dpip/dpip.h	Sun Nov 01 16:31:59 2009 -0300
@@ -26,6 +26,8 @@
 char *a_Dpip_get_attr(char *tag, const char *attrname);
 char *a_Dpip_get_attr_l(char *tag, size_t tagsize, const char *attrname);
 
+int a_Dpip_check_auth(const char *auth);
+
 
 #ifdef __cplusplus
 }
--- a/src/IO/dpi.c	Sun Nov 01 16:31:59 2009 -0300
+++ b/src/IO/dpi.c	Sun Nov 01 16:31:59 2009 -0300
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <errno.h>           /* for errno */
 #include <fcntl.h>
+#include <ctype.h>           /* isxdigit */
 
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -73,7 +74,7 @@
  */
 static Klist_t *ValidConns = NULL; /* Active connections list. It holds
                                     * pointers to dpi_conn_t structures. */
-
+static char SharedKey[32];
 
 /*
  * Initialize local data
@@ -400,8 +401,8 @@
 static int Dpi_read_comm_keys(int *port)
 {
    FILE *In;
-   char *fname, *rcline = NULL;
-   int ret = -1;
+   char *fname, *rcline = NULL, *tail;
+   int i, ret = -1;
 
    fname = dStrconcat(dGethomedir(), "/.dillo/dpid_comm_keys", NULL);
    if ((In = fopen(fname, "r")) == NULL) {
@@ -409,7 +410,10 @@
    } else if ((rcline = dGetline(In)) == NULL) {
       MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
    } else {
-      *port = strtol(rcline, NULL, 10);
+      *port = strtol(rcline, &tail, 10);
+      for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
+         SharedKey[i] = tail[i+1];
+      SharedKey[i] = 0;
       ret = 1;
    }
    dFree(rcline);
@@ -593,7 +597,7 @@
 static int Dpi_connect_socket(const char *server_name, int retry)
 {
    struct sockaddr_in sin;
-   int sock_fd, err, dpi_port;
+   int sock_fd, err, dpi_port, ret=-1;
 
    /* Query dpid for the port number for this server */
    if ((dpi_port = Dpi_get_server_port(server_name)) == -1) {
@@ -621,12 +625,17 @@
                break;
          }
       }
+
+   /* send authentication Key (the server closes sock_fd on error) */
+   } else if (Dpi_blocking_write(sock_fd,SharedKey,strlen(SharedKey)) == -1) {
+      MSG_ERR("[Dpi_connect_socket] Can't send auth message.\n");
+   } else {
+      ret = sock_fd;
    }
 
-   return sock_fd;
+   return ret;
 }
 
-
 /*
  * CCC function for the Dpi module
  */