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