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