Skip to content

Commit

Permalink
Adding RTSP authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
wberube committed Oct 27, 2024
1 parent ea11584 commit 1558cb8
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 20 deletions.
9 changes: 6 additions & 3 deletions divinus.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ osd:
mdns:
enable: false

rtsp:
enable: true
enable_auth: false
auth_user: admin
auth_pass: 12345

night_mode:
enable: false
ir_sensor_pin: 62
Expand All @@ -47,9 +53,6 @@ audio:
srate: 48000
bitrate: 128

rtsp:
enable: true

mp4:
enable: true
codec: H264
Expand Down
8 changes: 8 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ int main(int argc, char *argv[]) {
if (app_config.rtsp_enable) {
rtspHandle = rtsp_create(RTSP_MAXIMUM_CONNECTIONS, 1);
HAL_INFO("rtsp", "Started listening for clients...\n");
if (app_config.rtsp_enable_auth) {
if (!app_config.rtsp_auth_user || !app_config.rtsp_auth_pass)
HAL_ERROR("rtsp", "One or both credential fields have been left empty!\n");
else {
rtsp_configure_auth(rtspHandle, app_config.rtsp_auth_user, app_config.rtsp_auth_pass);
HAL_INFO("rtsp", "Authentication enabled!\n");
}
}
}

if (start_sdk())
Expand Down
46 changes: 36 additions & 10 deletions src/rtsp/rtsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern void request_idr();
* PRIVATE DEFINITIONS
******************************************************************************/
#define __STR_OPTIONS "OPTIONS"
#define __STR_AUTH "AUTHORIZATION"
#define __STR_CSEQ "CSEQ"
#define __STR_DESCRIBE "DESCRIBE"
#define __STR_SETUP "SETUP"
Expand Down Expand Up @@ -54,6 +55,7 @@ static inline int __bind_rtp(struct connection_item_t *con );
static inline int __bind_rtcp(struct connection_item_t *con );
static inline int __bind_tcp(unsigned short port);

static void __method_auth(struct connection_item_t *p, rtsp_handle h);
static void __method_options(struct connection_item_t *p, rtsp_handle h);
static void __method_describe(struct connection_item_t *p, rtsp_handle h);
static void __method_setup(struct connection_item_t *p, rtsp_handle h);
Expand Down Expand Up @@ -127,6 +129,14 @@ static inline bufpool_handle __transpool_create(int num)
/******************************************************************************
* RESPONSE IMPLEMENTATIONS
******************************************************************************/
static void __method_auth(struct connection_item_t *p, rtsp_handle h)
{
fprintf(p->fp_tcp_write, "RTSP/1.0 401 Unauthorized\r\n"
"CSeq: %d\r\n"
"WWW-Authenticate: Basic realm=\"Access the camera streams\"\r\n"
"\r\n", p->cseq);
}

static void __method_options(struct connection_item_t *p, rtsp_handle h)
{
fprintf(p->fp_tcp_write, "RTSP/1.0 200 OK\r\n"
Expand Down Expand Up @@ -262,19 +272,18 @@ static void __method_pause(struct connection_item_t *p, rtsp_handle h)
{
fprintf(p->fp_tcp_write,
"RTSP/1.0 "__RESPONCE_STR_METHODNOTALLOWED "\r\n");

}

static void __method_record(struct connection_item_t *p, rtsp_handle h)
{
fprintf(p->fp_tcp_write,
"RTSP/1.0 " __RESPONCE_STR_METHODNOTALLOWED "\r\n");

}

static void __method_error(struct connection_item_t *p, rtsp_handle h)
{
fprintf(p->fp_tcp_write,
"RTSP/1.0 " __RESPONCE_STR_SERVERERROR "\r\n");

}

static void __method_play(struct connection_item_t *p, rtsp_handle h)
Expand Down Expand Up @@ -315,7 +324,6 @@ static int __method_teardown(struct connection_item_t *p, rtsp_handle h)

p->con_state = __CON_S_INIT;


return SUCCESS;
}

Expand Down Expand Up @@ -345,7 +353,7 @@ static int __message_proc_sock(struct list_t *e, void *p)
con->parser_state = __PARSER_S_INIT;
con->method = __METHOD_NONE;

char header = 0, *tok, *last;
char header = 0, isAuthValid = 0, *tok, *last;
unsigned long long session_id;
/* parse line by line. hereafter parser is switched according to the finite state machine */
while (__read_line(con, buf)) {
Expand All @@ -359,12 +367,16 @@ static int __message_proc_sock(struct list_t *e, void *p)
} else if (SCMP(__STR_RECORDING, buf)) { con->method = __METHOD_RECORDING;
} else if (SCMP(__STR_PAUSE, buf)) { con->method = __METHOD_PAUSE;
} else if (SCMP(__STR_TEARDOWN, buf)) { con->method = __METHOD_TEARDOWN;
}
con->parser_state = __PARSER_S_HEAD;
header++;
} header++;
}

if (SCMP(__STR_CSEQ, buf)) {
if (SCMP(__STR_AUTH, buf) && h->isAuthOn) {
char cred[66], valid[256];
sprintf(cred, "%s:%s", h->user, h->pass);
strcpy(valid, "Basic ");
base64_encode(valid + 6, cred, strlen(cred));
isAuthValid = !strncmp(buf + strlen(__STR_AUTH) + 2, valid, strlen(valid));
} else if (SCMP(__STR_CSEQ, buf)) {
ASSERT(tok = strtok_r(buf, ": ", &last), goto error);
ASSERT(tok = strtok_r(NULL, ": ", &last), goto error);
ASSERT((con->cseq = atoi(tok)) > 0, goto error);
Expand Down Expand Up @@ -396,9 +408,12 @@ static int __message_proc_sock(struct list_t *e, void *p)
}

if (con->parser_state == __PARSER_S_ERROR) {
__method_error(con,h);
__method_error(con, h);
} else {
if (con->method != __METHOD_NONE && h->isAuthOn && !isAuthValid)
con->method = __METHOD_AUTH;
switch (con->method) {
case __METHOD_AUTH: __method_auth(con, h); break;
case __METHOD_OPTIONS: __method_options(con, h); break;
case __METHOD_DESCRIBE: __method_describe(con, h); break;
case __METHOD_SETUP: __method_setup(con, h); break;
Expand Down Expand Up @@ -822,6 +837,17 @@ rtsp_handle rtsp_create(unsigned char max_con, int priority)
return NULL;
}

void rtsp_configure_auth(rtsp_handle h, const char *user, const char *pass)
{
if (user && pass) {
h->isAuthOn = 1;
strncpy(h->user, user, sizeof(h->user) - 1);
strncpy(h->pass, pass, sizeof(h->pass) - 1);
} else {
h->isAuthOn = 0;
}
}

int rtsp_tick(rtsp_handle h)
{
ASSERT(h, return FAILURE);
Expand Down
15 changes: 9 additions & 6 deletions src/rtsp/rtsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ enum __connection_state_e {

enum __parser_state_e {
__PARSER_S_INIT = 0,
__PARSER_S_HEAD,
__PARSER_S_CSEQ,
__PARSER_S_TRANSPORT,
__PARSER_S_SESSION,
Expand All @@ -59,6 +58,7 @@ enum __method_e {
__METHOD_TEARDOWN,
__METHOD_PAUSE,
__METHOD_RECORDING,
__METHOD_AUTH,
__METHOD_NONE,
__METHOD_COUNT
};
Expand Down Expand Up @@ -122,18 +122,21 @@ struct __rtsp_obj_t {
threadpool_handle pool;
bufpool_handle con_pool;
bufpool_handle transfer_pool;
unsigned short port;
unsigned short port;
struct __time_stat_t stat;
char isH265;
unsigned char audioPt;
mime_encoded_handle sprop_vps_b64;
mime_encoded_handle sprop_sps_b64;
mime_encoded_handle sprop_pps_b64;
mime_encoded_handle sprop_sps_b16;
unsigned ctx; /* for rand_r */
int con_num;
unsigned char max_con;
int priority;
unsigned ctx; /* for rand_r */
int con_num;
unsigned char max_con;
int priority;
char isAuthOn;
char user[32];
char pass[32];
};

struct sock_select_t {
Expand Down
2 changes: 2 additions & 0 deletions src/rtsp/rtsp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ extern void rtsp_finish(rtsp_handle h);

extern rtsp_handle rtsp_create(unsigned char max_con, int priority);

extern void rtsp_configure_auth(rtsp_handle h, const char *user, const char *pass);

#if defined (__cplusplus)
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ void respond_request(struct Request *req) {

if (app_config.web_enable_auth) {
char *auth = request_header("Authorization");
char cred[65], valid[256];
char cred[66], valid[256];

strcpy(cred, app_config.web_auth_user);
strcpy(cred + strlen(app_config.web_auth_user), ":");
Expand Down

0 comments on commit 1558cb8

Please sign in to comment.