]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/aes'
authorAndre Noll <maan@systemlinux.org>
Sun, 16 Mar 2014 16:49:59 +0000 (17:49 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 16 Mar 2014 16:55:17 +0000 (17:55 +0100)
Cooking since 2014-02-02.

* t/aes:
  Implement aes_ctr128 and prefer it over RC4.
  server: Lookup user only once.

1  2 
NEWS
client_common.c
command.c
web/manual.m4

diff --combined NEWS
index b535dd6b7df182b3a9de88817b19701882c45c19,51d9db7c1e1b8b1b9c3ba201f464b29ebd25bcf4..84a420584242f6a7e2f6a1b2306c4c0000fb8065
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,16 -1,6 +1,25 @@@
  NEWS
  ====
  
 +---------------------------------------------
 +0.5.2 (to be announced) "orthogonal interior"
 +---------------------------------------------
 +
++The new sync filter, the AES_CTR128 stream cipher and the overhauled
++network code are the highlights of this release.
++
 +      - The new sync filter synchronizes playback between multiple
 +        clients.
++      - Connections between para_server and para_client are now
++        encrypted by means of AES rather than RC4 if both sides
++        support it. RC4 is still available as a fallback. This
++        feature is fully transparent, i.e. no command line options
++        are necessary, and a client linked against openssl can
++        speak with a server linked against libgcrypt and vice versa.
 +      - Major cleanup of the networking subsystem.
 +      - Improved user manual.
 +      - Minor fixes to avoid clang warnings.
 +
  ------------------------------------------
  0.5.1 (2013-12-20) "temporary implication"
  ------------------------------------------
diff --combined client_common.c
index 6652cc35477234a9dd4a9f0621be953c5cc9ba00,54b217129eaf13fc289da5b1f861c29b6ae8637e..3b8ed511090a5a637d867f48baf391338677c837
@@@ -6,13 -6,8 +6,13 @@@
  
  /** \file client_common.c Common functions of para_client and para_audiod. */
  
 +#include <netinet/in.h>
 +#include <sys/socket.h>
  #include <regex.h>
  #include <sys/types.h>
 +#include <arpa/inet.h>
 +#include <sys/un.h>
 +#include <netdb.h>
  
  #include "para.h"
  #include "error.h"
@@@ -336,7 -331,8 +336,8 @@@ static int client_post_select(struct sc
        case CL_RECEIVED_WELCOME: /* send auth command */
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
                        return 0;
-               sprintf(buf, AUTH_REQUEST_MSG "%s sideband", ct->user);
+               sprintf(buf, AUTH_REQUEST_MSG "%s sideband%s", ct->user,
+                       has_feature("aes_ctr128", ct)? ",aes_ctr128" : "");
                PARA_INFO_LOG("--> %s\n", buf);
                ret = write_buffer(ct->scc.fd, buf);
                if (ret < 0)
                /* decrypted challenge/session key buffer */
                unsigned char crypt_buf[1024];
                struct sb_buffer sbb;
+               bool use_aes;
  
                ret = recv_sb(ct, &s->rfds, &sbb);
                if (ret <= 0)
                        goto out;
                ct->challenge_hash = para_malloc(HASH_SIZE);
                hash_function((char *)crypt_buf, CHALLENGE_SIZE, ct->challenge_hash);
-               ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN);
+               use_aes = has_feature("aes_ctr128", ct);
+               ct->scc.send = sc_new(crypt_buf + CHALLENGE_SIZE, SESSION_KEY_LEN, use_aes);
                ct->scc.recv = sc_new(crypt_buf + CHALLENGE_SIZE + SESSION_KEY_LEN,
-                       SESSION_KEY_LEN);
+                       SESSION_KEY_LEN, use_aes);
                hash_to_asc(ct->challenge_hash, buf);
                PARA_INFO_LOG("--> %s\n", buf);
                ct->status = CL_RECEIVED_CHALLENGE;
diff --combined command.c
index fc098b7803f58259452906b1dfc52fd1b6b56144,0bd5c234ba9b652aa78e104f204d508e625cd26e..26126cc938cc0f8c9bb751b2cebf6f7ee52d5169
+++ b/command.c
@@@ -6,15 -6,10 +6,15 @@@
  
  /** \file command.c Client authentication and server commands. */
  
 +#include <netinet/in.h>
 +#include <sys/socket.h>
  #include <regex.h>
  #include <signal.h>
  #include <sys/types.h>
  #include <osl.h>
 +#include <arpa/inet.h>
 +#include <sys/un.h>
 +#include <netdb.h>
  
  #include "para.h"
  #include "error.h"
@@@ -559,7 -554,6 +559,7 @@@ static int send_list_of_commands(struc
                msg = para_strcat(msg, tmp);
                free(tmp);
        }
 +      assert(msg);
        return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false);
  }
  
@@@ -786,14 -780,20 +786,20 @@@ static void reset_signals(void
        para_sigaction(SIGHUP, SIG_DFL);
  }
  
- static int parse_auth_request(char *buf, int len, struct user **u)
+ struct connection_features {
+       bool sideband_requested;
+       bool aes_ctr128_requested;
+ };
+ static int parse_auth_request(char *buf, int len, struct user **u,
+               struct connection_features *cf)
  {
        int ret;
        char *p, *username, **features = NULL;
        size_t auth_rq_len = strlen(AUTH_REQUEST_MSG);
-       bool sideband_requested = false;
  
        *u = NULL;
+       memset(cf, 0, sizeof(*cf));
        if (len < auth_rq_len + 2)
                return -E_AUTH_REQUEST;
        if (strncmp(buf, AUTH_REQUEST_MSG, auth_rq_len) != 0)
                create_argv(p, ",", &features);
                for (i = 0; features[i]; i++) {
                        if (strcmp(features[i], "sideband") == 0)
-                               sideband_requested = true;
+                               cf->sideband_requested = true;
+                       else if (strcmp(features[i], "aes_ctr128") == 0)
+                               cf->aes_ctr128_requested = true;
                        else {
                                ret = -E_BAD_FEATURE;
                                goto out;
                        }
                }
        }
-       if (sideband_requested == false) { /* sideband is mandatory */
-               PARA_ERROR_LOG("client did not request sideband\n");
-               ret = -E_BAD_FEATURE;
-               goto out;
-       }
        PARA_DEBUG_LOG("received auth request for user %s\n", username);
        *u = lookup_user(username);
        ret = 1;
@@@ -895,10 -892,11 +898,11 @@@ __noreturn void handle_connect(int fd, 
        int ret;
        unsigned char rand_buf[CHALLENGE_SIZE + 2 * SESSION_KEY_LEN];
        unsigned char challenge_hash[HASH_SIZE];
-       char *p, *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */;
+       char *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */;
        size_t numbytes;
        struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct;
        struct iovec iov;
+       struct connection_features cf;
  
        cc->scc.fd = fd;
        reset_signals();
        /* send Welcome message */
        ret = write_va_buffer(fd, "This is para_server, version "
                PACKAGE_VERSION  ".\n"
-               "Features: sideband\n"
+               "Features: sideband,aes_ctr128\n"
        );
        if (ret < 0)
                goto net_err;
        ret = recv_buffer(fd, buf, HANDSHAKE_BUFSIZE);
        if (ret < 0)
                goto net_err;
-       ret = parse_auth_request(buf, ret, &cc->u);
+       ret = parse_auth_request(buf, ret, &cc->u, &cf);
        if (ret < 0)
                goto net_err;
-       p = buf + strlen(AUTH_REQUEST_MSG);
-       PARA_DEBUG_LOG("received auth request for user %s\n", p);
-       cc->u = lookup_user(p);
+       if (!cf.sideband_requested) { /* sideband is mandatory */
+               PARA_ERROR_LOG("client did not request sideband\n");
+               ret = -E_BAD_FEATURE;
+               goto net_err;
+       }
        if (cc->u) {
                get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
                ret = pub_encrypt(cc->u->pubkey, rand_buf, sizeof(rand_buf),
                numbytes = 256;
                get_random_bytes_or_die((unsigned char *)buf, numbytes);
        }
-       PARA_DEBUG_LOG("sending %u byte challenge + rc4 keys (%zu bytes)\n",
+       PARA_DEBUG_LOG("sending %u byte challenge + session key (%zu bytes)\n",
                CHALLENGE_SIZE, numbytes);
        ret = send_sb(&cc->scc, buf, numbytes, SBD_CHALLENGE, false);
        buf = NULL;
        alarm(0);
        PARA_INFO_LOG("good auth for %s\n", cc->u->name);
        /* init stream cipher keys with the second part of the random buffer */
-       cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN);
-       cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN, SESSION_KEY_LEN);
+       cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN,
+               cf.aes_ctr128_requested);
+       cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN,
+               SESSION_KEY_LEN, cf.aes_ctr128_requested);
        ret = send_sb(&cc->scc, NULL, 0, SBD_PROCEED, false);
        if (ret < 0)
                goto net_err;
diff --combined web/manual.m4
index 4edce03639b5ca4b719178e148f05a98fc3a6a21,20cae69ab7e00d6d50b8f5026ab5c42d8e39c33b..e809c8b22be7ddea6a6e9335550670098a303b06
@@@ -112,7 -112,7 +112,7 @@@ can be used by any scripting language t
  little programming effort.
  
  All connections between para_server and para_client are encrypted
- with a symmetric RC4 session key. For each user of paraslash you must
+ with a symmetric session key. For each user of paraslash you must
  create a public/secret RSA key pair for authentication.
  
  If para_client is started without non-option arguments, an interactive
@@@ -505,9 -505,9 +505,9 @@@ User managemen
  para_server uses a challenge-response mechanism to authenticate
  requests from incoming connections, similar to ssh's public key
  authentication method. Authenticated connections are encrypted using
the RC4 stream cipher.
a stream cipher, either RC4 or AES in integer counter mode.
  
- In this chapter we briefly describe RSA and RC4 and sketch the
+ In this chapter we briefly describe RSA, RC4 and AES, and sketch the
  REFERENCE(Client-server authentication, authentication handshake)
  between para_client and para_server. User management is discussed
  in the section on REFERENCE(The user_list file, the user_list file).
@@@ -517,8 -517,8 +517,8 @@@ in a REFERENCE(Connecting para_audiod, 
  
  
  
- RSA and RC4
- ~~~~~~~~~~~
+ RSA, RC4, AES
+ ~~~~~~~~~~~~~
  
  RSA is an asymmetric block cipher which is used in many applications,
  including ssh and gpg. An RSA key consists in fact of two keys,
@@@ -537,6 -537,15 +537,15 @@@ strong encryption by today's standards
  be used twice, a different, randomly-generated key is used for every
  new connection.
  
+ AES, the advanced encryption standard, is a well-known symmetric block
+ cipher, i.e. a transformation operating on fixed-length blocks which
+ is determined by a single key for both encryption and decryption. Any
+ block cipher can be turned into a stream cipher by generating
+ a pseudo-random key stream by encrypting successive values of a
+ counter. The AES_CTR128 stream cipher used in paraslash is obtained
+ in this way from the AES block cipher with a 128 bit block size.
  Client-server authentication
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
@@@ -557,7 -566,7 +566,7 @@@ as follows
        fixed-length buffer with random bytes, encrypts that buffer
        using the public key and sends the encrypted buffer to the
        client. The first part of the buffer is the challenge which
-       is used for authentication while the second part is the RC4
+       is used for authentication while the second part is the
        session key.
  
        - para_client receives the encrypted buffer and decrypts it
  
        - Otherwise the user is considered authenticated and the client
        is allowed to proceed by sending a command to be executed. From
-       this point on the communication is encrypted using the RC4
-       stream cipher with the session key known to both peers.
+       this point on the communication is encrypted using the stream
+       cipher with the session key known to both peers.
  
  paraslash relies on the quality of the pseudo-random bytes provided
  by the crypto library (openssl or libgcrypt), on the security of
- the implementation of the RSA and RC4 crypto routines and on the
+ the implementation of the RSA, RC4 and AES crypto routines and on the
  infeasibility to invert the SHA1 function.
  
  Neither para_server or para_client create RSA keys on their own. This
@@@ -1071,18 -1080,17 +1080,18 @@@ It is possible to change the behaviour 
  Troubleshooting
  ~~~~~~~~~~~~~~~
  
 -Use the debug loglevel (option -l debug for most commands) to show
 -debugging info. Almost all paraslash executables have a brief online
 -help which is displayed by using the -h switch. The --detailed-help
 -option prints the full help text.
 +Use the debug loglevel (-l debug) to show debugging info. All paraslash
 +executables have a brief online help which is displayed when -h is
 +given. The --detailed-help option prints the full help text.
  
  If para_server crashed or was killed by SIGKILL (signal 9), it
  may refuse to start again because of "dirty osl tables". In this
  case you'll have to run the oslfsck program of libosl to fix your
 -database. It might be necessary to use --force (even if your name
 -isn't Luke). However, make sure para_server isn't running before
 -executing oslfsck --force.
 +database:
 +
 +      oslfsck -fd ~/.paraslash/afs_database-0.4
 +
 +However, make sure para_server isn't running before executing oslfsck.
  
  If you don't mind to recreate your database you can start
  from scratch by removing the entire database directory, i.e.
@@@ -1100,14 -1108,6 +1109,14 @@@ care about the table contents. To chec
  This prints out references to missing audio files as well as invalid
  playlists and mood definitions.
  
 +Similarly, para_audiod refuses to start if its socket file exists, since
 +this indicates that another instance of para_audiod is running. After
 +a crash a stale socket file might remain and you must run
 +
 +      para_audiod --force
 +
 +once to fix it up.
 +
  ---------------------------------------
  Audio formats and audio format handlers
  ---------------------------------------
@@@ -1144,17 -1144,7 +1153,17 @@@ Excited Linear Prediction) coding. It i
  over IP applications, has modest complexity and a small memory
  footprint. Wideband and narrowband (telephone quality) speech are
  supported. As for Vorbis audio, Speex bit-streams are often stored
 -in OGG files.
 +in OGG files. As of 2012 this codec is considered obsolete since the
 +Oppus codec, described below, surpasses its performance in all areas.
 +
 +*OGG/Opus*
 +
 +Opus is a lossy audio compression format standardized through RFC
 +6716 in 2012. It combines the speech-oriented SILK codec and the
 +low-latency CELT (Constrained Energy Lapped Transform) codec. Like
 +OGG/Vorbis and OGG/Speex, Opus data is usually encapsulated in OGG
 +containers. All known software patents which cover Opus are licensed
 +under royalty-free terms.
  
  *AAC*
  
@@@ -1237,7 -1227,9 +1246,7 @@@ chunk table and reads the meta data
  The audio format handler code is linked into para_server and executed
  via the _add_ command. The same code is also available as a stand-alone
  tool, para_afh, which can be used to print the technical data, the
 -chunk table and the meta data of a file. Furthermore, one can use
 -para_afh to cut an audio file, i.e. to select some of its chunks to
 -produce a new file containing only these chunks.
 +chunk table and the meta data of a file.
  
  ----------
  Networking
@@@ -1523,10 -1515,10 +1532,10 @@@ the output to STDOUT, the filter module
  connected to a receiver which produces the input stream and a writer
  which absorbs the output stream.
  
 -Some filters depend on a specific library being installed and are
 -not compiled in if this library was not found at compile time. To
 -see the list of supported filters, run para_filter and para_audiod
 -with the --help option. The output looks similar to the following:
 +Some filters depend on a specific library and are not compiled in
 +if this library was not found at compile time. To see the list of
 +supported filters, run para_filter and para_audiod with the --help
 +option. The output looks similar to the following:
  
        Available filters:
                compress wav amp fecdec wmadec prebuffer oggdec aacdec mp3dec
@@@ -2198,8 -2190,6 +2207,8 @@@ RFC
        Congestion Control ID 2: TCP-like Congestion Control
        - XREFERENCE(http://www.ietf.org/rfc/rfc4342.txt, RFC 4342) (2006):
        Congestion Control ID 3: TCP-Friendly Rate Control (TFRC)
 +      - XREFERENCE(http://www.ietf.org/rfc/rfc6716.txt, RFC 6716) (2012):
 +      Definition of the Opus Audio Codec
  
  Application web pages
  ~~~~~~~~~~~~~~~~~~~~~