PERFORCE change 125139 for review

Alexey Mikhailov karma at FreeBSD.org
Tue Aug 14 08:23:23 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=125139

Change 125139 by karma at karma_ez on 2007/08/14 15:22:50

	* Server side SSL implementation
	* Host are resolved while config parsing and we hold sockaddr-s for future use
	* Worker thread skeleton

Affected files ...

.. //depot/projects/soc2007/karma_audit/dlog/config.h#5 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/client.c#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.c#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.h#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/dummy_certificate.pem#1 add
.. //depot/projects/soc2007/karma_audit/dlog/daemon/server.c#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/util.c#2 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/util.h#2 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/worker.c#1 add
.. //depot/projects/soc2007/karma_audit/dlog/daemon/worker.h#1 add
.. //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.c#4 edit

Differences ...

==== //depot/projects/soc2007/karma_audit/dlog/config.h#5 (text+ko) ====

@@ -12,8 +12,15 @@
 #define CLIENT_CONFIG "client.conf"
 #define SERVER_CONFIG "server.conf"
 
-#define SERVER_PORT "9991"
+#define SERVER_PORT 9991
 
 #define QLEN 10
 
+#define SPOOL_DIR "/tmp/dlogd"
+
+#define SERVER_CERT "dummy_certificate.pem"
+#define SERVER_KEY  "dummy_certificate.pem"
+
+#define WORKER_PERIOD 120
+
 #endif

==== //depot/projects/soc2007/karma_audit/dlog/daemon/client.c#4 (text+ko) ====

@@ -1,6 +1,7 @@
 #include "../config.h"
 #include <errno.h>
 #include <string.h>
+#include <stdio.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -18,6 +19,7 @@
 	char buf[KEYWORD_MAX+PATH_MAX+1];
 	char keyword[KEYWORD_MAX];
 	char pathname[PATH_MAX];
+	char pathbuf[PATH_MAX];
 	struct msghdr msg;
 	struct iovec iov[2];
 	union {
@@ -93,14 +95,22 @@
 #ifdef DEBUG
 			printf("UID %d, GID %d\n", cr.uc.sc_uid, cr.uc.sc_gid);
 #endif
-			if ((verify_client_access(cr.uc.sc_uid, cr.uc.sc_gid)) == 0)
-			{
+			if ((verify_client_access(cr.uc.sc_uid, cr.uc.sc_gid)) == 0) {
 				/* TODO: add logfile to spool here */
+				/* TODO: umask? */
+				snprintf(pathbuf, PATH_MAX, "%s/%s", SPOOL_DIR, keyword);
+				if (mkdir(pathbuf, "0700") == -1 && errno != EEXIST) {
+					fprintf(stderr, "can't create spool dir for keyword");
+				}
+				else
+				{
+					snprintf(pathbuf, PATH_MAX, "%s/%ld.%s");
+				}
 			}
 			
 		} else {
 			/* TODO: can't check permissions. wrong query */
-			printf("can't check permissions");
+			fprintf(stderr,"can't check permissions");
 		}
 		close(cs);
 	}

==== //depot/projects/soc2007/karma_audit/dlog/daemon/config.c#4 (text+ko) ====

@@ -7,6 +7,10 @@
 #include <errno.h>
 #include <grp.h>
 #include <stdio.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
 
 cl_kw_access  * cka   = NULL;
 cl_kw_access  * pcka  = NULL;
@@ -14,6 +18,8 @@
 cl_kw_hosts   * pckh  = NULL;
 sv_kw_hostdir * svhd  = NULL;
 sv_kw_hostdir * psvhd = NULL;
+host_ll       * clh   = NULL;
+host_ll       * pclh  = NULL;
 
 extern int errno;
 extern FILE * yyin;
@@ -24,10 +30,13 @@
 {
 	client_kw_tree = allocate_ttree();
 	server_kw_tree = allocate_ttree();
+        client_host_tree = allocate_ttree();
+        server_host_tree = allocate_ttree();
 	(void)parse_client_config();
 }
 #endif
 
+/* Parse client configuration file */
 void
 parse_client_config (void)
 {
@@ -48,6 +57,7 @@
 	}
 }
 
+/* Parse server configuration file */
 void
 parse_server_config (void)
 {
@@ -68,6 +78,7 @@
 	}
 }
 
+/* Add keyword to client tree and insert linked list there */
 int
 add_client_keyword (char * keyword)
 {
@@ -82,10 +93,12 @@
 	pcka = NULL;
 	ckh = NULL;
 	pckh = NULL;
+        clh = NULL;
 
 	return 0;
 }
 
+/* Build linked list of user permissions */
 int
 add_client_kw_access (char * id, char * val)
 {
@@ -168,9 +181,41 @@
 	return 1;
 }
 
+/* Build linked list of hosts */
 int
 add_client_kw_host (char * host)
 {
+        struct addrinfo hints, *h, *hh;
+        int r;
+
+        bzero(&hints, sizeof(hints));
+        hints.ai_family = AF_INET;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = IPPROTO_TCP;
+
+        r = getaddrinfo(host, NULL, &hints, &h);
+
+        if (r != 0) {
+                fprintf(stderr, "Failed getaddrinfo() for host \"%s\": %s",
+                        host, gai_strerror(r));
+                return 1;
+        }
+
+        clh = xmalloc(sizeof(host_ll));
+        pclh = clh;
+        hh = h;
+
+        for ( ; hh != NULL; hh = hh -> ai_next)
+        {
+                memcpy(&(pclh -> s), hh -> ai_addr, sizeof(struct sockaddr));
+                pclh -> next = xmalloc(sizeof(host_ll));
+                pclh = pclh -> next;
+        }
+
+        bzero(&(pclh -> s), sizeof(struct sockaddr));
+
+        freeaddrinfo(h);
+        
 	if (ckh == NULL)
 	{
 		ckh = xmalloc(sizeof(cl_kw_hosts));
@@ -183,7 +228,8 @@
 		pckh -> next = NULL;
 	}
 
-	pckh -> host = strdup (host);
+        pckh -> host = strdup (host);
+        pckh -> hs   = clh;
 
 	if (pckh -> host == NULL)
 	{
@@ -199,6 +245,7 @@
 	return 0;
 }
 
+/* Add keyword to server tree and attach linked list to it */
 int
 add_server_keyword (char * keyword)
 {
@@ -214,9 +261,41 @@
 	return 0;
 }
 
+/* Add hostname\directory pair to linked list */
 int
 add_server_kw_host (char * hostname, char * dir)
 {
+        struct addrinfo hints, *h, *hh;
+        int r;
+
+        bzero(&hints, sizeof(hints));
+        hints.ai_family = AF_INET;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_protocol = IPPROTO_TCP;
+
+        r = getaddrinfo(hostname, NULL, &hints, &h);
+
+        if (r != 0) {
+                fprintf(stderr, "Failed getaddrinfo() for host \"%s\": %s",
+                        hostname, gai_strerror(r));
+                return 1;
+        }
+
+        clh = xmalloc(sizeof(host_ll));
+        pclh = clh;
+        hh = h;
+
+        for ( ; hh != NULL; hh = hh -> ai_next)
+        {
+                memcpy(&(pclh -> s), hh -> ai_addr, sizeof(struct sockaddr));
+                pclh -> next = xmalloc(sizeof(host_ll));
+                pclh = pclh -> next;
+        }
+
+        bzero(&(pclh -> s), sizeof(struct sockaddr));
+
+        freeaddrinfo(h);
+
 	if (svhd == NULL)
 	{
 		svhd = xmalloc(sizeof(sv_kw_hostdir));
@@ -231,6 +310,7 @@
 
 	psvhd -> host = strdup (hostname);
 	psvhd -> dir = strdup (dir);
+        psvhd -> hs = clh;
 
 	if (psvhd -> host == NULL || psvhd -> dir == NULL)
 	{
@@ -290,3 +370,9 @@
 	
 	return (-2); /* access denied */
 }
+
+char *
+verify_server_access (struct sockaddr * sa, const char * keyword)
+{
+        return 0;
+}

==== //depot/projects/soc2007/karma_audit/dlog/daemon/config.h#4 (text+ko) ====

@@ -2,6 +2,7 @@
 #define DLOG_CONFIG_H
 #include "ttree.h"
 #include <sys/types.h>
+#include <sys/socket.h>
 
 typedef struct client_kw_access {
 	int id;
@@ -10,13 +11,20 @@
 	struct client_kw_access * next;
 } cl_kw_access;
 
+typedef struct host_ll {
+        struct sockaddr s;
+        struct host_ll *next;
+} host_ll;
+
 typedef struct client_kw_host {
 	char *host;
+        host_ll *hs;
 	struct client_kw_host * next;
 } cl_kw_hosts;
 
 typedef struct server_kw_host {
-	char *host;
+        char *host;
+	host_ll *hs;
 	char *dir;
 	struct server_kw_host * next;
 } sv_kw_hostdir;
@@ -47,5 +55,5 @@
 void parse_server_config();
 
 int verify_client_access (const char * keyword, uid_t uid, gid_t gid);
-
+char * verify_server_access (struct sockaddr * sa, const char * keyword);
 #endif

==== //depot/projects/soc2007/karma_audit/dlog/daemon/server.c#4 (text+ko) ====

@@ -3,16 +3,21 @@
 #include <limits.h>
 #include <stdio.h>
 #include <sys/socket.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
 
-void
-server_serve (int s)
-{
-	return;
-}
+static SSL_CTX  *sslContext = NULL;
+extern int errno;
+
+static void serve_conn(int, struct sockaddr *);
+static int  myssl_accept(int, SSL*);
 
 void
 server_main()
 {
+#if 0
 	int s,err;
 	struct addrinfo *aip, *ailist;
 	struct addrinfo hint;
@@ -63,5 +68,125 @@
 		server_serve(s);
 		return;
 	}
+#endif
+        int sockfd, clifd;
+        size_t l;
+        struct sockaddr_in sockaddr, sockaddr_cli;
+
+        /* SSL initialization */
+        SSL_load_error_strings();
+        SSLeay_add_ssl_algorithms();
+        sslContext = SSL_CTX_new(SSLv23_method());
+
+        if (sslContext == NULL) {
+                fprintf(stderr, "Error allocating context: %s\n", ERR_error_string(ERR_get_error(),NULL));
+                exit(1);
+        }
+
+        if(!SSL_CTX_use_certificate_file(sslContext, SERVER_CERT, SSL_FILETYPE_PEM)) {
+                fprintf(stderr, "SSL: error reading certificate from file %s: %s\n", SERVER_CERT, ERR_error_string(ERR_get_error(), NULL));
+                exit(1);
+        }
+
+#ifdef KEY
+        if (!SSL_CTX_use_PrivateKey_file(sslContext, SERVER_KEY, SSL_FILETYPE_PEM)) {
+                fprintf(stderr, "SSL: error reading key from file %s: %s\n", SERVER_KEY, ERR_error_string(ERR_get_error(), NULL));
+                exit(1);
+        }
+      
+        if (!SSL_CTX_check_private_key(sslContext)) {
+                fprintf(stderr,"SSL: private key does not match the certificate public key\n");
+                exit(1);
+        }
+#endif
+
+        SSL_CTX_set_client_CA_list(sslContext, SSL_load_client_CA_file(SERVER_CERT));
+        
+        /* Socket initialization */
+        if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+                err_fatal("Can't create server socket");
+        
+        bzero(&sockaddr, sizeof(sockaddr));
+        sockaddr.sin_family = AF_INET;
+        sockaddr.sin_addr.s_addr = INADDR_ANY;
+        sockaddr.sin_port = htons(SERVER_PORT);
+
+        if ((bind(sockfd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) < 0)
+                err_fatal("Can't bind server socket");
+
+        if ((listen(sockfd, QLEN)) < 0)
+                err_fatal("Can't listen server socket");
+
+        l = sizeof(sockaddr_cli);
+
+        /* Go loop */
+        for (;;) {
+                clifd = accept(sockfd, (struct sockaddr *)&sockaddr_cli, &l);
+                if (clifd < 0)
+                {
+                        if (errno = EINTR)
+                                continue;
+                        err_fatal("accept()");
+                }
+                printf("%d\n",clifd);
+                serve_conn(clifd, (struct sockaddr *)&sockaddr_cli);
+        }
 }
 
+static void
+serve_conn (int clifd, struct sockaddr *sacli)
+{
+        SSL *ssl;
+        size_t e;
+        char buf[KEYWORD_MAX+FILENAME_MAX+2];
+        char filename[FILENAME_MAX+1];
+        char keyword[KEYWORD_MAX+1];
+#ifdef DEBUG
+        printf("got connection from %lx\n", ((struct sockaddr_in *)sacli)->sin_addr.s_addr);
+#endif
+        if (myssl_accept(clifd, ssl) != 0) {
+                fprintf(stderr, "Failed SSL negotitation\n");
+                return;
+        }
+
+        /* Great, we're here already :) SSL handshake done */
+        printf("%d\n", sizeof(buf));
+        e = SSL_read(ssl, buf, sizeof(buf) - 1);
+        buf[e] = '\0';
+        
+        if (search_bad_chars(buf) != 0)
+        {
+                SSL_write(ssl, "Malformed request", strlen("Malformed request"));
+                SSL_shutdown(ssl);
+                close(clifd);
+                SSL_free(ssl);
+                return;
+        }
+
+        /* TODO: Could go bad here? */
+        e = sscanf(buf, "%s\n%s", keyword, filename);
+
+#ifdef DEBUG
+        printf("received keyword %s with filename %s", keyword, filename);
+#endif
+}
+
+static int
+myssl_accept (int clifd, SSL *ssl)
+{
+        if ((ssl = SSL_new(sslContext)) == NULL) {
+                fprintf(stderr, "SSL_new(): %s\n", ERR_error_string(ERR_get_error(), NULL));
+                return -1;
+        }
+
+        SSL_set_fd(ssl, clifd);
+        
+        if (SSL_accept(ssl) <= 0) {
+                fprintf(stderr, "SSL_accept(): %s\n", ERR_error_string(ERR_get_error(), NULL));
+                return -1;
+        }
+#ifdef DEBUG
+        fprintf(stderr, "SSL_get_cipher(): %s\n", SSL_get_cipher(ssl));
+#endif
+        return 0;
+}

==== //depot/projects/soc2007/karma_audit/dlog/daemon/util.c#2 (text+ko) ====

@@ -21,3 +21,17 @@
 	fprintf(stderr, "Fatal error: %s\n", msg);
 	exit(1);
 }
+
+int
+search_bad_chars (const char * msg)
+{
+        int i, nl = 0;
+        for (i = 0; i < strlen(msg) - 1; i++) {
+                if (msg[i] == '\n' && ++nl > 1)
+                        return 1;
+                if (msg[i] == '/')
+                        return 1;
+        }
+        if (nl == 0) return 1;
+        return 0;
+}

==== //depot/projects/soc2007/karma_audit/dlog/daemon/util.h#2 (text+ko) ====


==== //depot/projects/soc2007/karma_audit/dlog/lib/libdlogd.c#4 (text+ko) ====

@@ -24,7 +24,7 @@
 int
 dlogd_submit (const char * pathname, const char * keyword)
 {
-	int fd, rc;
+	int fd, rc, an = -1;
 	size_t len;
 	char buf[KEYWORD_MAX + PATH_MAX + 1];
 	struct msghdr msg;
@@ -77,10 +77,19 @@
 		return (-5);  /* can't sendmsg */
 	}
 
+        if ((read (fd, an, sizeof(int))) < 0)
+        {
+                close(fd);
+                return (-6); /* can't read */
+        }
+            
+        if (an != 0)
+        {
+                return (-7); /* bad server response */
+        }
+
 	rc = close(fd);
 
-	printf("close returned %d\n", rc);
-	
 	return 0;
 }
 


More information about the p4-projects mailing list