server: Reduce scope of struct server_command.
[paraslash.git] / command.c
1 /*
2  * Copyright (C) 1997 Andre Noll <maan@tuebingen.mpg.de>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file command.c Client authentication and server commands. */
8
9 #include <netinet/in.h>
10 #include <sys/socket.h>
11 #include <regex.h>
12 #include <signal.h>
13 #include <sys/types.h>
14 #include <osl.h>
15 #include <arpa/inet.h>
16 #include <sys/un.h>
17 #include <netdb.h>
18
19 #include "para.h"
20 #include "error.h"
21 #include "crypt.h"
22 #include "sideband.h"
23 #include "command.h"
24 #include "server.cmdline.h"
25 #include "string.h"
26 #include "afh.h"
27 #include "afs.h"
28 #include "server.h"
29 #include "list.h"
30 #include "send.h"
31 #include "sched.h"
32 #include "vss.h"
33 #include "net.h"
34 #include "daemon.h"
35 #include "fd.h"
36 #include "ipc.h"
37 #include "user_list.h"
38 #include "server.command_list.h"
39 #include "afs.command_list.h"
40 #include "signal.h"
41 #include "version.h"
42
43 /* Defines one command of para_server. */
44 struct server_command {
45         /* The name of the command. */
46         const char *name;
47         /* Pointer to the function that handles the command. */
48         int (*handler)(struct command_context *);
49         /* The privileges a user must have to execute this command. */
50         unsigned int perms;
51         /* One-line description of the command. */
52         const char *description;
53         /* Summary of the command line options. */
54         const char *usage;
55         /* The long help text. */
56         const char *help;
57 };
58
59 static struct server_command afs_cmds[] = {DEFINE_AFS_CMD_ARRAY};
60 static struct server_command server_cmds[] = {DEFINE_SERVER_CMD_ARRAY};
61
62 /** Commands including options must be shorter than this. */
63 #define MAX_COMMAND_LEN 32768
64
65 extern int mmd_mutex;
66 extern struct misc_meta_data *mmd;
67 extern struct sender senders[];
68 int send_afs_status(struct command_context *cc, int parser_friendly);
69
70 static void dummy(__a_unused int s)
71 {
72 }
73
74 static void mmd_dup(struct misc_meta_data *new_mmd)
75 {
76         mutex_lock(mmd_mutex);
77         *new_mmd = *mmd;
78         mutex_unlock(mmd_mutex);
79 }
80
81 /*
82  * Compute human readable string containing vss status for given integer value.
83  *
84  * We don't want to use vss_playing() and friends here because we take a
85  * snapshot of the mmd struct and use the copy for computing the state of the
86  * vss. If the real data were used, we would take the mmd lock for a rather
87  * long time or risk to get an inconsistent view.
88  */
89 static char *vss_status_tohuman(unsigned int flags)
90 {
91         if (flags & VSS_PLAYING)
92                 return para_strdup("playing");
93         if (flags & VSS_NEXT)
94                 return para_strdup("stopped");
95         return para_strdup("paused");
96 }
97
98 /*
99  * return human readable permission string. Never returns NULL.
100  */
101 static char *cmd_perms_itohuman(unsigned int perms)
102 {
103         char *msg = para_malloc(5 * sizeof(char));
104
105         msg[0] = perms & AFS_READ? 'a' : '-';
106         msg[1] = perms & AFS_WRITE? 'A' : '-';
107         msg[2] = perms & VSS_READ? 'v' : '-';
108         msg[3] = perms & VSS_WRITE? 'V' : '-';
109         msg[4] = '\0';
110         return msg;
111 }
112
113 /*
114  * Never returns NULL.
115  */
116 static char *vss_get_status_flags(unsigned int flags)
117 {
118         char *msg = para_malloc(5 * sizeof(char));
119
120         msg[0] = (flags & VSS_PLAYING)? 'P' : '_';
121         msg[1] = (flags & VSS_NOMORE)? 'O' : '_';
122         msg[2] = (flags & VSS_NEXT)? 'N' : '_';
123         msg[3] = (flags & VSS_REPOS)? 'R' : '_';
124         msg[4] = '\0';
125         return msg;
126 }
127
128 static unsigned get_status(struct misc_meta_data *nmmd, int parser_friendly,
129                 char **result)
130 {
131         char *status, *flags; /* vss status info */
132         /* nobody updates our version of "now" */
133         long offset = (nmmd->offset + 500) / 1000;
134         struct timeval current_time;
135         struct para_buffer b = {.flags = parser_friendly? PBF_SIZE_PREFIX : 0};
136
137         /* report real status */
138         status = vss_status_tohuman(nmmd->vss_status_flags);
139         flags = vss_get_status_flags(nmmd->vss_status_flags);
140         clock_get_realtime(&current_time);
141         /*
142          * The calls to WRITE_STATUS_ITEM() below never fail because
143          * b->max_size is zero (unlimited), see para_printf(). However, clang
144          * is not smart enough to prove this and complains nevertheless.
145          * Casting the return value to void silences clang.
146          */
147         (void)WRITE_STATUS_ITEM(&b, SI_STATUS, "%s\n", status);
148         (void)WRITE_STATUS_ITEM(&b, SI_STATUS_FLAGS, "%s\n", flags);
149         (void)WRITE_STATUS_ITEM(&b, SI_OFFSET, "%li\n", offset);
150         (void)WRITE_STATUS_ITEM(&b, SI_AFS_MODE, "%s\n", mmd->afs_mode_string);
151         (void)WRITE_STATUS_ITEM(&b, SI_STREAM_START, "%lu.%lu\n",
152                 (long unsigned)nmmd->stream_start.tv_sec,
153                 (long unsigned)nmmd->stream_start.tv_usec);
154         (void)WRITE_STATUS_ITEM(&b, SI_CURRENT_TIME, "%lu.%lu\n",
155                 (long unsigned)current_time.tv_sec,
156                 (long unsigned)current_time.tv_usec);
157         free(flags);
158         free(status);
159         *result = b.buf;
160         return b.offset;
161 }
162
163 static int check_sender_args(int argc, char * const * argv, struct sender_command_data *scd)
164 {
165         int i;
166         /* this has to match sender.h */
167         const char *subcmds[] = {"add", "delete", "allow", "deny", "on", "off", NULL};
168
169         scd->sender_num = -1;
170         if (argc < 2)
171                 return -E_COMMAND_SYNTAX;
172         for (i = 0; senders[i].name; i++)
173                 if (!strcmp(senders[i].name, argv[1]))
174                         break;
175         PARA_DEBUG_LOG("%d:%s\n", argc, argv[1]);
176         if (!senders[i].name)
177                 return -E_COMMAND_SYNTAX;
178         scd->sender_num = i;
179         for (i = 0; subcmds[i]; i++)
180                 if (!strcmp(subcmds[i], argv[2]))
181                         break;
182         if (!subcmds[i])
183                 return -E_COMMAND_SYNTAX;
184         scd->cmd_num = i;
185         if (!senders[scd->sender_num].client_cmds[scd->cmd_num])
186                 return -E_SENDER_CMD;
187         switch (scd->cmd_num) {
188         case SENDER_ON:
189         case SENDER_OFF:
190                 if (argc != 3)
191                         return -E_COMMAND_SYNTAX;
192                 break;
193         case SENDER_DENY:
194         case SENDER_ALLOW:
195                 if (argc != 4 || parse_cidr(argv[3], scd->host,
196                                 sizeof(scd->host), &scd->netmask) == NULL)
197                         return -E_COMMAND_SYNTAX;
198                 break;
199         case SENDER_ADD:
200         case SENDER_DELETE:
201                 if (argc != 4)
202                         return -E_COMMAND_SYNTAX;
203                 return parse_fec_url(argv[3], scd);
204         default:
205                 return -E_COMMAND_SYNTAX;
206         }
207         return 1;
208 }
209
210 /**
211  * Send a sideband packet through a blocking file descriptor.
212  *
213  * \param scc fd and crypto keys.
214  * \param buf The buffer to send.
215  * \param numbytes The size of \a buf.
216  * \param band The sideband designator of this packet.
217  * \param dont_free If true, never deallocate \a buf.
218  *
219  * The nonblock flag must be disabled for the file descriptor given by \a scc.
220  *
221  * Stream cipher encryption is automatically activated if necessary via the
222  * sideband transformation, depending on the value of \a band.
223  *
224  * \return Standard.
225  *
226  * \sa \ref send_sb_va().
227  */
228 int send_sb(struct stream_cipher_context *scc, void *buf, size_t numbytes,
229                 int band, bool dont_free)
230 {
231         int ret;
232         struct sb_context *sbc;
233         struct iovec iov[2];
234         sb_transformation trafo = band < SBD_PROCEED? NULL : sc_trafo;
235         struct sb_buffer sbb = SBB_INIT(band, buf, numbytes);
236
237         sbc = sb_new_send(&sbb, dont_free, trafo, scc->send);
238         do {
239                 ret = sb_get_send_buffers(sbc, iov);
240                 ret = xwritev(scc->fd, iov, ret);
241                 if (ret < 0)
242                         goto fail;
243         } while (sb_sent(sbc, ret) == false);
244         return 1;
245 fail:
246         sb_free(sbc);
247         return ret;
248 }
249
250 /**
251  * Create a variable sized buffer and send it as a sideband packet.
252  *
253  * \param scc Passed to \ref send_sb.
254  * \param band See \ref send_sb.
255  * \param fmt The format string.
256  *
257  * \return The return value of the underlying call to \ref send_sb.
258  */
259 __printf_3_4 int send_sb_va(struct stream_cipher_context *scc, int band,
260                 const char *fmt, ...)
261 {
262         va_list ap;
263         char *msg;
264         int ret;
265
266         va_start(ap, fmt);
267         ret = xvasprintf(&msg, fmt, ap);
268         va_end(ap);
269         return send_sb(scc, msg, ret, band, false);
270 }
271
272 /**
273  * Send an error message to a client.
274  *
275  * \param cc Client info.
276  * \param err The (positive) error code.
277  *
278  * \return The return value of the underlying call to send_sb_va().
279  */
280 int send_strerror(struct command_context *cc, int err)
281 {
282         return send_sb_va(&cc->scc, SBD_ERROR_LOG, "%s\n", para_strerror(err));
283 }
284
285 /**
286  * Send a sideband packet through a blocking file descriptor.
287  *
288  * \param scc fd and crypto keys.
289  * \param expected_band The expected band designator.
290  * \param max_size Passed to \ref sb_new_recv().
291  * \param result Body of the sideband packet is returned here.
292  *
293  * If \a expected_band is not \p SBD_ANY, the band designator of the received
294  * sideband packet is compared to \a expected_band and a mismatch is considered
295  * an error.
296  *
297  * \return Standard.
298  */
299 int recv_sb(struct stream_cipher_context *scc,
300                 enum sb_designator expected_band,
301                 size_t max_size, struct iovec *result)
302 {
303         int ret;
304         struct sb_context *sbc;
305         struct iovec iov;
306         struct sb_buffer sbb;
307         sb_transformation trafo;
308
309         trafo = expected_band != SBD_ANY && expected_band < SBD_PROCEED?
310                 NULL : sc_trafo;
311         sbc = sb_new_recv(max_size, trafo, scc->recv);
312         for (;;) {
313                 sb_get_recv_buffer(sbc, &iov);
314                 ret = recv_bin_buffer(scc->fd, iov.iov_base, iov.iov_len);
315                 if (ret == 0)
316                         ret = -E_EOF;
317                 if (ret < 0)
318                         goto fail;
319                 ret = sb_received(sbc, ret, &sbb);
320                 if (ret < 0)
321                         goto fail;
322                 if (ret > 0)
323                         break;
324         }
325         ret = -E_BAD_BAND;
326         if (expected_band != SBD_ANY && sbb.band != expected_band)
327                 goto fail;
328         *result = sbb.iov;
329         return 1;
330 fail:
331         sb_free(sbc);
332         return ret;
333 }
334
335 static int com_sender(struct command_context *cc)
336 {
337         int i, ret = 0;
338         char *msg = NULL;
339         struct sender_command_data scd;
340
341         if (cc->argc < 2) {
342                 for (i = 0; senders[i].name; i++) {
343                         char *tmp;
344                         ret = xasprintf(&tmp, "%s%s\n", msg? msg : "",
345                                 senders[i].name);
346                         free(msg);
347                         msg = tmp;
348                 }
349                 return send_sb(&cc->scc, msg, ret, SBD_OUTPUT, false);
350         }
351         ret = check_sender_args(cc->argc, cc->argv, &scd);
352         if (ret < 0) {
353                 if (scd.sender_num < 0)
354                         return ret;
355                 if (strcmp(cc->argv[2], "status") == 0)
356                         msg = senders[scd.sender_num].status();
357                 else
358                         msg = senders[scd.sender_num].help();
359                 return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false);
360         }
361
362         switch (scd.cmd_num) {
363         case SENDER_ADD:
364         case SENDER_DELETE:
365                 assert(senders[scd.sender_num].resolve_target);
366                 ret = senders[scd.sender_num].resolve_target(cc->argv[3], &scd);
367                 if (ret < 0)
368                         return ret;
369         }
370
371         for (i = 0; i < 10; i++) {
372                 mutex_lock(mmd_mutex);
373                 if (mmd->sender_cmd_data.cmd_num >= 0) {
374                         /* another sender command is active, retry in 100ms */
375                         struct timespec ts = {.tv_nsec = 100 * 1000 * 1000};
376                         mutex_unlock(mmd_mutex);
377                         nanosleep(&ts, NULL);
378                         continue;
379                 }
380                 mmd->sender_cmd_data = scd;
381                 mutex_unlock(mmd_mutex);
382                 break;
383         }
384         return (i < 10)? 1 : -E_LOCK;
385 }
386
387 /* server info */
388 static int com_si(struct command_context *cc)
389 {
390         int ret;
391         char *msg, *ut;
392
393         if (cc->argc != 1)
394                 return -E_COMMAND_SYNTAX;
395         mutex_lock(mmd_mutex);
396         ut = daemon_get_uptime_str(now);
397         ret = xasprintf(&msg,
398                 "up: %s\nplayed: %u\n"
399                 "server_pid: %d\n"
400                 "afs_pid: %d\n"
401                 "connections (active/accepted/total): %u/%u/%u\n"
402                 "current loglevel: %s\n"
403                 "supported audio formats: %s\n",
404                 ut, mmd->num_played,
405                 (int)getppid(),
406                 (int)mmd->afs_pid,
407                 mmd->active_connections,
408                 mmd->num_commands,
409                 mmd->num_connects,
410                 conf.loglevel_arg,
411                 AUDIO_FORMAT_HANDLERS
412         );
413         mutex_unlock(mmd_mutex);
414         free(ut);
415         return send_sb(&cc->scc, msg, ret, SBD_OUTPUT, false);
416 }
417
418 /* version */
419 static int com_version(struct command_context *cc)
420 {
421         char *msg;
422         size_t len;
423
424         if (cc->argc != 1)
425                 return -E_COMMAND_SYNTAX;
426         len = xasprintf(&msg, "%s", version_text("server"));
427         return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false);
428 }
429
430 /** These status items are cleared if no audio file is currently open. */
431 #define EMPTY_STATUS_ITEMS \
432         ITEM(PATH) \
433         ITEM(DIRECTORY) \
434         ITEM(BASENAME) \
435         ITEM(SCORE) \
436         ITEM(ATTRIBUTES_BITMAP) \
437         ITEM(ATTRIBUTES_TXT) \
438         ITEM(HASH) \
439         ITEM(IMAGE_ID) \
440         ITEM(IMAGE_NAME) \
441         ITEM(LYRICS_ID) \
442         ITEM(LYRICS_NAME) \
443         ITEM(BITRATE) \
444         ITEM(FORMAT) \
445         ITEM(FREQUENCY) \
446         ITEM(CHANNELS) \
447         ITEM(DURATION) \
448         ITEM(SECONDS_TOTAL) \
449         ITEM(NUM_PLAYED) \
450         ITEM(LAST_PLAYED) \
451         ITEM(TECHINFO) \
452         ITEM(ARTIST) \
453         ITEM(TITLE) \
454         ITEM(YEAR) \
455         ITEM(ALBUM) \
456         ITEM(COMMENT) \
457         ITEM(MTIME) \
458         ITEM(FILE_SIZE) \
459         ITEM(CHUNK_TIME) \
460         ITEM(NUM_CHUNKS) \
461         ITEM(AMPLIFICATION) \
462
463 /**
464  * Write a list of audio-file related status items with empty values.
465  *
466  * This is used by vss when currently no audio file is open.
467  */
468 static unsigned empty_status_items(int parser_friendly, char **result)
469 {
470         char *esi;
471         unsigned len;
472
473         if (parser_friendly)
474                 len = xasprintf(&esi,
475                         #define ITEM(x) "0004 %02x:\n"
476                         EMPTY_STATUS_ITEMS
477                         #undef ITEM
478                         #define ITEM(x) , SI_ ## x
479                         EMPTY_STATUS_ITEMS
480                         #undef ITEM
481                 );
482         else
483                 len = xasprintf(&esi,
484                         #define ITEM(x) "%s:\n"
485                         EMPTY_STATUS_ITEMS
486                         #undef ITEM
487                         #define ITEM(x) ,status_item_list[SI_ ## x]
488                         EMPTY_STATUS_ITEMS
489                         #undef ITEM
490                 );
491         *result = esi;
492         return len;
493 }
494 #undef EMPTY_STATUS_ITEMS
495
496 /* stat */
497 static int com_stat(struct command_context *cc)
498 {
499         int i, ret;
500         struct misc_meta_data tmp, *nmmd = &tmp;
501         char *s;
502         int32_t num = 0;
503         int parser_friendly = 0;
504
505         para_sigaction(SIGUSR1, dummy);
506
507         for (i = 1; i < cc->argc; i++) {
508                 const char *arg = cc->argv[i];
509                 if (arg[0] != '-')
510                         break;
511                 if (!strcmp(arg, "--")) {
512                         i++;
513                         break;
514                 }
515                 if (!strncmp(arg, "-n=", 3)) {
516                         ret = para_atoi32(arg + 3, &num);
517                         if (ret < 0)
518                                 return ret;
519                         continue;
520                 }
521                 if (!strcmp(arg, "-p")) {
522                         parser_friendly = 1;
523                         continue;
524                 }
525                 return -E_COMMAND_SYNTAX;
526         }
527         if (i != cc->argc)
528                 return -E_COMMAND_SYNTAX;
529         for (;;) {
530                 mmd_dup(nmmd);
531                 ret = get_status(nmmd, parser_friendly, &s);
532                 ret = send_sb(&cc->scc, s, ret, SBD_OUTPUT, false);
533                 if (ret < 0)
534                         goto out;
535                 if (nmmd->vss_status_flags & VSS_NEXT) {
536                         char *esi;
537                         ret = empty_status_items(parser_friendly, &esi);
538                         ret = send_sb(&cc->scc, esi, ret, SBD_OUTPUT, false);
539                         if (ret < 0)
540                                 goto out;
541                 } else
542                         send_afs_status(cc, parser_friendly);
543                 ret = 1;
544                 if (num > 0 && !--num)
545                         goto out;
546                 sleep(50);
547                 ret = -E_SERVER_CRASH;
548                 if (getppid() == 1)
549                         goto out;
550         }
551 out:
552         return ret;
553 }
554
555 static int send_list_of_commands(struct command_context *cc, struct server_command *cmd,
556                 const char *handler)
557 {
558         char *msg = NULL;
559
560         for (; cmd->name; cmd++) {
561                 char *tmp, *perms = cmd_perms_itohuman(cmd->perms);
562                 tmp = make_message("%s\t%s\t%s\t%s\n", cmd->name, handler,
563                         perms, cmd->description);
564                 free(perms);
565                 msg = para_strcat(msg, tmp);
566                 free(tmp);
567         }
568         assert(msg);
569         return send_sb(&cc->scc, msg, strlen(msg), SBD_OUTPUT, false);
570 }
571
572 /* returns string that must be freed by the caller */
573 static struct server_command *get_cmd_ptr(const char *name, char **handler)
574 {
575         struct server_command *cmd;
576
577         for (cmd = server_cmds; cmd->name; cmd++)
578                 if (!strcmp(cmd->name, name)) {
579                         if (handler)
580                                 *handler = para_strdup("server"); /* server commands */
581                         return cmd;
582                 }
583         /* not found, look for commands supported by afs */
584         for (cmd = afs_cmds; cmd->name; cmd++)
585                 if (!strcmp(cmd->name, name)) {
586                         if (handler)
587                                 *handler = para_strdup("afs");
588                         return cmd;
589                 }
590         return NULL;
591 }
592
593 /* help */
594 static int com_help(struct command_context *cc)
595 {
596         struct server_command *cmd;
597         char *perms, *handler, *buf;
598         int ret;
599
600         if (cc->argc < 2) {
601                 /* no argument given, print list of commands */
602                 if ((ret = send_list_of_commands(cc, server_cmds, "server")) < 0)
603                         return ret;
604                 return send_list_of_commands(cc, afs_cmds, "afs");
605         }
606         /* argument given for help */
607         cmd = get_cmd_ptr(cc->argv[1], &handler);
608         if (!cmd)
609                 return -E_BAD_CMD;
610         perms = cmd_perms_itohuman(cmd->perms);
611         ret = xasprintf(&buf, "%s - %s\n\n"
612                 "handler: %s\n"
613                 "permissions: %s\n"
614                 "usage: %s\n\n"
615                 "%s\n",
616                 cc->argv[1],
617                 cmd->description,
618                 handler,
619                 perms,
620                 cmd->usage,
621                 cmd->help
622         );
623         free(perms);
624         free(handler);
625         return send_sb(&cc->scc, buf, ret, SBD_OUTPUT, false);
626 }
627
628 /* hup */
629 static int com_hup(struct command_context *cc)
630 {
631         if (cc->argc != 1)
632                 return -E_COMMAND_SYNTAX;
633         kill(getppid(), SIGHUP);
634         return 1;
635 }
636
637 /* term */
638 static int com_term(struct command_context *cc)
639 {
640         if (cc->argc != 1)
641                 return -E_COMMAND_SYNTAX;
642         kill(getppid(), SIGTERM);
643         return 1;
644 }
645
646 static int com_play(struct command_context *cc)
647 {
648         if (cc->argc != 1)
649                 return -E_COMMAND_SYNTAX;
650         mutex_lock(mmd_mutex);
651         mmd->new_vss_status_flags |= VSS_PLAYING;
652         mmd->new_vss_status_flags &= ~VSS_NOMORE;
653         mutex_unlock(mmd_mutex);
654         return 1;
655 }
656
657 /* stop */
658 static int com_stop(struct command_context *cc)
659 {
660         if (cc->argc != 1)
661                 return -E_COMMAND_SYNTAX;
662         mutex_lock(mmd_mutex);
663         mmd->new_vss_status_flags &= ~VSS_PLAYING;
664         mmd->new_vss_status_flags &= ~VSS_REPOS;
665         mmd->new_vss_status_flags |= VSS_NEXT;
666         mutex_unlock(mmd_mutex);
667         return 1;
668 }
669
670 /* pause */
671 static int com_pause(struct command_context *cc)
672 {
673         if (cc->argc != 1)
674                 return -E_COMMAND_SYNTAX;
675         mutex_lock(mmd_mutex);
676         if (!vss_paused() && !vss_stopped()) {
677                 mmd->events++;
678                 mmd->new_vss_status_flags &= ~VSS_PLAYING;
679                 mmd->new_vss_status_flags &= ~VSS_NEXT;
680         }
681         mutex_unlock(mmd_mutex);
682         return 1;
683 }
684
685 /* next */
686 static int com_next(struct command_context *cc)
687 {
688         if (cc->argc != 1)
689                 return -E_COMMAND_SYNTAX;
690         mutex_lock(mmd_mutex);
691         mmd->events++;
692         mmd->new_vss_status_flags |= VSS_NEXT;
693         mutex_unlock(mmd_mutex);
694         return 1;
695 }
696
697 /* nomore */
698 static int com_nomore(struct command_context *cc)
699 {
700         if (cc->argc != 1)
701                 return -E_COMMAND_SYNTAX;
702         mutex_lock(mmd_mutex);
703         if (vss_playing() || vss_paused())
704                 mmd->new_vss_status_flags |= VSS_NOMORE;
705         mutex_unlock(mmd_mutex);
706         return 1;
707 }
708
709 /* ff */
710 static int com_ff(struct command_context *cc)
711 {
712         long promille;
713         int ret, backwards = 0;
714         unsigned i;
715         char c;
716
717         if (cc->argc != 2)
718                 return -E_COMMAND_SYNTAX;
719         if (!(ret = sscanf(cc->argv[1], "%u%c", &i, &c)))
720                 return -E_COMMAND_SYNTAX;
721         if (ret > 1 && c == '-')
722                 backwards = 1; /* jmp backwards */
723         mutex_lock(mmd_mutex);
724         ret = -E_NO_AUDIO_FILE;
725         if (!mmd->afd.afhi.chunks_total || !mmd->afd.afhi.seconds_total)
726                 goto out;
727         promille = (1000 * mmd->current_chunk) / mmd->afd.afhi.chunks_total;
728         if (backwards)
729                 promille -= 1000 * i / mmd->afd.afhi.seconds_total;
730         else
731                 promille += 1000 * i / mmd->afd.afhi.seconds_total;
732         if (promille < 0)
733                 promille = 0;
734         if (promille > 1000) {
735                 mmd->new_vss_status_flags |= VSS_NEXT;
736                 goto out;
737         }
738         mmd->repos_request = (mmd->afd.afhi.chunks_total * promille) / 1000;
739         mmd->new_vss_status_flags |= VSS_REPOS;
740         mmd->new_vss_status_flags &= ~VSS_NEXT;
741         mmd->events++;
742         ret = 1;
743 out:
744         mutex_unlock(mmd_mutex);
745         return ret;
746 }
747
748 /* jmp */
749 static int com_jmp(struct command_context *cc)
750 {
751         long unsigned int i;
752         int ret;
753
754         if (cc->argc != 2)
755                 return -E_COMMAND_SYNTAX;
756         if (sscanf(cc->argv[1], "%lu", &i) <= 0)
757                 return -E_COMMAND_SYNTAX;
758         mutex_lock(mmd_mutex);
759         ret = -E_NO_AUDIO_FILE;
760         if (!mmd->afd.afhi.chunks_total)
761                 goto out;
762         if (i > 100)
763                 i = 100;
764         PARA_INFO_LOG("jumping to %lu%%\n", i);
765         mmd->repos_request = (mmd->afd.afhi.chunks_total * i + 50) / 100;
766         PARA_INFO_LOG("sent: %lu, offset before jmp: %lu\n",
767                 mmd->chunks_sent, mmd->offset);
768         mmd->new_vss_status_flags |= VSS_REPOS;
769         mmd->new_vss_status_flags &= ~VSS_NEXT;
770         ret = 1;
771         mmd->events++;
772 out:
773         mutex_unlock(mmd_mutex);
774         return ret;
775 }
776
777 static int com_tasks(struct command_context *cc)
778 {
779         char *tl = server_get_tasks();
780         int ret = 1;
781
782         if (tl)
783                 ret = send_sb(&cc->scc, tl, strlen(tl), SBD_OUTPUT, false);
784         return ret;
785 }
786
787 /*
788  * check if perms are sufficient to exec a command having perms cmd_perms.
789  * Returns 0 if perms are sufficient, -E_PERM otherwise.
790  */
791 static int check_perms(unsigned int perms, const struct server_command *cmd_ptr)
792 {
793         PARA_DEBUG_LOG("checking permissions\n");
794         return (cmd_ptr->perms & perms) < cmd_ptr->perms ? -E_PERM : 0;
795 }
796
797 static void reset_signals(void)
798 {
799         para_sigaction(SIGCHLD, SIG_IGN);
800         para_sigaction(SIGINT, SIG_DFL);
801         para_sigaction(SIGTERM, SIG_DFL);
802         para_sigaction(SIGHUP, SIG_DFL);
803 }
804
805 struct connection_features {
806         bool sideband_requested;
807         bool aes_ctr128_requested;
808 };
809
810 static int parse_auth_request(char *buf, int len, struct user **u,
811                 struct connection_features *cf)
812 {
813         int ret;
814         char *p, *username, **features = NULL;
815         size_t auth_rq_len = strlen(AUTH_REQUEST_MSG);
816
817         *u = NULL;
818         memset(cf, 0, sizeof(*cf));
819         if (len < auth_rq_len + 2)
820                 return -E_AUTH_REQUEST;
821         if (strncmp(buf, AUTH_REQUEST_MSG, auth_rq_len) != 0)
822                 return -E_AUTH_REQUEST;
823         username = buf + auth_rq_len;
824         p = strchr(username, ' ');
825         if (p) {
826                 int i;
827                 if (p == username)
828                         return -E_AUTH_REQUEST;
829                 *p = '\0';
830                 p++;
831                 create_argv(p, ",", &features);
832                 for (i = 0; features[i]; i++) {
833                         if (strcmp(features[i], "sideband") == 0)
834                                 cf->sideband_requested = true;
835                         else if (strcmp(features[i], "aes_ctr128") == 0)
836                                 cf->aes_ctr128_requested = true;
837                         else {
838                                 ret = -E_BAD_FEATURE;
839                                 goto out;
840                         }
841                 }
842         }
843         PARA_DEBUG_LOG("received auth request for user %s\n", username);
844         *u = lookup_user(username);
845         ret = 1;
846 out:
847         free_argv(features);
848         return ret;
849 }
850
851 #define HANDSHAKE_BUFSIZE 4096
852
853 static int parse_sb_command(struct command_context *cc, struct iovec *iov)
854 {
855         int ret, i;
856         char *p, *end;
857
858         ret = -E_BAD_CMD;
859         if (iov->iov_base == NULL || iov->iov_len == 0)
860                 goto out;
861         p = iov->iov_base;
862         p[iov->iov_len - 1] = '\0'; /* just to be sure */
863         cc->cmd = get_cmd_ptr(p, NULL);
864         if (!cc->cmd)
865                 goto out;
866         ret = check_perms(cc->u->perms, cc->cmd);
867         if (ret < 0)
868                 goto out;
869         end = iov->iov_base + iov->iov_len;
870         for (i = 0; p < end; i++)
871                 p += strlen(p) + 1;
872         cc->argc = i;
873         cc->argv = para_malloc((cc->argc + 1) * sizeof(char *));
874         for (i = 0, p = iov->iov_base; p < end; i++) {
875                 cc->argv[i] = para_strdup(p);
876                 p += strlen(p) + 1;
877         }
878         cc->argv[cc->argc] = NULL;
879         ret = cc->argc;
880 out:
881         free(iov->iov_base);
882         return ret;
883 }
884
885 /**
886  * Perform user authentication and execute a command.
887  *
888  * \param fd The file descriptor to send output to.
889  * \param peername Identifies the connecting peer.
890  *
891  * Whenever para_server accepts an incoming tcp connection on the port it
892  * listens on, it forks and the resulting child calls this function.
893  *
894  * An RSA-based challenge/response is used to authenticate the peer. It that
895  * authentication succeeds, a random session key is generated and sent back to
896  * the peer, encrypted with its RSA public key. From this point on, all
897  * transfers are crypted with this session key.
898  *
899  * Next it is checked if the peer supplied a valid server command or a command
900  * for the audio file selector. If yes, and if the user has sufficient
901  * permissions to execute that command, the function calls the corresponding
902  * command handler which does argument checking and further processing.
903  *
904  * In order to cope with a DOS attacks, a timeout is set up which terminates
905  * the function if the connection was not authenticated when the timeout
906  * expires.
907  *
908  * \sa alarm(2), crypt.c, crypt.h
909  */
910 __noreturn void handle_connect(int fd, const char *peername)
911 {
912         int ret;
913         unsigned char rand_buf[CHALLENGE_SIZE + 2 * SESSION_KEY_LEN];
914         unsigned char challenge_hash[HASH_SIZE];
915         char *command = NULL, *buf = para_malloc(HANDSHAKE_BUFSIZE) /* must be on the heap */;
916         size_t numbytes;
917         struct command_context cc_struct = {.peer = peername}, *cc = &cc_struct;
918         struct iovec iov;
919         struct connection_features cf;
920
921         cc->scc.fd = fd;
922         reset_signals();
923         /* we need a blocking fd here as recv() might return EAGAIN otherwise. */
924         ret = mark_fd_blocking(fd);
925         if (ret < 0)
926                 goto net_err;
927         /* send Welcome message */
928         ret = write_va_buffer(fd, "This is para_server, version "
929                 PACKAGE_VERSION ".\n"
930                 "Features: sideband,aes_ctr128\n"
931         );
932         if (ret < 0)
933                 goto net_err;
934         /* recv auth request line */
935         ret = recv_buffer(fd, buf, HANDSHAKE_BUFSIZE);
936         if (ret < 0)
937                 goto net_err;
938         ret = parse_auth_request(buf, ret, &cc->u, &cf);
939         if (ret < 0)
940                 goto net_err;
941         if (!cf.sideband_requested) { /* sideband is mandatory */
942                 PARA_ERROR_LOG("client did not request sideband\n");
943                 ret = -E_BAD_FEATURE;
944                 goto net_err;
945         }
946         if (cc->u) {
947                 get_random_bytes_or_die(rand_buf, sizeof(rand_buf));
948                 ret = pub_encrypt(cc->u->pubkey, rand_buf, sizeof(rand_buf),
949                         (unsigned char *)buf);
950                 if (ret < 0)
951                         goto net_err;
952                 numbytes = ret;
953         } else {
954                 /*
955                  * We don't want to reveal our user names, so we send a
956                  * challenge to the client even if the user does not exist, and
957                  * fail the authentication later.
958                  */
959                 numbytes = 256;
960                 get_random_bytes_or_die((unsigned char *)buf, numbytes);
961         }
962         PARA_DEBUG_LOG("sending %u byte challenge + session key (%zu bytes)\n",
963                 CHALLENGE_SIZE, numbytes);
964         ret = send_sb(&cc->scc, buf, numbytes, SBD_CHALLENGE, false);
965         buf = NULL;
966         if (ret < 0)
967                 goto net_err;
968         ret = recv_sb(&cc->scc, SBD_CHALLENGE_RESPONSE,
969                 HANDSHAKE_BUFSIZE, &iov);
970         if (ret < 0)
971                 goto net_err;
972         buf = iov.iov_base;
973         numbytes = iov.iov_len;
974         PARA_DEBUG_LOG("received %zu bytes challenge response\n", numbytes);
975         ret = -E_BAD_USER;
976         if (!cc->u)
977                 goto net_err;
978         /*
979          * The correct response is the hash of the first CHALLENGE_SIZE bytes
980          * of the random data.
981          */
982         ret = -E_BAD_AUTH;
983         if (numbytes != HASH_SIZE)
984                 goto net_err;
985         hash_function((char *)rand_buf, CHALLENGE_SIZE, challenge_hash);
986         if (memcmp(challenge_hash, buf, HASH_SIZE))
987                 goto net_err;
988         /* auth successful */
989         alarm(0);
990         PARA_INFO_LOG("good auth for %s\n", cc->u->name);
991         /* init stream cipher keys with the second part of the random buffer */
992         cc->scc.recv = sc_new(rand_buf + CHALLENGE_SIZE, SESSION_KEY_LEN,
993                 cf.aes_ctr128_requested);
994         cc->scc.send = sc_new(rand_buf + CHALLENGE_SIZE + SESSION_KEY_LEN,
995                 SESSION_KEY_LEN, cf.aes_ctr128_requested);
996         ret = send_sb(&cc->scc, NULL, 0, SBD_PROCEED, false);
997         if (ret < 0)
998                 goto net_err;
999         ret = recv_sb(&cc->scc, SBD_COMMAND, MAX_COMMAND_LEN, &iov);
1000         if (ret < 0)
1001                 goto net_err;
1002         ret = parse_sb_command(cc, &iov);
1003         if (ret < 0)
1004                 goto err_out;
1005         cc->argc = ret;
1006         PARA_NOTICE_LOG("calling com_%s() for %s@%s\n", cc->cmd->name,
1007                 cc->u->name, peername);
1008         ret = cc->cmd->handler(cc);
1009         free_argv(cc->argv);
1010         mutex_lock(mmd_mutex);
1011         mmd->num_commands++;
1012         mutex_unlock(mmd_mutex);
1013         if (ret >= 0)
1014                 goto out;
1015 err_out:
1016         if (send_strerror(cc, -ret) >= 0)
1017                 send_sb(&cc->scc, NULL, 0, SBD_EXIT__FAILURE, true);
1018 net_err:
1019         PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
1020 out:
1021         free(buf);
1022         free(command);
1023         mutex_lock(mmd_mutex);
1024         if (cc->cmd && (cc->cmd->perms & AFS_WRITE) && ret >= 0)
1025                 mmd->events++;
1026         mmd->active_connections--;
1027         mutex_unlock(mmd_mutex);
1028         if (ret >= 0) {
1029                 ret = send_sb(&cc->scc, NULL, 0, SBD_EXIT__SUCCESS, true);
1030                 if (ret < 0)
1031                         PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
1032         }
1033         sc_free(cc->scc.recv);
1034         sc_free(cc->scc.send);
1035         exit(ret < 0? EXIT_FAILURE : EXIT_SUCCESS);
1036 }