chiark / gitweb /
Shorter confirmation URLs. 'confirm=' becomes 'c=' and the
[disorder] / server / server.c
index dfea91e73360a10d41b8040a12c91fa452c48731..a09025ed475f526133f51407a99715e50934b7bd 100644 (file)
 # define NONCE_SIZE 16
 #endif
 
+#ifndef CONFIRM_SIZE
+# define CONFIRM_SIZE 10
+#endif
+
 int volume_left, volume_right;         /* last known volume */
 
 /** @brief Accept all well-formed login attempts
@@ -233,22 +237,15 @@ static int c_play(struct conn *c, char **vec,
 static int c_remove(struct conn *c, char **vec,
                    int attribute((unused)) nvec) {
   struct queue_entry *q;
-  rights_type r;
 
   if(!(q = queue_find(vec[0]))) {
     sink_writes(ev_writer_sink(c->w), "550 no such track on the queue\n");
     return 1;
   }
-  if(q->submitter)
-    if(!strcmp(q->submitter, c->who))
-      r = RIGHT_REMOVE_MINE;
-    else
-      r = RIGHT_REMOVE_ANY;
-  else
-    r = RIGHT_REMOVE_RANDOM;
-  if(!(c->rights & r)) {
+  if(!right_removable(c->rights, c->who, q)) {
+    error(0, "%s attempted remove but lacks required rights", c->who);
     sink_writes(ev_writer_sink(c->w),
-               "550 Not authorized to remove that track\n");
+               "510 Not authorized to remove that track\n");
     return 1;
   }
   queue_remove(q, c->who);
@@ -268,8 +265,6 @@ static int c_remove(struct conn *c, char **vec,
 static int c_scratch(struct conn *c,
                     char **vec,
                     int nvec) {
-  rights_type r;
-  
   if(!playing) {
     sink_writes(ev_writer_sink(c->w), "250 nothing is playing\n");
     return 1;                  /* completed */
@@ -277,16 +272,10 @@ static int c_scratch(struct conn *c,
   /* TODO there is a bug here: if we specify an ID but it's not the currently
    * playing track then you will get 550 if you weren't authorized to scratch
    * the currently playing track. */
-  if(playing->submitter)
-    if(!strcmp(playing->submitter, c->who))
-      r = RIGHT_SCRATCH_MINE;
-    else
-      r = RIGHT_SCRATCH_ANY;
-  else
-    r = RIGHT_SCRATCH_RANDOM;
-  if(!(c->rights & r)) {
+  if(!right_scratchable(c->rights, c->who, playing)) {
+    error(0, "%s attempted scratch but lacks required rights", c->who);
     sink_writes(ev_writer_sink(c->w),
-               "550 Not authorized to scratch that track\n");
+               "510 Not authorized to scratch that track\n");
     return 1;
   }
   scratch(c->who, nvec == 1 ? vec[0] : 0);
@@ -754,7 +743,8 @@ static int c_volume(struct conn *c,
   }
   rights = set ? RIGHT_VOLUME : RIGHT_READ;
   if(!(c->rights & rights)) {
-    sink_writes(ev_writer_sink(c->w), "530 Prohibited\n");
+    error(0, "%s attempted to set volume but lacks required rights", c->who);
+    sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
     return 1;
   }
   if(mixer_control(&l, &r, set))
@@ -849,20 +839,13 @@ static int c_log(struct conn *c,
  * @return 0 if move is prohibited, non-0 if it is allowed
  */
 static int has_move_rights(struct conn *c, struct queue_entry **qs, int nqs) {
-  rights_type r = 0;
-
   for(; nqs > 0; ++qs, --nqs) {
     struct queue_entry *const q = *qs;
 
-    if(q->submitter)
-      if(!strcmp(q->submitter, c->who))
-       r |= RIGHT_MOVE_MINE;
-      else
-      r |= RIGHT_MOVE_ANY;
-    else
-      r |= RIGHT_MOVE_RANDOM;
+    if(!right_movable(c->rights, c->who, q))
+      return 0;
   }
-  return (c->rights & r) == r;
+  return 1;
 }
 
 static int c_move(struct conn *c,
@@ -876,8 +859,9 @@ static int c_move(struct conn *c,
     return 1;
   }
   if(!has_move_rights(c, &q, 1)) {
+    error(0, "%s attempted move but lacks required rights", c->who);
     sink_writes(ev_writer_sink(c->w),
-               "550 Not authorized to move that track\n");
+               "510 Not authorized to move that track\n");
     return 1;
   }
   n = queue_move(q, atoi(vec[1]), c->who);
@@ -910,8 +894,9 @@ static int c_moveafter(struct conn *c,
       return 1;
     }
   if(!has_move_rights(c, qs, nvec)) {
+    error(0, "%s attempted moveafter but lacks required rights", c->who);
     sink_writes(ev_writer_sink(c->w),
-               "550 Not authorized to move those tracks\n");
+               "510 Not authorized to move those tracks\n");
     return 1;
   }
   queue_moveafter(q, nvec, qs, c->who);
@@ -1008,7 +993,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->speaker_backend == BACKEND_NETWORK) {
+  if(config->api == BACKEND_NETWORK) {
     sink_printf(ev_writer_sink(c->w), "252 %s %s\n",
                quoteutf8(config->broadcast.s[0]),
                quoteutf8(config->broadcast.s[1]));
@@ -1120,8 +1105,10 @@ static int c_edituser(struct conn *c,
       sink_writes(ev_writer_sink(c->w), "550 Failed to change setting\n");
     else
       sink_writes(ev_writer_sink(c->w), "250 OK\n");
-  } else
-    sink_writes(ev_writer_sink(c->w), "550 Restricted to administrators\n");
+  } else {
+    error(0, "%s attempted edituser but lacks required rights", c->who);
+    sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
+  }
   return 1;
 }
 
@@ -1144,8 +1131,10 @@ static int c_userinfo(struct conn *c,
        sink_writes(ev_writer_sink(c->w), "555 Not set\n");
     else
       sink_writes(ev_writer_sink(c->w), "550 No such user\n");
-  } else
-    sink_writes(ev_writer_sink(c->w), "550 Restricted to administrators\n");
+  } else {
+    error(0, "%s attempted userinfo but lacks required rights", c->who);
+    sink_writes(ev_writer_sink(c->w), "510 Restricted to administrators\n");
+  }
   return 1;
 }
 
@@ -1173,11 +1162,11 @@ static int c_register(struct conn *c,
   int offset;
 
   /* The confirmation string is base64(username;nonce) */
-  bufsize = strlen(vec[0]) + NONCE_SIZE + 2;
+  bufsize = strlen(vec[0]) + CONFIRM_SIZE + 2;
   buf = xmalloc_noptr(bufsize);
   offset = byte_snprintf(buf, bufsize, "%s;", vec[0]);
-  gcry_randomize(buf + offset, NONCE_SIZE, GCRY_STRONG_RANDOM);
-  cs = mime_to_base64((uint8_t *)buf, offset + NONCE_SIZE);
+  gcry_randomize(buf + offset, CONFIRM_SIZE, GCRY_STRONG_RANDOM);
+  cs = mime_to_base64((uint8_t *)buf, offset + CONFIRM_SIZE);
   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
@@ -1309,7 +1298,9 @@ static int command(struct conn *c, char *line) {
   else {
     if(commands[n].rights
        && !(c->rights & commands[n].rights)) {
-      sink_writes(ev_writer_sink(c->w), "530 Prohibited\n");
+      error(0, "%s attempted %s but lacks required rights", c->who ? c->who : "NULL",
+           commands[n].name);
+      sink_writes(ev_writer_sink(c->w), "510 Prohibited\n");
       return 1;
     }
     ++vec;