paraslash Paraslash Audio Streaming
About   News   Download   Documentation   Development

Macros | Functions | Variables
command.c File Reference

Client authentication and server commands. More...

#include <netinet/in.h>
#include <sys/socket.h>
#include <regex.h>
#include <signal.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <lopsub.h>
#include "para.h"
#include "error.h"
#include "lsu.h"
#include "crypt.h"
#include "sideband.h"
#include "command.h"
#include "string.h"
#include "afh.h"
#include "net.h"
#include "server.h"
#include "list.h"
#include "sched.h"
#include "send.h"
#include "vss.h"
#include "daemon.h"
#include "fd.h"
#include "ipc.h"
#include "server_cmd.lsg.h"
#include "user_list.h"
#include "version.h"

Macros

#define SERVER_CMD_AUX_INFO(_arg)   _arg,
 
#define SERVER_CMD_AUX_INFO(_arg)   #_arg,
 
#define MAX_COMMAND_LEN   32768
 Commands including options must be shorter than this. More...
 
#define EMPTY_STATUS_ITEMS
 These status items are cleared if no audio file is currently open. More...
 
#define ITEM(x)   "0004 %02x:\n"
 
#define ITEM(x)   , (unsigned) SI_ ## x
 
#define ITEM(x)   "%s:\n"
 
#define ITEM(x)   ,status_item_list[SI_ ## x]
 
#define HANDSHAKE_BUFSIZE   4096
 

Functions

int send_afs_status (struct command_context *cc, int parser_friendly)
 Get the current afs status items from the afs process and send it. More...
 
int send_sb (struct stream_cipher_context *scc, void *buf, size_t numbytes, int band, bool dont_free)
 Send a sideband packet through a blocking file descriptor. More...
 
__printf_3_4 int send_sb_va (struct stream_cipher_context *scc, int band, const char *fmt,...)
 Create a variable sized buffer and send it as a sideband packet. More...
 
int send_strerror (struct command_context *cc, int err)
 Send an error message to a client. More...
 
int send_errctx (struct command_context *cc, char *errctx)
 Send an error context to a client,. More...
 
int recv_sb (struct stream_cipher_context *scc, enum sb_designator expected_band, size_t max_size, struct iovec *result)
 Receive a sideband packet from a blocking file descriptor. More...
 
int handle_connect (int fd)
 Perform user authentication and execute a command. More...
 

Variables

int mmd_mutex
 The mutex protecting the shared memory area containing the mmd struct. More...
 
struct misc_meta_datammd
 Pointer to shared memory area for communication between para_server and its children. More...
 
const struct server_cmd_user_data lsg_server_cmd_com_sender_user_data = { .handler = com_sender }
 
const struct server_cmd_user_data lsg_server_cmd_com_si_user_data = { .handler = com_si }
 
const struct server_cmd_user_data lsg_server_cmd_com_version_user_data = { .handler = com_version }
 
const struct server_cmd_user_data lsg_server_cmd_com_stat_user_data = { .handler = com_stat }
 
const struct server_cmd_user_data lsg_server_cmd_com_help_user_data = { .handler = com_help }
 
const struct server_cmd_user_data lsg_server_cmd_com_hup_user_data = { .handler = com_hup }
 
const struct server_cmd_user_data lsg_server_cmd_com_ll_user_data = { .handler = com_ll }
 
const struct server_cmd_user_data lsg_server_cmd_com_term_user_data = { .handler = com_term }
 
const struct server_cmd_user_data lsg_server_cmd_com_play_user_data = { .handler = com_play }
 
const struct server_cmd_user_data lsg_server_cmd_com_stop_user_data = { .handler = com_stop }
 
const struct server_cmd_user_data lsg_server_cmd_com_pause_user_data = { .handler = com_pause }
 
const struct server_cmd_user_data lsg_server_cmd_com_next_user_data = { .handler = com_next }
 
const struct server_cmd_user_data lsg_server_cmd_com_nomore_user_data = { .handler = com_nomore }
 
const struct server_cmd_user_data lsg_server_cmd_com_ff_user_data = { .handler = com_ff }
 
const struct server_cmd_user_data lsg_server_cmd_com_jmp_user_data = { .handler = com_jmp }
 

Detailed Description

Client authentication and server commands.

Macro Definition Documentation

◆ SERVER_CMD_AUX_INFO [1/2]

#define SERVER_CMD_AUX_INFO (   _arg)    _arg,

◆ SERVER_CMD_AUX_INFO [2/2]

#define SERVER_CMD_AUX_INFO (   _arg)    #_arg,

◆ MAX_COMMAND_LEN

#define MAX_COMMAND_LEN   32768

Commands including options must be shorter than this.

◆ EMPTY_STATUS_ITEMS

#define EMPTY_STATUS_ITEMS

These status items are cleared if no audio file is currently open.

◆ ITEM [1/4]

#define ITEM (   x)    "0004 %02x:\n"

◆ ITEM [2/4]

#define ITEM (   x)    , (unsigned) SI_ ## x

◆ ITEM [3/4]

#define ITEM (   x)    "%s:\n"

◆ ITEM [4/4]

#define ITEM (   x)    ,status_item_list[SI_ ## x]

◆ HANDSHAKE_BUFSIZE

#define HANDSHAKE_BUFSIZE   4096

Function Documentation

◆ send_afs_status()

int send_afs_status ( struct command_context cc,
int  parser_friendly 
)

Get the current afs status items from the afs process and send it.

Parameters
ccThe command context, used e.g. for data encryption.
parser_friendlyWhether parser-friendly output format should be used.

As the contents of the afs status items change in time and the command handler only has a COW version created at fork time, it can not send up-to-date afs status items directly. Therefore the usual callback mechanism is used to pass the status items from the afs process to the command handler via a shared memory area and a pipe.

Returns
The return value of the underlying call to send_callback_request().

References send_callback_request().

◆ send_sb()

int send_sb ( struct stream_cipher_context scc,
void *  buf,
size_t  numbytes,
int  band,
bool  dont_free 
)

Send a sideband packet through a blocking file descriptor.

Parameters
sccfd and crypto keys.
bufThe buffer to send.
numbytesThe size of buf.
bandThe sideband designator of this packet.
dont_freeIf true, never deallocate buf.

The nonblock flag must be disabled for the file descriptor given by scc.

Stream cipher encryption is automatically activated if necessary via the sideband transformation, depending on the value of band.

Returns
Standard.
See also
send_sb_va().

References sb_buffer::band, stream_cipher_context::fd, sb_buffer::iov, sb_free(), sb_get_send_buffers(), sb_new_send(), sb_sent(), SBB_INIT, SBD_PROCEED, sc_trafo(), stream_cipher_context::send, and xwritev().

Referenced by send_sb_va().

◆ send_sb_va()

__printf_3_4 int send_sb_va ( struct stream_cipher_context scc,
int  band,
const char *  fmt,
  ... 
)

Create a variable sized buffer and send it as a sideband packet.

Parameters
sccPassed to send_sb.
bandSee send_sb.
fmtThe format string.
Returns
The return value of the underlying call to send_sb.

References sb_buffer::band, send_sb(), and xvasprintf().

Referenced by send_errctx(), and send_strerror().

◆ send_strerror()

int send_strerror ( struct command_context cc,
int  err 
)

Send an error message to a client.

Parameters
ccClient info.
errThe (positive) error code.
Returns
The return value of the underlying call to send_sb_va().

References para_strerror(), SBD_ERROR_LOG, command_context::scc, and send_sb_va().

◆ send_errctx()

int send_errctx ( struct command_context cc,
char *  errctx 
)

Send an error context to a client,.

Parameters
ccClient info.
errctxThe error context string.
Returns
The return value of the underlying call to send_sb_va().

This function frees the error context string after it was sent.

References SBD_ERROR_LOG, command_context::scc, and send_sb_va().

◆ recv_sb()

int recv_sb ( struct stream_cipher_context scc,
enum sb_designator  expected_band,
size_t  max_size,
struct iovec *  result 
)

Receive a sideband packet from a blocking file descriptor.

Parameters
sccfd and crypto keys.
expected_bandThe expected band designator.
max_sizePassed to sb_new_recv().
resultBody of the sideband packet is returned here.

If expected_band is not SBD_ANY, the band designator of the received sideband packet is compared to expected_band and a mismatch is considered an error.

Returns
Standard.

References sb_buffer::band, stream_cipher_context::fd, sb_buffer::iov, stream_cipher_context::recv, recv_bin_buffer(), sb_free(), sb_get_recv_buffer(), sb_new_recv(), sb_received(), SBD_ANY, SBD_PROCEED, and sc_trafo().

◆ handle_connect()

int handle_connect ( int  fd)

Perform user authentication and execute a command.

Parameters
fdThe file descriptor to send output to.

Whenever para_server accepts an incoming tcp connection on the port it listens on, it forks and the resulting child calls this function.

An RSA-based challenge/response is used to authenticate the peer. If the authentication succeeds, a random session key is generated and sent back to the peer, encrypted with its RSA public key. From this point on, all transfers are encrypted with this session key using a stream cipher.

Next it is checked if the peer supplied a valid server command or a command for the audio file selector. If yes, and if the user has sufficient permissions to execute this command, the function calls the corresponding command handler which performs argument checking and further processing.

To cope with DOS attacks, a timer is set up right after the fork. If the connection was still not authenticated when the timeout expires, the child process is terminated.

Returns
Standard.
See also
alarm(2), openssl.c, crypt.h.

References alloc(), APC_CHALLENGE_SIZE, stream_cipher_context::fd, HANDSHAKE_BUFSIZE, HASH2_SIZE, command_context::scc, SESSION_KEY_LEN, and command_context::u.

Variable Documentation

◆ mmd_mutex

int mmd_mutex
extern

The mutex protecting the shared memory area containing the mmd struct.

◆ mmd

struct misc_meta_data* mmd
extern

Pointer to shared memory area for communication between para_server and its children.

Exported to vss.c, command.c and to afs.

◆ lsg_server_cmd_com_sender_user_data

const struct server_cmd_user_data lsg_server_cmd_com_sender_user_data = { .handler = com_sender }

◆ lsg_server_cmd_com_si_user_data

const struct server_cmd_user_data lsg_server_cmd_com_si_user_data = { .handler = com_si }

◆ lsg_server_cmd_com_version_user_data

const struct server_cmd_user_data lsg_server_cmd_com_version_user_data = { .handler = com_version }

◆ lsg_server_cmd_com_stat_user_data

const struct server_cmd_user_data lsg_server_cmd_com_stat_user_data = { .handler = com_stat }

◆ lsg_server_cmd_com_help_user_data

const struct server_cmd_user_data lsg_server_cmd_com_help_user_data = { .handler = com_help }

◆ lsg_server_cmd_com_hup_user_data

const struct server_cmd_user_data lsg_server_cmd_com_hup_user_data = { .handler = com_hup }

◆ lsg_server_cmd_com_ll_user_data

const struct server_cmd_user_data lsg_server_cmd_com_ll_user_data = { .handler = com_ll }

◆ lsg_server_cmd_com_term_user_data

const struct server_cmd_user_data lsg_server_cmd_com_term_user_data = { .handler = com_term }

◆ lsg_server_cmd_com_play_user_data

const struct server_cmd_user_data lsg_server_cmd_com_play_user_data = { .handler = com_play }

◆ lsg_server_cmd_com_stop_user_data

const struct server_cmd_user_data lsg_server_cmd_com_stop_user_data = { .handler = com_stop }

◆ lsg_server_cmd_com_pause_user_data

const struct server_cmd_user_data lsg_server_cmd_com_pause_user_data = { .handler = com_pause }

◆ lsg_server_cmd_com_next_user_data

const struct server_cmd_user_data lsg_server_cmd_com_next_user_data = { .handler = com_next }

◆ lsg_server_cmd_com_nomore_user_data

const struct server_cmd_user_data lsg_server_cmd_com_nomore_user_data = { .handler = com_nomore }

◆ lsg_server_cmd_com_ff_user_data

const struct server_cmd_user_data lsg_server_cmd_com_ff_user_data = { .handler = com_ff }

◆ lsg_server_cmd_com_jmp_user_data

const struct server_cmd_user_data lsg_server_cmd_com_jmp_user_data = { .handler = com_jmp }