summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2009-11-01 16:31:59 -0300
committerJorge Arellano Cid <jcid@dillo.org>2009-11-01 16:31:59 -0300
commitf22fea661d0755029173a21fa72f7c131ee884e7 (patch)
tree48a0f4ae5bf1225709a4571a134a5900964fd354
parente909b151a01c444a1630dc524249190d333620b2 (diff)
Introduce basic shared-secret-based authentication
-rw-r--r--dpi/bookmarks.c5
-rw-r--r--dpi/file.c28
-rw-r--r--dpid/dpid.c16
-rw-r--r--dpid/misc_new.c23
-rw-r--r--dpid/misc_new.h1
-rw-r--r--dpip/dpip.c41
-rw-r--r--dpip/dpip.h2
-rw-r--r--src/IO/dpi.c23
8 files changed, 117 insertions, 22 deletions
diff --git a/dpi/bookmarks.c b/dpi/bookmarks.c
index 648b5f82..66d8a23e 100644
--- a/dpi/bookmarks.c
+++ b/dpi/bookmarks.c
@@ -1653,7 +1653,8 @@ static int Bmsrv_parse_buf(SockHandler *sh, char *Buf)
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 @@ static void termination_handler(int signum)
/*
* -- MAIN -------------------------------------------------------------------
*/
-int main (void) {
+int main(void) {
struct sockaddr_un spun;
int temp_sock_descriptor;
socklen_t address_size;
diff --git a/dpi/file.c b/dpi/file.c
index ce7dcee7..8f18c19b 100644
--- a/dpi/file.c
+++ b/dpi/file.c
@@ -844,14 +844,30 @@ static int File_num_clients(void)
* 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 @@ static void *File_serve_client(void *data)
MSG("file.dpi:: Failed to parse 'url'\n");
}
}
+ dFree(cmd);
}
- dFree(cmd);
dFree(dpip_tag);
if (!DPIBYE && url) {
@@ -886,8 +902,6 @@ static void *File_serve_client(void *data)
/* flag the the transfer finished */
Client->done = 1;
-
- return NULL;
}
/*
diff --git a/dpid/dpid.c b/dpid/dpid.c
index 70f59a62..ecc4605e 100644
--- a/dpid/dpid.c
+++ b/dpid/dpid.c
@@ -38,6 +38,7 @@
#define QUEUE 5
volatile sig_atomic_t caught_sigchld = 0;
+char *SharedKey = NULL;
/*! Remove UDS filenames
*/
@@ -562,14 +563,14 @@ int bind_socket_fd(int base_port, int *p_port)
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 @@ int save_comm_keys(int srs_port)
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 @@ int init_ids_srs_socket()
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 @@ void stop_active_dpis(struct dp *dpi_attr_list, int numdpis)
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);
}
diff --git a/dpid/misc_new.c b/dpid/misc_new.c
index 35bc77ae..7f963aed 100644
--- a/dpid/misc_new.c
+++ b/dpid/misc_new.c
@@ -191,3 +191,26 @@ char *a_Misc_mkfname(char *template)
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;
+}
+
diff --git a/dpid/misc_new.h b/dpid/misc_new.h
index 248b2895..325451a1 100644
--- a/dpid/misc_new.h
+++ b/dpid/misc_new.h
@@ -7,5 +7,6 @@ Dstr *a_Misc_rdtag(int socket);
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
diff --git a/dpip/dpip.c b/dpip/dpip.c
index bf6667d3..f07070a5 100644
--- a/dpip/dpip.c
+++ b/dpip/dpip.c
@@ -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 @@ char *a_Dpip_get_attr(char *tag, const char *attrname)
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;
+}
+
/* ------------------------------------------------------------------------- */
diff --git a/dpip/dpip.h b/dpip/dpip.h
index 584bf89e..372b588a 100644
--- a/dpip/dpip.h
+++ b/dpip/dpip.h
@@ -26,6 +26,8 @@ char *a_Dpip_build_cmd(const char *format, ...);
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
}
diff --git a/src/IO/dpi.c b/src/IO/dpi.c
index 615e67bb..7827245c 100644
--- a/src/IO/dpi.c
+++ b/src/IO/dpi.c
@@ -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 @@ typedef struct {
*/
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_start_dpid(void)
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 @@ static int Dpi_read_comm_keys(int *port)
} 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 @@ int Dpi_get_server_port(const char *server_name)
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 @@ static int Dpi_connect_socket(const char *server_name, int retry)
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
*/