X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=net.c;h=74b8e1f7eddbc6c76bbf0e717bb05df5311b3bb5;hp=59b8616a56be2cd0dec066a5c431d3fbea9cab43;hb=a87d4a87ac7418084eb78f0bcb3accff1388df3a;hpb=2ed89c59f0efcd0a2763f47c7d3455663241e623 diff --git a/net.c b/net.c index 59b8616a..74b8e1f7 100644 --- a/net.c +++ b/net.c @@ -20,13 +20,30 @@ #include "para.h" #include "net.h" -#include "gcc-compat.h" -#include -#include "error.h" #include "string.h" +#include "error.h" + +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; +} -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); /** * initialize a struct sockaddr_in @@ -74,7 +91,7 @@ static int sendall(int fd, const char *buf, size_t *len) total += n; bytesleft -= n; if (total < *len) - PARA_DEBUG_LOG("short write (%d byte(s) left)", + PARA_DEBUG_LOG("short write (%zd byte(s) left)", *len - total); } *len = total; /* return number actually sent here */ @@ -96,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 @@ -131,7 +152,7 @@ int send_buffer(int fd, const char *buf) * * @return Positive on success, \p -E_SEND on errors. */ -__printf_2_3 int send_va_buffer(int fd, char *fmt, ...) +__printf_2_3 int send_va_buffer(int fd, const char *fmt, ...) { char *msg; int ret; @@ -160,12 +181,15 @@ __printf_2_3 int send_va_buffer(int fd, 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); @@ -189,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; } @@ -201,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; } /** @@ -254,7 +282,7 @@ int para_connect(int fd, struct sockaddr_in *their_addr) * * \sa accept(2). */ -int para_accept(int fd, void *addr, size_t size) +int para_accept(int fd, void *addr, socklen_t size) { int new_fd; @@ -332,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 * @@ -391,19 +432,21 @@ static void dispose_fds(int *fds, int num) * \param fd the socket file descriptor * \param buf the buffer to store the message * \param size the size of \a buffer - * \param cred the credentials are returned here + * + * \return negative on errors, the user id on success. * * \sa okir's Black Hats Manual * \sa recvmsg(2) */ -int recv_cred_buffer(int fd, char *buf, size_t size, struct ucred *cred) +int recv_cred_buffer(int fd, char *buf, size_t size) { char control[255]; struct msghdr msg; struct cmsghdr *cmsg; struct iovec iov; - int result; + int result = 0; int yes = 1; + struct ucred cred; setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &yes, sizeof(int)); memset(&msg, 0, sizeof(msg)); @@ -416,13 +459,13 @@ int recv_cred_buffer(int fd, char *buf, size_t size, struct ucred *cred) msg.msg_controllen = sizeof(control); if (recvmsg(fd, &msg, 0) < 0) return -E_RECVMSG; - result = -SCM_CREDENTIALS; + result = -E_SCM_CREDENTIALS; cmsg = CMSG_FIRSTHDR(&msg); while (cmsg) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { - memcpy(cred, CMSG_DATA(cmsg), sizeof(struct ucred)); - result = iov.iov_len; + memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred)); + result = cred.uid; } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { @@ -434,6 +477,7 @@ int recv_cred_buffer(int fd, char *buf, size_t size, struct ucred *cred) } return result; } +#endif /* HAVE_UCRED */ /** how many pending connections queue will hold */ #define BACKLOG 10 @@ -445,7 +489,7 @@ int recv_cred_buffer(int fd, char *buf, size_t size, struct ucred *cred) * \return The file descriptor of the created socket, negative * on errors. * - * \sa get_socket() + * \sa get_socket() * \sa setsockopt(2) * \sa bind(2) * \sa listen(2) @@ -494,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; }