X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/0f55e9050dd26ab8804934a188f1ee8ab8b55ffe..1011401782de9fc44636e88f4b3e4bceb0de4e04:/server/server.c diff --git a/server/server.c b/server/server.c index a69c451..a09025e 100644 --- a/server/server.c +++ b/server/server.c @@ -66,12 +66,16 @@ #include "cache.h" #include "unicode.h" #include "cookies.h" -#include "mime.h" +#include "base64.h" #ifndef NONCE_SIZE # 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])); @@ -1041,14 +1026,15 @@ static int c_cookie(struct conn *c, return 1; } /* Log in */ - c->who = vec[0]; + c->who = user; c->cookie = vec[0]; c->rights = rights; if(strcmp(host, "local")) { info("S%x %s connected with cookie from %s", c->tag, user, host); c->rights |= RIGHT__LOCAL; } - sink_writes(ev_writer_sink(c->w), "230 OK\n"); + /* Response contains username so client knows who they are acting as */ + sink_printf(ev_writer_sink(c->w), "232 %s\n", quoteutf8(user)); return 1; } @@ -1119,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; } @@ -1143,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; } @@ -1172,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 @@ -1308,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;