chiark / gitweb /
Merge from uaudio branch.
authorRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 10:42:26 +0000 (10:42 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sat, 14 Mar 2009 10:42:26 +0000 (10:42 +0000)
In summary:
  - disorder-speaker now uses uaudio and should have more reliable
    gapless play
  - volume setting now uses uaudio
  - the command backend now uses the same scheduling mechanism
    as rtp, and sends silence for pauses
  - multicast API fixes
  - gcrypt API usage fixes

1  2 
server/server.c

diff --combined server/server.c
index 1cfd9bbbb8157cd778da21c3e22b4d0095ebbf49,b00a70e69af29820c5531274f313bb8fbb3a4828..767fa31773ecb2bfeb39e3d5acd4e8ba7d10a1ac
   */
  
  #include "disorder-server.h"
 +#include "basen.h"
  
  #ifndef NONCE_SIZE
  # define NONCE_SIZE 16
  #endif
  
  #ifndef CONFIRM_SIZE
 -# define CONFIRM_SIZE 10
 +/** @brief Size of nonce in confirmation string in 32-bit words
 + *
 + * 64 bits gives 11 digits (in base 62).
 + */
 +# define CONFIRM_SIZE 2
  #endif
  
  int volume_left, volume_right;                /* last known volume */
@@@ -830,17 -825,18 +830,18 @@@ static int c_volume(struct conn *c
      sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
      return 1;
    }
-   if(mixer_control(-1/*as configured*/, &l, &r, set))
+   if(!api || !api->set_volume) {
      sink_writes(ev_writer_sink(c->w), "550 error accessing mixer\n");
-   else {
-     sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r);
-     if(l != volume_left || r != volume_right) {
-       volume_left = l;
-       volume_right = r;
-       snprintf(lb, sizeof lb, "%d", l);
-       snprintf(rb, sizeof rb, "%d", r);
-       eventlog("volume", lb, rb, (char *)0);
-     }
+     return 1;
+   }
+   (set ? api->set_volume : api->get_volume)(&l, &r);
+   sink_printf(ev_writer_sink(c->w), "252 %d %d\n", l, r);
+   if(l != volume_left || r != volume_right) {
+     volume_left = l;
+     volume_right = r;
+     snprintf(lb, sizeof lb, "%d", l);
+     snprintf(rb, sizeof rb, "%d", r);
+     eventlog("volume", lb, rb, (char *)0);
    }
    return 1;
  }
@@@ -1103,7 -1099,7 +1104,7 @@@ static int c_new(struct conn *c
  static int c_rtp_address(struct conn *c,
                         char attribute((unused)) **vec,
                         int attribute((unused)) nvec) {
-   if(config->api == BACKEND_NETWORK) {
+   if(api == &uaudio_rtp) {
      sink_printf(ev_writer_sink(c->w), "252 %s %s\n",
                quoteutf8(config->broadcast.s[0]),
                quoteutf8(config->broadcast.s[1]));
@@@ -1323,23 -1319,30 +1324,23 @@@ static int c_users(struct conn *c
    return 1;                           /* completed */
  }
  
 -/** @brief Base64 mapping table for confirmation strings
 - *
 - * This is used with generic_to_base64() and generic_base64().  We cannot use
 - * the MIME table as that contains '+' and '=' which get quoted when
 - * URL-encoding.  (The CGI still does the URL encoding but it is desirable to
 - * avoid it being necessary.)
 - */
 -static const char confirm_base64_table[] =
 -  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/.*";
 -
  static int c_register(struct conn *c,
                      char **vec,
                      int attribute((unused)) nvec) {
 -  char *buf, *cs;
 -  size_t bufsize;
 -  int offset;
 -
 -  /* The confirmation string is base64(username;nonce) */
 -  bufsize = strlen(vec[0]) + CONFIRM_SIZE + 2;
 -  buf = xmalloc_noptr(bufsize);
 -  offset = byte_snprintf(buf, bufsize, "%s;", vec[0]);
 -  gcry_randomize(buf + offset, CONFIRM_SIZE, GCRY_STRONG_RANDOM);
 -  cs = generic_to_base64((uint8_t *)buf, offset + CONFIRM_SIZE,
 -                       confirm_base64_table);
 +  char *cs;
 +  uint32_t nonce[CONFIRM_SIZE];
 +  char nonce_str[(32 * CONFIRM_SIZE) / 5 + 1];
 +
 +  /* The confirmation string is username/base62(nonce).  The confirmation
 +   * process will pick the username back out to identify them but the _whole_
 +   * string is used as the confirmation string.  Base 62 means we used only
 +   * letters and digits, minimizing the chance of the URL being mispasted. */
 +  gcry_randomize(nonce, sizeof nonce, GCRY_STRONG_RANDOM);
 +  if(basen(nonce, CONFIRM_SIZE, nonce_str, sizeof nonce_str, 62)) {
 +    error(0, "buffer too small encoding confirmation string");
 +    sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
 +  }
 +  byte_xasprintf(&cs, "%s/%s", vec[0], nonce_str);
    if(trackdb_adduser(vec[0], vec[1], config->default_rights, vec[2], cs))
      sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
    else
  static int c_confirm(struct conn *c,
                     char **vec,
                     int attribute((unused)) nvec) {
 -  size_t nuser;
    char *user, *sep;
    rights_type rights;
    const char *host;
      sink_writes(ev_writer_sink(c->w), "530 Authentication failure\n");
      return 1;
    }
 -  if(!(user = generic_base64(vec[0], &nuser, confirm_base64_table))
 -     || !(sep = memchr(user, ';', nuser))) {
 +  /* Picking the LAST / means we don't (here) rule out slashes in usernames. */
 +  if(!(sep = strrchr(vec[0], '/'))) {
      sink_writes(ev_writer_sink(c->w), "550 Malformed confirmation string\n");
      return 1;
    }
 -  *sep = 0;
 +  user = xstrndup(vec[0], sep - vec[0]);
    if(trackdb_confirm(user, vec[0], &rights))
      sink_writes(ev_writer_sink(c->w), "550 Incorrect confirmation string\n");
    else {