Date: Tue, 14 Aug 2007 15:23:22 GMT From: Alexey Mikhailov <karma@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 125139 for review Message-ID: <200708141523.l7EFNMqg043145@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125139 Change 125139 by karma@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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708141523.l7EFNMqg043145>