Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Aug 2007 14:06:49 GMT
From:      Alexey Mikhailov <karma@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125348 for review
Message-ID:  <200708191406.l7JE6nSV038580@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125348

Change 125348 by karma@karma_ez on 2007/08/19 14:06:25

	- Spooling
	- Network protocol
	- Minor fixes 

Affected files ...

.. //depot/projects/soc2007/karma_audit/dlog/daemon/client.c#6 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.c#6 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/config.h#6 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/server.c#6 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/util.c#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/util.h#4 edit
.. //depot/projects/soc2007/karma_audit/dlog/daemon/worker.c#3 edit

Differences ...

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

@@ -6,6 +6,8 @@
 #include <string.h>
 #include <strings.h>
 #include <stdio.h>
+#include <libgen.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -15,16 +17,17 @@
 
 extern int errno;
 
-void *
-client_main()
+static void
+client_serve(int cs)
 {
-	int s, cs, opt = 1;
 	size_t nr = 0;
-	struct sockaddr_un n;
-	char buf[KEYWORD_MAX+PATH_MAX+1];
-	char keyword[KEYWORD_MAX];
-	char pathname[PATH_MAX];
-	char pathbuf[PATH_MAX];
+        char buf[KEYWORD_MAX+PATH_MAX+1];
+        char keyword[KEYWORD_MAX];
+        char pathname[PATH_MAX];
+        char pathbuf[PATH_MAX];
+        char filebuf[PATH_MAX];
+        char jobbuf[PATH_MAX];
+        long ts;
 	struct msghdr msg;
 	struct iovec iov[2];
 	union {
@@ -37,6 +40,9 @@
 		struct sockcred     uc;
 		char                b[sizeof (struct sockcred) + NGROUPS * sizeof (int)];
 	} cr;
+        int ans, r,fd;
+        pjob j;
+        cl_kw_hosts *hl;
 
 	cm = &c.cm;
 	
@@ -56,6 +62,78 @@
 	msg.msg_iov = iov;
 	msg.msg_iovlen = 1;
 
+        nr = recvmsg (cs, &msg, 0);
+	
+        /* TODO: could go bad here.. fix later.. */
+        if ((sscanf(buf, "%s\n%s", pathname, keyword)) < 2) {
+
+                /* TODO: wrong query */
+        }
+		
+#ifdef DEBUG
+        printf("RECEIVED: %s %s\n", pathname, keyword);
+#endif
+		
+        if (cm -> cmsg_type == SCM_CREDS) {
+                memcpy(&cr, ((struct sockcred *) CMSG_DATA(cm)),
+                       cm -> cmsg_len - sizeof(struct cmsghdr));
+#ifdef DEBUG
+                printf("UID %d, GID %d\n", cr.uc.sc_uid, cr.uc.sc_gid);
+#endif
+                if ((verify_client_access(keyword, cr.uc.sc_uid, cr.uc.sc_gid)) == 0) {
+                        /* umask! */
+                        snprintf(pathbuf, PATH_MAX, "%s", SPOOL_DIR);
+                        if (mkdir(pathbuf, 0700) == -1 && errno != EEXIST) {
+                                err_fatal("client: can't create spool dir for keyword");
+                        }
+                        else
+                        {
+                                ts = get_timestamp();
+                                snprintf(filebuf, PATH_MAX, "%s/%ld.%s",pathbuf, ts,basename(pathname));
+                                r = link(pathname, filebuf);
+                                /* errno == EEXIST ? modify timestamp */
+                                if (r < 0) {
+                                        /* Can't link to spool */
+                                        ans = 2;
+                                        write(cs, &ans, sizeof(ans));
+                                        return;
+                                }
+
+                                /* populate .hds file */
+                                snprintf(jobbuf, PATH_MAX, "%s/.%ld.%s.hds", pathbuf,ts,basename(pathname));
+                                fd = open(jobbuf, O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP);
+                                hl = client_get_hosts(keyword);
+                                while (hl == NULL) {
+                                        bzero(&j, sizeof(j));
+                                        memcpy(&(j.sa), &(hl->hs->s), sizeof(struct sockaddr));
+                                        j.done = 0;
+                                        write(fd, &j, sizeof(j));
+                                }
+                                close(fd);
+                                /* we re done */
+                                ans = 0;
+                                write(cs, &ans, sizeof(ans));
+                        }
+                }
+                else
+                {
+                        /* Permission denied */
+                        ans = 1;
+                        write(cs, &ans, sizeof(ans));
+                        return ;
+                }
+        } else {
+                /* TODO: can't check permissions. wrong query */
+                fprintf(stderr,"client: can't check permissions");
+        }
+}
+
+void *
+client_main()
+{
+	int s, cs, opt = 1;
+	struct sockaddr_un n;
+
 	s = socket(PF_LOCAL, SOCK_STREAM, 0);
 
 	if (s < 0) {
@@ -81,44 +159,7 @@
 	}
 	
 	while ((cs = accept(s, (struct sockaddr *) NULL, NULL)) >= 0) {
-		
-		nr = recvmsg (cs, &msg, 0);
-		
-		/* TODO: could go bad here.. fix later.. */
-		if ((sscanf(buf, "%s\n%s", pathname, keyword)) < 2) {
-
-			/* TODO: wrong query */
-		}
-		
-#ifdef DEBUG
-		printf("RECEIVED: %s %s\n", pathname, keyword);
-#endif
-		
-		if (cm -> cmsg_type == SCM_CREDS) {
-			memcpy(&cr, ((struct sockcred *) CMSG_DATA(cm)),
-			    cm -> cmsg_len - sizeof(struct cmsghdr));
-#ifdef DEBUG
-			printf("UID %d, GID %d\n", cr.uc.sc_uid, cr.uc.sc_gid);
-#endif
-			if ((verify_client_access(keyword, 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) {
-					err_fatal("client: can't create spool dir for keyword");
-				}
-				else
-				{
-#if 0
-					snprintf(pathbuf, PATH_MAX, "%s/%ld.%s");
-#endif
-				}
-			}
-			
-		} else {
-			/* TODO: can't check permissions. wrong query */
-			fprintf(stderr,"client: can't check permissions");
-		}
+                client_serve(cs);
 		close(cs);
 	}
         return 0;

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

@@ -21,17 +21,6 @@
 	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;
 	host_ll *hs;

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

@@ -4,6 +4,22 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+typedef struct pjob {
+        struct sockaddr sa;
+        int    done;
+} pjob;
+
+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;
+
 TTree * client_kw_tree;
 TTree * server_kw_tree;
 TTree * client_host_tree;
@@ -24,4 +40,7 @@
 
 int verify_client_access (const char * keyword, uid_t uid, gid_t gid);
 char * verify_server_access (struct sockaddr * sa, const char * keyword);
+
+cl_kw_hosts * client_get_hosts (const char * keyword);
+
 #endif

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

@@ -5,10 +5,12 @@
 #include <limits.h>
 #include <stdio.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <errno.h>
 #include <strings.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <netinet/in.h>
 #include <openssl/ssl.h>
 #include <openssl/err.h>
@@ -143,10 +145,14 @@
 serve_conn (int clifd, struct sockaddr *sacli)
 {
         SSL *ssl;
+        int ans,fd;
         size_t e;
         char buf[KEYWORD_MAX+FILENAME_MAX+2];
+        char recvbuf[BUFSIZ];
         char filename[FILENAME_MAX+1];
         char keyword[KEYWORD_MAX+1];
+        char *path;
+        char spoolfile[PATH_MAX];
 
         if (myssl_accept(clifd, ssl) != 0) {
                 fprintf(stderr, "Failed SSL negotitation\n");
@@ -160,25 +166,82 @@
         
         if (search_bad_chars(buf) != 0)
         {
-                SSL_write(ssl, "Malformed request", strlen("Malformed request"));
+                ans = 1;
+                SSL_write(ssl, &ans, sizeof(ans));
                 SSL_shutdown(ssl);
                 close(clifd);
                 SSL_free(ssl);
                 return;
         }
 
-        /* TODO: Could go bad here? */
-        e = sscanf(buf, "%s\n%s", keyword, filename);
+        sscanf(buf, "%s\n%s", keyword, filename);
 
-        /* TODO: Verify access + receive file */
-        if (verify_server_access(sacli, keyword))
+        if ((path = verify_server_access(sacli, keyword)) != NULL)
+        {
+                /* OK, permission granted */
+                snprintf(spoolfile, sizeof(spoolfile), "%s/%s", path, filename);
+                /* umask! */
+                fd = open(spoolfile, O_CREAT | O_TRUNC, S_IRUSR | S_IRGRP);
+                if (fd == -1) {
+                        /* Can't create job file */
+                        fprintf(stderr, "server: open() for %s\n", spoolfile);
+                        ans = 2;
+                        SSL_write(ssl, &ans, sizeof(ans));
+                        SSL_shutdown(ssl);
+                        close(clifd);
+                        SSL_free(ssl);
+                        return;
+                }
+                while ((e = SSL_read(ssl, recvbuf, sizeof(recvbuf))) > 0)
+                {
+                        write(fd, recvbuf, sizeof(recvbuf));
+                }
+                if (e == 0)
+                {
+                        /* EOF */
+                        ans = 0;
+                        SSL_write(ssl, &ans, sizeof(int));
+                        SSL_read(ssl, &ans, sizeof(int));
+                        if (ans == 0) {
+                                /* ACK */
+                                SSL_shutdown(ssl);
+                                close(fd);
+                                close(clifd);
+                                SSL_free(ssl);
+                                return;
+                        } else {
+                                /* No ACK */
+                                ans = 5;
+                                SSL_write(ssl, &ans, sizeof(int));
+                                SSL_shutdown(ssl);
+                                close(fd);
+                                unlink(spoolfile);
+                                close(clifd);
+                                SSL_free(ssl);
+                                return;
+                        }
+                } else {
+                        /* SSL_read */
+                        fprintf(stderr, "server: SSL_read()\n");
+                        close(fd);
+                        unlink(spoolfile);
+                        ans = 4;
+                        SSL_write(ssl, &ans, sizeof(ans));
+                        SSL_shutdown(ssl);
+                        close(clifd);
+                        SSL_free(ssl);
+                }
+        }
+        else
         {
-                
+                /* Permission denied */
+                ans = 3;
+                SSL_write(ssl, &ans, sizeof(ans));
+                SSL_shutdown(ssl);
+                close(clifd);
+                SSL_free(ssl);
+                return;
         }
-
-#ifdef DEBUG
-        printf("received keyword %s with filename %s", keyword, filename);
-#endif
 }
 
 /* Try to perform SSL handshake at clifd */

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

@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 
 #include "util.h"
 
@@ -38,3 +39,11 @@
         if (nl == 0) return 1;
         return 0;
 }
+
+long
+get_timestamp ()
+{
+        struct timeval tp;
+        gettimeofday(&tp, NULL);
+        return tp.tv_sec;
+}

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

@@ -7,5 +7,6 @@
 
 void err_fatal (const char * msg);
 int  search_bad_chars (const char * msg);
+long get_timestamp();
 
 #endif

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

@@ -1,11 +1,17 @@
 #include "../config.h"
+#include "config.h"
 #include "util.h"
 #include <signal.h>
 #include <libgen.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
 #include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
 #include <pthread.h>
 #include <openssl/x509.h>
 #include <openssl/err.h>
@@ -14,20 +20,85 @@
 static sigset_t mask;
 static SSL_CTX *sslContext=NULL;
 
+static int ssl_sendfile (const char *, const char *, struct sockaddr *);
+
+static int
+check_job (struct dirent * d)
+{
+        char *name, pathbuf[PATH_MAX];
+        int r;
+
+        name = d -> d_name;
+
+        if (name[0] == '.')
+                return 0;
+
+        snprintf(pathbuf, PATH_MAX, "%s/.%s.hds",SPOOL_DIR, name);
+        if ((r = open(pathbuf, O_RDONLY)) < 0) {
+                fprintf(stderr, "worker: weird spool entry %s\n", pathbuf);
+                return 0;
+        } else {
+                close(r);
+                return 1;
+        }
+}
+
 /* Go through spool and perform pending tasks */
 static void
 go_queue()
 {
-        
+        struct dirent **namelist;
+        int n, i, j,isdone;
+        char file[PATH_MAX];
+        char jobfile[PATH_MAX];
+        struct stat st;
+        int ffd, jfd,njobs,r;
+        off_t filesize;
+        pjob *win;
+        char keyword[KEYWORD_MAX];
+
+        n = scandir(SPOOL_DIR, &namelist, check_job, alphasort);
+
+        for (i = 0; i < n; i++)
+        {
+                isdone = 1;
+                snprintf(file, PATH_MAX, "%s/%s",SPOOL_DIR, namelist[i] -> d_name);
+                snprintf(jobfile, PATH_MAX, "%s/.%s.hds",SPOOL_DIR, namelist[i] -> d_name);
+                jfd = open(jobfile, O_RDWR);
+                stat(file, &st);
+                filesize = st.st_size;
+                win = mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, ffd, 0);
+                if (win == MAP_FAILED) {
+                        err_fatal("worker: mmap()");
+                }
+                njobs = filesize / sizeof(pjob);
+                for (j = 0; j < njobs; j++)
+                {
+                        if (win[j].done == 0) {
+                                r = ssl_sendfile(file, keyword, &(win[j].sa));
+                                if (r == 0)
+                                        win[j].done = 1;
+                                else
+                                        isdone = 0;
+                        }
+                }
+                close(jfd);
+                if (isdone == 1) {
+                        /* we're done with this entry */
+                        unlink(file);
+                        unlink(jobfile);
+                }
+        }
 }
 
 /* Perform sending log file out */
 static int
 ssl_sendfile (const char * pathname, const char * keyword, struct sockaddr * to)
 {
-        int sock, r, ans;
+        int sock, r, ans, fd;
         SSL* ssl;
         X509* cert;
+        char sndbuf[BUFSIZ];
         char buf[FILENAME_MAX + KEYWORD_MAX + 2];
 
         sock = socket (AF_INET, SOCK_STREAM, 0);
@@ -91,7 +162,24 @@
                 return 1;
         }
         
-        /* TODO: OK, sending flle goes here */
+        fd = open(pathname, O_RDONLY);
+
+        while ((r = read(fd, sndbuf, sizeof(sndbuf))) > 0) {
+                SSL_write(ssl, sndbuf, sizeof(sndbuf));
+        }
+
+        SSL_read(ssl, &r, sizeof(r));
+
+        if (r != 0) {
+                fprintf(stderr, "worker: proto error\n");
+                SSL_shutdown(ssl);
+                close(sock);
+                return 1;
+        }
+
+        SSL_shutdown(ssl);
+        close(sock);
+
         return 0;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708191406.l7JE6nSV038580>