Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
config: make http auth more configurable (plain, digest, both)
  • Loading branch information
perexg committed Mar 11, 2018
1 parent 5c5402b commit d5eaa4c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 8 deletions.
20 changes: 16 additions & 4 deletions src/config.c
Expand Up @@ -1688,7 +1688,7 @@ config_boot ( const char *path, gid_t gid, uid_t uid )
memset(&config, 0, sizeof(config));
config.idnode.in_class = &config_class;
config.ui_quicktips = 1;
config.digest = 1;
config.http_auth = HTTP_AUTH_DIGEST;
config.proxy = 0;
config.realm = strdup("tvheadend");
config.info_area = strdup("login,storage,time");
Expand Down Expand Up @@ -2013,6 +2013,17 @@ config_class_piconscheme_list ( void *o, const char *lang )
return strtab2htsmsg(tab, 1, lang);
}

static htsmsg_t *
config_class_http_auth_list ( void *o, const char *lang )
{
static const struct strtab tab[] = {
{ N_("Plain (insecure)"), HTTP_AUTH_PLAIN },
{ N_("Digest"), HTTP_AUTH_DIGEST },
{ N_("Both plain and digest"), HTTP_AUTH_PLAIN_DIGEST },
};
return strtab2htsmsg(tab, 1, lang);
}

#if ENABLE_MPEGTS_DVB
static void
config_muxconfpath_notify_cb(void *opaque, int disarmed)
Expand Down Expand Up @@ -2331,13 +2342,14 @@ const idclass_t config_class = {
.group = 5
},
{
.type = PT_BOOL,
.type = PT_INT,
.id = "digest",
.name = N_("Digest authentication"),
.name = N_("Authentication type"),
.desc = N_("Digest access authentication is intended as a security trade-off. "
"It is intended to replace unencrypted HTTP basic access authentication. "
"This option should be enabled for standard usage."),
.off = offsetof(config_t, digest),
.list = config_class_http_auth_list,
.off = offsetof(config_t, http_auth),
.opts = PO_EXPERT,
.group = 5
},
Expand Down
2 changes: 1 addition & 1 deletion src/config.h
Expand Up @@ -34,7 +34,7 @@ typedef struct config {
int uilevel;
int uilevel_nochange;
int ui_quicktips;
int digest;
int http_auth;
int proxy;
char *realm;
char *wizard;
Expand Down
11 changes: 8 additions & 3 deletions src/http.c
Expand Up @@ -381,7 +381,8 @@ http_send_header(http_connection_t *hc, int rc, const char *content,

if(rc == HTTP_STATUS_UNAUTHORIZED) {
const char *realm = tvh_str_default(config.realm, "tvheadend");
if (config.digest) {
if (config.http_auth == HTTP_AUTH_DIGEST ||
config.http_auth == HTTP_AUTH_PLAIN_DIGEST) {
if (hc->hc_nonce == NULL)
hc->hc_nonce = http_get_nonce();
char *opaque = http_get_opaque(realm, hc->hc_nonce);
Expand Down Expand Up @@ -1413,7 +1414,9 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
/* Extract authorization */
if((v = http_arg_get(&hc->hc_args, "Authorization")) != NULL) {
if((n = http_tokenize(v, argv, 2, -1)) == 2) {
if (strcasecmp(argv[0], "basic") == 0) {
if ((config.http_auth == HTTP_AUTH_PLAIN ||
config.http_auth == HTTP_AUTH_PLAIN_DIGEST) &&
strcasecmp(argv[0], "basic") == 0) {
n = base64_decode((uint8_t *)authbuf, argv[1], sizeof(authbuf) - 1);
if (n < 0)
n = 0;
Expand All @@ -1428,7 +1431,9 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill)
http_error(hc, HTTP_STATUS_UNAUTHORIZED);
return -1;
}
} else if (strcasecmp(argv[0], "digest") == 0) {
} else if ((config.http_auth == HTTP_AUTH_DIGEST ||
config.http_auth == HTTP_AUTH_PLAIN_DIGEST) &&
strcasecmp(argv[0], "digest") == 0) {
v = http_get_header_value(argv[1], "nonce");
if (v == NULL || !http_nonce_exists(v)) {
free(v);
Expand Down
4 changes: 4 additions & 0 deletions src/http.h
Expand Up @@ -88,6 +88,10 @@ typedef struct http_arg {
#define HTTP_STATUS_HTTP_VERSION 505
#define HTTP_STATUS_OP_NOT_SUPPRT 551

#define HTTP_AUTH_PLAIN 0
#define HTTP_AUTH_DIGEST 1
#define HTTP_AUTH_PLAIN_DIGEST 2

typedef enum http_state {
HTTP_CON_WAIT_REQUEST,
HTTP_CON_READ_HEADER,
Expand Down

4 comments on commit d5eaa4c

@TMHBOFH
Copy link

@TMHBOFH TMHBOFH commented on d5eaa4c Mar 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @perexg
thanks for your amazing work on this project.
Maybe for compatibility reasons, you should make the option "Both plain and digest" as default.

best regards

@Trujulu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, both options should be enabled by default for compatibility reasons!!

@Trujulu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how could I connect tvheadend channels between another tvheadend using digest, would it be possible?

@zipleen
Copy link
Contributor

@zipleen zipleen commented on d5eaa4c Mar 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we all got the digest as "default" because before this commit 0 meant PLAIN and 1 meant plain+digest.

But now, 1 means "only digest".

This also means that this value means 2 different things before this commit and after this commit, which makes detection of this feature impossible because there's no way to detect this specific commit in the middle of the 4.3 version.

Can we simply swap the #define to

#define HTTP_AUTH_DIGEST            2
#define HTTP_AUTH_PLAIN_DIGEST      1

?

This should make everyone that had that option previously enabled (the value 1) as "plain+digest" (which was what the previous value meant).

edit: found a way to detect this specific commit. the "type" of the variable changed from "bool" to "int" and the meta properties specify this

edit2: by the way, the default is actually 0, according to the metadata, which means PLAIN only.

Please sign in to comment.