]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 'crypt' into next
authorAndre Noll <maan@systemlinux.org>
Sat, 4 Jul 2009 14:25:20 +0000 (16:25 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 4 Jul 2009 14:25:20 +0000 (16:25 +0200)
1  2 
command.c
grab_client.c
net.c
net.h
para.h

diff --combined command.c
index e3b15a5ae0e44985a6279ac2f8e137d19fb3c9be,a14fff8b6b53c2e03be60781d4cd4c1fac50926b..fc5b5cace3c8e51e4ef1560c4c813131f7966020
+++ b/command.c
@@@ -14,6 -14,8 +14,8 @@@
  
  #include "para.h"
  #include "error.h"
+ #include "crypt.h"
+ #include "command.h"
  #include "server.cmdline.h"
  #include "string.h"
  #include "afh.h"
  /** Commands including options must be shorter than this. */
  #define MAX_COMMAND_LEN 32768
  
- static RC4_KEY rc4_recv_key;
- static RC4_KEY rc4_send_key;
- static unsigned char rc4_buf[2 * RC4_KEY_LEN];
  extern int mmd_mutex;
  extern struct misc_meta_data *mmd;
  extern struct sender senders[];
@@@ -185,9 -183,17 +183,9 @@@ static int check_sender_args(int argc, 
                break;
        case SENDER_DENY:
        case SENDER_ALLOW:
 -              if (argc != 4 && argc != 5)
 +              if (argc != 4 || parse_cidr(argv[3], scd->host,
 +                              sizeof(scd->host), &scd->netmask) == NULL)
                        return -E_COMMAND_SYNTAX;
 -              if (!is_valid_ipv4_address(argv[3]))
 -                      return -E_COMMAND_SYNTAX;
 -              scd->netmask = 32;
 -              if (argc == 5) {
 -                      scd->netmask = atoi(argv[4]);
 -                      if (scd->netmask < 0 || scd->netmask > 32)
 -                              return -E_COMMAND_SYNTAX;
 -              }
 -              strncpy(scd->host, argv[3], sizeof(scd->host));
                break;
        case SENDER_ADD:
        case SENDER_DELETE:
        return 1;
  }
  
- int com_sender(int fd, int argc, char * const * argv)
+ int com_sender(struct rc4_context *rc4c, int argc, char * const * argv)
  {
        int i, ret;
        struct sender_command_data scd;
                        free(msg);
                        msg = tmp;
                }
-               ret = send_buffer(fd, msg);
+               ret = rc4_send_buffer(rc4c, msg);
                free(msg);
                return ret;
        }
                if (scd.sender_num < 0)
                        return ret;
                msg = senders[scd.sender_num].help();
-               ret = send_buffer(fd, msg);
+               ret = rc4_send_buffer(rc4c, msg);
                free(msg);
                return ret;
        }
  }
  
  /* server info */
- int com_si(int fd, int argc, __a_unused char * const * argv)
+ int com_si(struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        int i, ret;
        char *ut;
                sender_list = para_strcat(sender_list, " ");
        }
        ut = uptime_str();
-       ret = send_va_buffer(fd, "up: %s\nplayed: %u\n"
+       ret = rc4_send_va_buffer(rc4c, "up: %s\nplayed: %u\n"
                "server_pid: %d\n"
                "afs_pid: %d\n"
                "connections (active/accepted/total): %u/%u/%u\n"
  }
  
  /* version */
- int com_version(int fd, int argc, __a_unused char * const * argv)
+ int com_version(struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
-       return send_buffer(fd, VERSION_TEXT("server")
+       return rc4_send_buffer(rc4c, VERSION_TEXT("server")
                "built: " BUILD_DATE "\n"
                UNAME_RS ", " CC_VERSION "\n"
        );
  }
  
  /* stat */
- int com_stat(int fd, int argc, char * const * argv)
+ int com_stat(struct rc4_context *rc4c, int argc, char * const * argv)
  {
        int ret, num = 0;/* status will be printed that many
                          * times. num <= 0 means: print forever
  
                mmd_dup(nmmd);
                s = get_status(nmmd);
-               ret = send_buffer(fd, s);
+               ret = rc4_send_buffer(rc4c, s);
                free(s);
                if (ret < 0)
                        goto out;
@@@ -328,14 -334,14 +326,14 @@@ out
        return ret;
  }
  
- static int send_list_of_commands(int fd, struct server_command *cmd,
+ static int send_list_of_commands(struct rc4_context *rc4c, struct server_command *cmd,
                const char *handler)
  {
        int ret, i;
  
        for (i = 1; cmd->name; cmd++, i++) {
                char *perms = cmd_perms_itohuman(cmd->perms);
-               ret = send_va_buffer(fd, "%s\t%s\t%s\t%s\n", cmd->name,
+               ret = rc4_send_va_buffer(rc4c, "%s\t%s\t%s\t%s\n", cmd->name,
                        handler,
                        perms,
                        cmd->description);
@@@ -368,7 -374,7 +366,7 @@@ static struct server_command *get_cmd_p
  }
  
  /* help */
- int com_help(int fd, int argc, char * const * argv)
+ int com_help(struct rc4_context *rc4c, int argc, char * const * argv)
  {
        struct server_command *cmd;
        char *perms, *handler;
  
        if (argc < 2) {
                /* no argument given, print list of commands */
-               if ((ret = send_list_of_commands(fd, server_cmds, "server")) < 0)
+               if ((ret = send_list_of_commands(rc4c, server_cmds, "server")) < 0)
                        return ret;
-               return send_list_of_commands(fd, afs_cmds, "afs");
+               return send_list_of_commands(rc4c, afs_cmds, "afs");
        }
        /* argument given for help */
        cmd = get_cmd_ptr(argv[1], &handler);
                return -E_BAD_CMD;
        }
        perms = cmd_perms_itohuman(cmd->perms);
-       ret = send_va_buffer(fd,
+       ret = rc4_send_va_buffer(rc4c,
                "%s - %s\n\n"
                "handler: %s\n"
                "permissions: %s\n"
  }
  
  /* hup */
- int com_hup(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_hup(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* term */
- int com_term(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_term(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
        return 1;
  }
  
- int com_play(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_play(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* stop */
- int com_stop(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_stop(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* pause */
- int com_pause(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_pause(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* next */
- int com_next(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_next(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* nomore */
- int com_nomore(__a_unused int fd, int argc, __a_unused char * const * argv)
+ int com_nomore(__a_unused struct rc4_context *rc4c, int argc, __a_unused char * const * argv)
  {
        if (argc != 1)
                return -E_COMMAND_SYNTAX;
  }
  
  /* ff */
- int com_ff(__a_unused int fd, int argc, char * const * argv)
+ int com_ff(__a_unused struct rc4_context *rc4c, int argc, char * const * argv)
  {
        long promille;
        int ret, backwards = 0;
@@@ -527,7 -533,7 +525,7 @@@ out
  }
  
  /* jmp */
- int com_jmp(__a_unused int fd, int argc, char * const * argv)
+ int com_jmp(__a_unused struct rc4_context *rc4c, int argc, char * const * argv)
  {
        long unsigned int i;
        int ret;
@@@ -581,32 -587,7 +579,7 @@@ static struct server_command *parse_cmd
        return get_cmd_ptr(buf, NULL);
  }
  
- static void init_rc4_keys(void)
- {
-       int i;
-       for (i = 0; i < 2 * RC4_KEY_LEN; i++)
-               rc4_buf[i] = para_random(256);
-       PARA_DEBUG_LOG("rc4 keys initialized (%u:%u)\n",
-               (unsigned char) rc4_buf[0],
-               (unsigned char) rc4_buf[RC4_KEY_LEN]);
-       RC4_set_key(&rc4_recv_key, RC4_KEY_LEN, rc4_buf);
-       RC4_set_key(&rc4_send_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
- }
- static void rc4_recv(unsigned long len, const unsigned char *indata,
-               unsigned char *outdata, __a_unused void *private_data)
- {
-       RC4(&rc4_recv_key, len, indata, outdata);
- }
- static void rc4_send(unsigned long len, const unsigned char *indata,
-               unsigned char *outdata, __a_unused void *private_data)
- {
-       RC4(&rc4_send_key, len, indata, outdata);
- }
- static int read_command(int fd, char **result)
+ static int read_command(struct rc4_context *rc4c, char **result)
  {
        int ret;
        char buf[4096];
                size_t numbytes;
                char *p;
  
-               ret = recv_buffer(fd, buf, sizeof(buf));
+               ret = rc4_recv_buffer(rc4c, buf, sizeof(buf));
                if (ret < 0)
                        goto out;
                if (!ret)
@@@ -679,22 -660,22 +652,22 @@@ static void reset_signals(void
   */
  __noreturn void handle_connect(int fd, const char *peername)
  {
-       int ret, argc, use_rc4 = 0;
+       int ret, argc;
        char buf[4096];
-       unsigned char crypt_buf[MAXLINE];
+       unsigned char rand_buf[CHALLENGE_SIZE + 2 * RC4_KEY_LEN];
+       unsigned char challenge_sha1[HASH_SIZE];
        struct user *u;
        struct server_command *cmd = NULL;
-       long unsigned challenge_nr, chall_response;
        char **argv = NULL;
        char *p, *command = NULL;
        size_t numbytes;
+       struct rc4_context rc4c = {.fd = fd};
  
        reset_signals();
        /* we need a blocking fd here as recv() might return EAGAIN otherwise. */
        ret = mark_fd_blocking(fd);
        if (ret < 0)
                goto err_out;
-       challenge_nr = random();
        /* send Welcome message */
        ret = send_va_buffer(fd, "This is para_server, version "
                PACKAGE_VERSION  ".\n" );
        ret = recv_buffer(fd, buf, sizeof(buf));
        if (ret < 0)
                goto err_out;
-       if (ret <= 6) {
-               ret = -E_AUTH;
+       if (ret < 10) {
+               ret = -E_AUTH_REQUEST;
                goto err_out;
        }
        numbytes = ret;
-       ret = -E_AUTH;
-       if (strncmp(buf, "auth ", 5))
+       ret = -E_AUTH_REQUEST;
+       if (strncmp(buf, AUTH_REQUEST_MSG, strlen(AUTH_REQUEST_MSG)))
                goto err_out;
-       if (numbytes < 9 || strncmp(buf, "auth rc4 ", 9))
-               p = buf + 5; /* client version < 0.2.6 */
-       else {
-               p = buf + 9; /* client version >= 0.2.6 */
-               use_rc4 = 1;
-       }
-       PARA_DEBUG_LOG("received %s request for user %s\n",
-               use_rc4? "rc4" : "auth", p);
+       p = buf + strlen(AUTH_REQUEST_MSG);
+       PARA_DEBUG_LOG("received auth request for user %s\n", p);
        ret = -E_BAD_USER;
        u = lookup_user(p);
-       if (!u)
-               goto err_out;
-       ret = para_encrypt_challenge(u->rsa, challenge_nr, crypt_buf);
-       if (ret <= 0)
-               goto err_out;
-       numbytes = ret;
-       PARA_DEBUG_LOG("sending %zu byte challenge\n", numbytes);
-       /* We can't use send_buffer here since buf may contain null bytes */
-       ret = send_bin_buffer(fd,(char *) crypt_buf, numbytes);
+       if (u) {
+               get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
+               ret = para_encrypt_buffer(u->rsa, rand_buf, sizeof(rand_buf),
+                       (unsigned char *)buf);
+               if (ret < 0)
+                       goto err_out;
+               numbytes = ret;
+       } else {
+               /*
+                * We don't want to reveal our user names, so we send a
+                * challenge to the client even if the user does not exist, and
+                * fail the authentication later.
+                */
+               numbytes = 256;
+               get_random_bytes_or_die((unsigned char *)buf, numbytes);
+       }
+       PARA_DEBUG_LOG("sending %zu byte challenge + rc4 keys (%u bytes)\n",
+               CHALLENGE_SIZE, numbytes);
+       ret = send_bin_buffer(fd, buf, numbytes);
        if (ret < 0)
                goto net_err;
-       /* recv decrypted number */
-       ret = recv_buffer(fd, buf, sizeof(buf));
+       /* recv challenge response */
+       ret = recv_bin_buffer(fd, buf, HASH_SIZE);
        if (ret < 0)
                goto net_err;
        numbytes = ret;
-       ret = -E_AUTH;
-       if (!numbytes)
+       PARA_DEBUG_LOG("received %zu bytes challenge response\n", ret);
+       ret = -E_BAD_USER;
+       if (!u)
                goto net_err;
-       if (sscanf(buf, CHALLENGE_RESPONSE_MSG "%lu", &chall_response) < 1
-                       || chall_response != challenge_nr)
-               goto err_out;
-       /* auth successful, send 'Proceed' message */
-       PARA_INFO_LOG("good auth for %s (%lu)\n", u->name, challenge_nr);
-       sprintf(buf, "%s", PROCEED_MSG);
-       if (use_rc4) {
-               init_rc4_keys();
-               ret = para_encrypt_buffer(u->rsa, rc4_buf, 2 * RC4_KEY_LEN,
-                       (unsigned char *)buf + PROCEED_MSG_LEN + 1);
-               if (ret <= 0)
-                       goto err_out;
-               numbytes = ret + strlen(PROCEED_MSG) + 1;
-       } else
-               numbytes = strlen(buf);
-       ret = send_bin_buffer(fd, buf, numbytes);
+       /*
+        * The correct response is the sha1 of the first CHALLENGE_SIZE bytes
+        * of the random data.
+        */
+       ret = -E_BAD_AUTH;
+       if (numbytes != HASH_SIZE)
+               goto net_err;
+       sha1_hash((char *)rand_buf, CHALLENGE_SIZE, challenge_sha1);
+       if (memcmp(challenge_sha1, buf, HASH_SIZE))
+               goto net_err;
+       /* auth successful */
+       alarm(0);
+       PARA_INFO_LOG("good auth for %s\n", u->name);
+       /* init rc4 keys with the second part of the random buffer */
+       RC4_set_key(&rc4c.recv_key, RC4_KEY_LEN, rand_buf + CHALLENGE_SIZE);
+       RC4_set_key(&rc4c.send_key, RC4_KEY_LEN, rand_buf + CHALLENGE_SIZE
+               + RC4_KEY_LEN);
+       ret = rc4_send_buffer(&rc4c, PROCEED_MSG);
        if (ret < 0)
                goto net_err;
-       if (use_rc4)
-               enable_crypt(fd, rc4_recv, rc4_send, NULL);
-       ret = read_command(fd, &command);
+       ret = read_command(&rc4c, &command);
        if (ret == -E_COMMAND_SYNTAX)
                goto err_out;
        if (ret < 0)
        if (ret < 0)
                goto err_out;
        /* valid command and sufficient perms */
-       alarm(0);
        argc = split_args(command, &argv, "\n");
        PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cmd->name, u->name,
                        peername);
-       ret = cmd->handler(fd, argc, argv);
+       ret = cmd->handler(&rc4c, argc, argv);
        mutex_lock(mmd_mutex);
        mmd->num_commands++;
        mutex_unlock(mmd_mutex);
        if (ret >= 0)
                goto out;
  err_out:
-       send_va_buffer(fd, "%s\n", para_strerror(-ret));
+       rc4_send_va_buffer(&rc4c, "%s\n", para_strerror(-ret));
  net_err:
        PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
  out:
diff --combined grab_client.c
index f3a0f48486e14ac478413e78efcfd41ee38e87dc,ccfdb0c8e129ffea3aafa15ca8d6cbdb9933e53e..9b4ef69c5f4dae98409f707959abcdb9ca8b13c9
@@@ -25,7 -25,6 +25,6 @@@
  #include "error.h"
  #include "string.h"
  #include "fd.h"
- #include "crypt.h"
  
  /** Grab clients that are not yet attached to a filter node. */
  struct list_head inactive_grab_client_list;
@@@ -83,7 -82,7 +82,7 @@@ static int check_gc_args(struct grab_cl
  {
        int i;
        struct grab_client_args_info *c = gc->conf;
 -      char **mv = grab_client_cmdline_parser_mode_values;
 +      const char **mv = grab_client_cmdline_parser_mode_values;
  
        PARA_INFO_LOG("filter_num: %d\n", c->filter_num_arg);
        for (i = 0; mv[i]; i++)
diff --combined net.c
index ab6a98940b1e920eee7ee5e3f8f6b9bb33cf94b9,f10afb71e31f0a1e7178972102b22c0feb01bfcc..b3588f6d9e3d43d62f592a982b11f0db5f1e550b
--- 1/net.c
--- 2/net.c
+++ b/net.c
  
  #include <dirent.h>
  #include <regex.h>
+ #include <openssl/rc4.h>
  
  #include "para.h"
  #include "error.h"
+ #include "crypt.h"
  #include "net.h"
  #include "string.h"
  #include "fd.h"
  
- /** Information about one encrypted connection. */
- struct crypt_data {
-       /** Function used to decrypt received data. */
-       crypt_function *recv;
-       /** Function used to encrypt data to be sent. */
-       crypt_function *send;
-       /**
-        * Context-dependent data (crypt keys), passed verbatim to the above
-        * crypt functions.
-        */
-       void *private_data;
- };
- /** Array holding per fd crypt data. */
- static struct crypt_data *crypt_data_array;
- /** Current size of the crypt data array. */
- static unsigned cda_size = 0;
- /**
-  * Activate encryption for one file descriptor.
-  *
-  * \param fd The file descriptor.
-  * \param recv_f The function used for decrypting received data.
-  * \param send_f The function used for encrypting before sending.
-  * \param private_data User data supplied by the caller.
-  */
- void enable_crypt(int fd, crypt_function *recv_f, crypt_function *send_f,
-       void *private_data)
- {
-       if (fd + 1 > cda_size) {
-               crypt_data_array = para_realloc(crypt_data_array,
-                       (fd + 1) * sizeof(struct crypt_data));
-               memset(crypt_data_array + cda_size, 0,
-                       (fd + 1 - cda_size) * sizeof(struct crypt_data));
-               cda_size = fd + 1;
-       }
-       crypt_data_array[fd].recv = recv_f;
-       crypt_data_array[fd].send = send_f;
-       crypt_data_array[fd].private_data = private_data;
-       PARA_INFO_LOG("rc4 encryption activated for fd %d\n", fd);
- }
- /**
-  * Deactivate encryption for a given fd.
-  *
-  * \param fd The file descriptor.
-  *
-  * This must be called if and only if \p fd was activated via enable_crypt().
-  */
- void disable_crypt(int fd)
- {
-       if (cda_size < fd + 1)
-               return;
-       crypt_data_array[fd].recv = NULL;
-       crypt_data_array[fd].send = NULL;
-       crypt_data_array[fd].private_data = NULL;
- }
 +/**
 + * Parse and validate IPv4 address/netmask string.
 + *
 + * \param cidr          Address in CIDR notation
 + * \param addr          Copy of the IPv4 address part of \a cidr
 + * \param addrlen Size of \a addr in bytes
 + * \param netmask Value of the netmask part in \a cidr or the
 + *              default of 32 if not specified.
 + *
 + * \return Pointer to \a addr if succesful, NULL on error.
 + * \sa RFC 4632
 + */
 +char *parse_cidr(const char *cidr,
 +               char    *addr, ssize_t addrlen,
 +               int32_t *netmask)
 +{
 +      const char *o = cidr;
 +      char *c = addr, *end = c + (addrlen - 1);
 +
 +      *netmask = 0x20;
 +
 +      if (cidr == NULL || addrlen < 1)
 +              goto failed;
 +
 +      for (o = cidr; (*c = *o == '/'? '\0' : *o); c++, o++)
 +              if (c == end)
 +                      goto failed;
 +
 +      if (*o == '/')
 +              if (para_atoi32(++o, netmask) < 0 ||
 +                  *netmask < 0 || *netmask > 0x20)
 +                      goto failed;
 +
 +      if (is_valid_ipv4_address(addr))
 +              return addr;
 +failed:
 +      *addr = '\0';
 +      return NULL;
 +}
 +
 +
  /**
   * Match string as a candidate IPv4 address.
   *
@@@ -528,41 -431,26 +472,26 @@@ struct in_addr extract_v4_addr(const st
  }
  
  /**
-  * Encrypt and send a binary buffer.
+  * Send a binary buffer.
   *
   * \param fd The file descriptor.
-  * \param buf The buffer to be encrypted and sent.
+  * \param buf The buffer to be sent.
   * \param len The length of \a buf.
   *
-  * Check if encryption is available. If yes, encrypt the given buffer.  Send
-  * out the buffer, encrypted or not, and try to resend the remaining part in
-  * case of short writes.
+  * Send out the buffer and try to resend the remaining part in case of short
+  * writes.
   *
   * \return Standard.
   */
  int send_bin_buffer(int fd, const char *buf, size_t len)
  {
-       int ret;
-       crypt_function *cf = NULL;
        if (!len)
                PARA_CRIT_LOG("len == 0\n");
-       if (fd + 1 <= cda_size)
-               cf = crypt_data_array[fd].send;
-       if (cf) {
-               void *private = crypt_data_array[fd].private_data;
-               /* RC4 may write more than len to the output buffer */
-               unsigned char *outbuf = para_malloc(ROUND_UP(len, 8));
-               (*cf)(len, (unsigned char *)buf, outbuf, private);
-               ret = write_all(fd, (char *)outbuf, &len);
-               free(outbuf);
-       } else
-               ret = write_all(fd, buf, &len);
-       return ret;
+       return write_all(fd, buf, &len);
  }
  
  /**
-  * Encrypt and send null terminated buffer.
+  * Send a \p NULL-terminated buffer.
   *
   * \param fd The file descriptor.
   * \param buf The null-terminated buffer to be send.
@@@ -576,9 -464,8 +505,8 @@@ int send_buffer(int fd, const char *buf
        return send_bin_buffer(fd, buf, strlen(buf));
  }
  
  /**
-  * Send and encrypt a buffer given by a format string.
+  * Send a buffer given by a format string.
   *
   * \param fd The file descriptor.
   * \param fmt A format string.
@@@ -597,51 -484,37 +525,37 @@@ __printf_2_3 int send_va_buffer(int fd
  }
  
  /**
-  * Receive and decrypt.
+  * Receive data from a file descriptor.
   *
   * \param fd The file descriptor.
-  * \param buf The buffer to write the decrypted data to.
+  * \param buf The buffer to write the data to.
   * \param size The size of \a buf.
   *
-  * Receive at most \a size bytes from file descriptor \a fd. If encryption is
-  * available, decrypt the received buffer.
+  * Receive at most \a size bytes from file descriptor \a fd.
   *
-  * \return The number of bytes received on success, negative on errors.
+  * \return The number of bytes received on success, negative on errors, zero if
+  * the peer has performed an orderly shutdown.
   *
-  * \sa recv(2)
+  * \sa recv(2).
   */
  __must_check int recv_bin_buffer(int fd, char *buf, size_t size)
  {
        ssize_t n;
-       crypt_function *cf = NULL;
-       if (fd + 1 <= cda_size)
-               cf = crypt_data_array[fd].recv;
-       if (cf) {
-               unsigned char *tmp = para_malloc(size);
-               void *private = crypt_data_array[fd].private_data;
-               n = recv(fd, tmp, size, 0);
-               if (n > 0) {
-                       size_t numbytes = n;
-                       unsigned char *b = (unsigned char *)buf;
-                       (*cf)(numbytes, tmp, b, private);
-               }
-               free(tmp);
-       } else
-               n = recv(fd, buf, size, 0);
+       n = recv(fd, buf, size, 0);
        if (n == -1)
                return -ERRNO_TO_PARA_ERROR(errno);
        return n;
  }
  
  /**
-  * Receive, decrypt and write terminating NULL byte.
+  * Receive and write terminating NULL byte.
   *
   * \param fd The file descriptor.
-  * \param buf The buffer to write the decrypted data to.
+  * \param buf The buffer to write the data to.
   * \param size The size of \a buf.
   *
-  * Read and decrypt at most \a size - 1 bytes from file descriptor \a fd and
+  * Read at most \a size - 1 bytes from file descriptor \a fd and
   * write a NULL byte at the end of the received data.
   *
   * \return The return value of the underlying call to \a recv_bin_buffer().
diff --combined net.h
index 8b706178e635fda2ba5ae00568730e36c87fac6a,b85403fdbfee4771bdec019409348e01a2f684ce..15412586583ae9398090f98a8bfee83b59a09d59
--- 1/net.h
--- 2/net.h
+++ b/net.h
@@@ -29,8 -29,6 +29,8 @@@
  /**
   * Functions to parse and validate (parts of) URLs.
   */
 +extern char *parse_cidr(const char *cidr,
 +                      char *addr, ssize_t addrlen, int32_t *netmask);
  extern char *parse_url(const char *url,
                       char *host, ssize_t hostlen, int32_t *port);
  /**
@@@ -80,15 -78,13 +80,13 @@@ extern int para_listen(unsigned l3type
  extern char *local_name(int sockfd);
  extern char *remote_name(int sockfd);
  
- /** used to crypt the communication between para_server and para_client */
- typedef void crypt_function(unsigned long len,
-       const unsigned char *indata, unsigned char *outdata, void *private_data);
- int send_buffer(int, const char *);
  int send_bin_buffer(int, const char *, size_t);
+ int send_buffer(int, const char *);
  __printf_2_3 int send_va_buffer(int fd, const char *fmt, ...);
- int recv_buffer(int fd, char *buf, size_t size);
  int recv_bin_buffer(int fd, char *buf, size_t size);
+ int recv_buffer(int fd, char *buf, size_t size);
  int para_accept(int, void *addr, socklen_t size);
  int create_local_socket(const char *name, struct sockaddr_un *unix_addr,
        mode_t mode);
@@@ -96,6 -92,3 +94,3 @@@ int create_remote_socket(const char *na
  int recv_cred_buffer(int, char *, size_t);
  ssize_t send_cred_buffer(int, char*);
  int recv_pattern(int fd, const char *pattern, size_t bufsize);
- void enable_crypt(int fd, crypt_function *recv_f, crypt_function *send_f,
-       void *private_data);
- void disable_crypt(int fd);
diff --combined para.h
index e4e9a53dd96c740e2178b9d439cf8ed6e790ffb3,112d5fef0d1daef2f9d32f39c56e2c38442c0d27..d49d7221ba7d6fbb07344e55e679ac2915110335
--- 1/para.h
--- 2/para.h
+++ b/para.h
                printf("%s", VERSION_TEXT(_prefix)); \
                exit(EXIT_SUCCESS); \
        }
+ /* Sent by para_client to initiate the authentication procedure. */
+ #define AUTH_REQUEST_MSG "auth rsa "
  /** sent by para_server for commands that expect a data file */
  #define AWAITING_DATA_MSG "\nAwaiting Data."
  /** sent by para_server if authentication was successful */
- #define PROCEED_MSG "\nProceed.\n"
+ #define PROCEED_MSG "Proceed."
  /** length of the \p PROCEED_MSG string */
  #define PROCEED_MSG_LEN strlen(PROCEED_MSG)
  /** sent by para_client to indicate the end of the command line */
  #define EOC_MSG "\nEnd of Command."
- /** sent by para_client, followed by the decrypted challenge number */
- #define CHALLENGE_RESPONSE_MSG "challenge_response:"
  
  /* exec */
  int para_exec_cmdline_pid(pid_t *pid, const char *cmdline, int *fds);
@@@ -183,7 -184,7 +184,7 @@@ extern const char *status_item_list[]
  int stat_item_valid(const char *item);
  int stat_line_valid(const char *);
  void stat_client_write(const char *msg, int itemnum);
 -int stat_client_add(int fd, long unsigned mask);
 +int stat_client_add(int fd, uint64_t mask);
  
  __printf_2_3 void para_log(int, const char*, ...);
  
   *
   * \return An integer between zero and \p max - 1, inclusively.
   */
static inline long int para_random(unsigned max)
_static_inline_ long int para_random(unsigned max)
  {
        return ((max + 0.0) * (random() / (RAND_MAX + 1.0)));
  }