Use openssl's RAND_load_file() and RAND_bytes() to get randomness.
[paraslash.git] / command.c
index 1ca54da..ab765a1 100644 (file)
--- a/command.c
+++ b/command.c
@@ -591,10 +591,7 @@ static struct server_command *parse_cmd(const char *cmdstr)
 
 static void init_rc4_keys(void)
 {
-       int i;
-
-       for (i = 0; i < 2 * RC4_KEY_LEN; i++)
-               rc4_buf[i] = para_random(256);
+       get_random_bytes_or_die(rc4_buf, 2 * RC4_KEY_LEN);
        PARA_DEBUG_LOG("rc4 keys initialized (%u:%u)\n",
                (unsigned char) rc4_buf[0],
                (unsigned char) rc4_buf[RC4_KEY_LEN]);
@@ -687,7 +684,7 @@ 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];
        struct user *u;
@@ -702,7 +699,6 @@ __noreturn void handle_connect(int fd, const char *peername)
        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" );
@@ -712,27 +708,22 @@ __noreturn void handle_connect(int fd, const char *peername)
        ret = recv_buffer(fd, buf, sizeof(buf));
        if (ret < 0)
                goto err_out;
-       if (ret <= 6) {
+       if (ret < 10) {
                ret = -E_AUTH;
                goto err_out;
        }
        numbytes = ret;
        ret = -E_AUTH;
-       if (strncmp(buf, "auth ", 5))
+       if (strncmp(buf, "auth rc4 ", 9))
                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 + 9;
+       PARA_DEBUG_LOG("received auth request for user %s\n", p);
        ret = -E_BAD_USER;
        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;
@@ -756,20 +747,17 @@ __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);
-       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);
+       init_rc4_keys();
+       /* 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);
+       if (ret <= 0)
+               goto err_out;
+       numbytes = ret + strlen(PROCEED_MSG) + 1;
        ret = send_bin_buffer(fd, buf, numbytes);
        if (ret < 0)
                goto net_err;
-       if (use_rc4)
-               enable_crypt(fd, rc4_recv, rc4_send, NULL);
+       enable_crypt(fd, rc4_recv, rc4_send, NULL);
        ret = read_command(fd, &command);
        if (ret == -E_COMMAND_SYNTAX)
                goto err_out;