diff options
author | Jorge Arellano Cid <jcid@dillo.org> | 2009-11-01 16:31:59 -0300 |
---|---|---|
committer | Jorge Arellano Cid <jcid@dillo.org> | 2009-11-01 16:31:59 -0300 |
commit | f22fea661d0755029173a21fa72f7c131ee884e7 (patch) | |
tree | 48a0f4ae5bf1225709a4571a134a5900964fd354 | |
parent | e909b151a01c444a1630dc524249190d333620b2 (diff) |
Introduce basic shared-secret-based authentication
-rw-r--r-- | dpi/bookmarks.c | 5 | ||||
-rw-r--r-- | dpi/file.c | 28 | ||||
-rw-r--r-- | dpid/dpid.c | 16 | ||||
-rw-r--r-- | dpid/misc_new.c | 23 | ||||
-rw-r--r-- | dpid/misc_new.h | 1 | ||||
-rw-r--r-- | dpip/dpip.c | 41 | ||||
-rw-r--r-- | dpip/dpip.h | 2 | ||||
-rw-r--r-- | src/IO/dpi.c | 23 |
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; @@ -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 */ |