]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - net.c
Make crypo a per fd feature
[paraslash.git] / net.c
diff --git a/net.c b/net.c
index 5af967b99b13313565bb3ab830457c5cb607b414..74b8e1f7eddbc6c76bbf0e717bb05df5311b3bb5 100644 (file)
--- a/net.c
+++ b/net.c
 #include "para.h"
 #include "net.h"
 #include "string.h"
-#include <netdb.h>
 #include "error.h"
 
-extern void (*crypt_function_recv)(unsigned long len, const unsigned char *indata, unsigned char *outdata);
-extern void (*crypt_function_send)(unsigned long len, const unsigned char *indata, unsigned char *outdata);
+static crypt_function **crypt_functions;
+static unsigned max_crypt_fd;
 
+void enable_crypt(int fd, crypt_function *recv, crypt_function *send)
+{
+       if (max_crypt_fd < fd) {
+               crypt_functions = para_realloc(crypt_functions,
+                       2 * (fd + 1) * sizeof(crypt_function*));
+               max_crypt_fd = fd;
+       }
+       crypt_functions[2 * fd] = recv;
+       crypt_functions[2 * fd + 1] = send;
+       PARA_INFO_LOG("rc4 encryption activated for fd %d\n", fd);
+}
+
+void disable_crypt(int fd)
+{
+       crypt_functions[2 * fd] = NULL;
+       crypt_functions[2 * fd + 1] = NULL;
+}
 
-#ifndef HAVE_UCRED
-       struct ucred {
-       uid_t uid, pid, gid;
-};
-#endif /* HAVE_UCRED */
 
 /**
  * initialize a struct sockaddr_in
@@ -102,12 +113,16 @@ static int sendall(int fd, const char *buf, size_t *len)
 int send_bin_buffer(int fd, const char *buf, size_t len)
 {
        int ret;
+       crypt_function *cf = NULL;
+
+       if (fd <= max_crypt_fd)
+               cf = crypt_functions[2 * fd + 1];
 
        if (!len)
                PARA_CRIT_LOG("%s", "len == 0\n");
-       if (crypt_function_send) {
+       if (cf) {
                unsigned char *outbuf = para_malloc(len);
-               crypt_function_send(len, (unsigned char *)buf, outbuf);
+               (*cf)(len, (unsigned char *)buf, outbuf);
                ret = sendall(fd, (char *)outbuf, &len);
                free(outbuf);
        } else
@@ -166,12 +181,15 @@ __printf_2_3 int send_va_buffer(int fd, const char *fmt, ...)
 __must_check int recv_bin_buffer(int fd, char *buf, ssize_t size)
 {
        int n;
+       crypt_function *cf = NULL;
 
-       if (crypt_function_recv) {
+       if (fd <= max_crypt_fd)
+               cf = crypt_functions[2 * fd];
+       if (cf) {
                unsigned char *tmp = para_malloc(size);
                n = recv(fd, tmp, size, 0);
                if (n > 0)
-                       crypt_function_recv(n, tmp, (unsigned char *)buf);
+                       (*cf)(n, tmp, (unsigned char *)buf);
                free(tmp);
        } else
                n = recv(fd, buf, size, 0);
@@ -195,8 +213,11 @@ int recv_buffer(int fd, char *buf, ssize_t size)
 {
        int n;
 
-       if ((n = recv_bin_buffer(fd, buf, size - 1)) >= 0)
+       n = recv_bin_buffer(fd, buf, size - 1);
+       if (n >= 0)
                buf[n] = '\0';
+       else
+               *buf = '\0';
        return n;
 }
 
@@ -207,11 +228,12 @@ int recv_buffer(int fd, char *buf, ssize_t size)
  * \return The hostent structure or a NULL pointer if an error occurs
  * \sa gethostbyname(2)
  */
-struct hostent *get_host_info(char *host)
+int get_host_info(char *host, struct hostent **ret)
 {
        PARA_INFO_LOG("getting host info of %s\n", host);
        /* FIXME: gethostbyname() is obsolete */
-       return gethostbyname(host);
+       *ret = gethostbyname(host);
+       return *ret? 1 : -E_HOST_INFO;
 }
 
 /**
@@ -338,6 +360,19 @@ int create_pf_socket(const char *name, struct sockaddr_un *unix_addr, int mode)
        return fd;
 }
 
+#ifndef HAVE_UCRED
+       struct ucred {
+       uid_t uid, pid, gid;
+};
+ssize_t send_cred_buffer(int sock, char *buf)
+{
+       return send_buffer(sock, buf);
+}
+int recv_cred_buffer(int fd, char *buf, size_t size)
+{
+       return recv_buffer(fd, buf, size) > 0? 1 : -E_RECVMSG;
+}
+#else /* HAVE_UCRED */
 /**
  * send NULL terminated buffer and Unix credentials of the current process
  *
@@ -370,7 +405,6 @@ ssize_t send_cred_buffer(int sock, char *buf)
        msg.msg_iovlen = 1;
        msg.msg_control = control;
        msg.msg_controllen = sizeof(control);
-#ifdef HAVE_UCRED
        /* attach the ucred struct */
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_level = SOL_SOCKET;
@@ -378,7 +412,6 @@ ssize_t send_cred_buffer(int sock, char *buf)
        cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
        *(struct ucred *)CMSG_DATA(cmsg) = c;
        msg.msg_controllen = cmsg->cmsg_len;
-#endif
        ret = sendmsg(sock, &msg, 0);
        if (ret  < 0)
                ret = -E_SENDMSG;
@@ -415,9 +448,7 @@ int recv_cred_buffer(int fd, char *buf, size_t size)
        int yes = 1;
        struct ucred cred;
 
-#ifdef HAVE_UCRED
        setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &yes, sizeof(int));
-#endif
        memset(&msg, 0, sizeof(msg));
        memset(buf, 0, size);
        iov.iov_base = buf;
@@ -428,7 +459,6 @@ int recv_cred_buffer(int fd, char *buf, size_t size)
        msg.msg_controllen = sizeof(control);
        if (recvmsg(fd, &msg, 0) < 0)
                return -E_RECVMSG;
-#ifdef HAVE_UCRED
        result = -E_SCM_CREDENTIALS;
        cmsg = CMSG_FIRSTHDR(&msg);
        while (cmsg) {
@@ -445,9 +475,9 @@ int recv_cred_buffer(int fd, char *buf, size_t size)
                        }
                cmsg = CMSG_NXTHDR(&msg, cmsg);
        }
-#endif
        return result;
 }
+#endif /* HAVE_UCRED */
 
 /** how many pending connections queue will hold */
 #define BACKLOG 10
@@ -508,11 +538,12 @@ int recv_pattern(int fd, const char *pattern, size_t bufsize)
 
        if (n < len)
                goto out;
-       buf[n] = '\0';
        if (strncasecmp(buf, pattern, len))
                goto out;
        ret = 1;
 out:
+       if (ret < 0)
+               PARA_NOTICE_LOG("did not receive pattern '%s'\n", pattern);
        free(buf);
        return ret;
 }