]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - command.c
Make rc4 encryption/decryption more explicit.
[paraslash.git] / command.c
index 15b166adbb1c959c803c46bc38a270e95e1e8e7d..4b3a155277fbdde2ead5c0ba8ed238770b710169 100644 (file)
--- a/command.c
+++ b/command.c
@@ -14,6 +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[];
 
+static void init_rc4_keys(struct rc4_context *rcc)
+{
+       get_random_bytes_or_die(rc4_buf, 2 * RC4_KEY_LEN);
+       RC4_set_key(&rcc->recv_key, RC4_KEY_LEN, rc4_buf);
+       RC4_set_key(&rcc->send_key, RC4_KEY_LEN, rc4_buf + RC4_KEY_LEN);
+}
+
 static void dummy(__a_unused int s)
 {
 }
@@ -208,7 +215,7 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman
        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;
@@ -221,7 +228,7 @@ int com_sender(int fd, int argc, char * const * argv)
                        free(msg);
                        msg = tmp;
                }
-               ret = send_buffer(fd, msg);
+               ret = rc4_send_buffer(rc4c, msg);
                free(msg);
                return ret;
        }
@@ -231,7 +238,7 @@ int com_sender(int fd, int argc, char * const * argv)
                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;
        }
@@ -250,7 +257,7 @@ int com_sender(int fd, int argc, char * const * argv)
 }
 
 /* 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;
@@ -267,7 +274,7 @@ int com_si(int fd, int argc, __a_unused char * const * argv)
                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"
@@ -294,18 +301,18 @@ int com_si(int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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
@@ -321,7 +328,7 @@ int com_stat(int fd, int argc, char * const * argv)
 
                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;
@@ -336,14 +343,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);
@@ -376,7 +383,7 @@ static struct server_command *get_cmd_ptr(const char *name, char **handler)
 }
 
 /* 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;
@@ -384,9 +391,9 @@ int com_help(int fd, int argc, char * const * argv)
 
        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);
@@ -395,7 +402,7 @@ int com_help(int fd, int argc, char * const * argv)
                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"
@@ -414,7 +421,7 @@ int com_help(int fd, int argc, char * const * argv)
 }
 
 /* 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;
@@ -423,7 +430,7 @@ int com_hup(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -431,7 +438,7 @@ int com_term(__a_unused int fd, int argc, __a_unused char * const * argv)
        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;
@@ -444,7 +451,7 @@ int com_play(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -457,7 +464,7 @@ int com_stop(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -472,7 +479,7 @@ int com_pause(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -484,7 +491,7 @@ int com_next(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -496,7 +503,7 @@ int com_nomore(__a_unused int fd, int argc, __a_unused char * const * argv)
 }
 
 /* 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;
@@ -535,7 +542,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;
@@ -589,32 +596,7 @@ static struct server_command *parse_cmd(const char *cmdstr)
        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];
@@ -624,7 +606,7 @@ static int read_command(int fd, char **result)
                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)
@@ -696,13 +678,13 @@ __noreturn void handle_connect(int fd, const char *peername)
        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" );
@@ -726,6 +708,8 @@ __noreturn void handle_connect(int fd, const char *peername)
        u = lookup_user(p);
        if (!u)
                goto err_out;
+       get_random_bytes_or_die((unsigned char *)&challenge_nr,
+               sizeof(challenge_nr));
        ret = para_encrypt_challenge(u->rsa, challenge_nr, crypt_buf);
        if (ret <= 0)
                goto err_out;
@@ -749,7 +733,7 @@ __noreturn void handle_connect(int fd, const char *peername)
        /* auth successful, send 'Proceed' message */
        PARA_INFO_LOG("good auth for %s (%lu)\n", u->name, challenge_nr);
        sprintf(buf, "%s", PROCEED_MSG);
-       init_rc4_keys();
+       init_rc4_keys(&rc4c);
        /* Should we also encrypt the proceed message? */
        ret = para_encrypt_buffer(u->rsa, rc4_buf, 2 * RC4_KEY_LEN,
                (unsigned char *)buf + PROCEED_MSG_LEN + 1);
@@ -759,8 +743,7 @@ __noreturn void handle_connect(int fd, const char *peername)
        ret = send_bin_buffer(fd, buf, numbytes);
        if (ret < 0)
                goto net_err;
-       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)
@@ -778,14 +761,14 @@ __noreturn void handle_connect(int fd, const char *peername)
        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: