PERFORCE change 125348 for review
Alexey Mikhailov
karma at FreeBSD.org
Sun Aug 19 07:06:49 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125348
Change 125348 by karma at 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;
}
More information about the p4-projects
mailing list