auth_static.c 3.96 KB
Newer Older
Philipp Schafft's avatar
Philipp Schafft committed
1
2
3
4
5
/* Icecast
 *
 * This program is distributed under the GNU General Public License, version 2.
 * A copy of this license is included with this source.
 *
6
 * Copyright 2014-2018, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
Philipp Schafft's avatar
Philipp Schafft committed
7
8
 */

9
/**
Philipp Schafft's avatar
Philipp Schafft committed
10
11
12
13
14
15
16
 * Client authentication functions
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Philipp Schafft's avatar
Philipp Schafft committed
17
18
19
/* for strcmp() and strdup() */
#include <string.h>

Philipp Schafft's avatar
Philipp Schafft committed
20
#include "auth.h"
21
#include "cfgfile.h"
Philipp Schafft's avatar
Philipp Schafft committed
22
#include "client.h"
23
#include "util.h"
Philipp Schafft's avatar
Philipp Schafft committed
24
25
26
27
28
29
30

#include "logging.h"
#define CATMODULE "auth_static"

typedef struct auth_static {
    char *username;
    char *password;
31
32
    auth_alter_t action;
    char *arg;
Philipp Schafft's avatar
Philipp Schafft committed
33
34
} auth_static_t;

Marvin Scholz's avatar
Marvin Scholz committed
35
36
37
38
39
static auth_result static_auth(auth_client *auth_user)
{
    client_t        *client     = auth_user->client;
    auth_t          *auth       = client->auth;
    auth_static_t   *auth_info  = auth->state;
Philipp Schafft's avatar
Philipp Schafft committed
40
41
42
43
44
45
46
47
48
49
50

    if (auth_info->username) {
        if (!client->username)
            return AUTH_NOMATCH;
        if (strcmp(auth_info->username, client->username) != 0)
            return AUTH_NOMATCH;
    }

    if (!client->password)
        return AUTH_NOMATCH;

51
52
    if (strcmp(auth_info->password, client->password) != 0)
        return AUTH_FAILED;
Philipp Schafft's avatar
Philipp Schafft committed
53

54
55
56
57
58
59
60
61

    if (auth_info->action != AUTH_ALTER_NOOP) {
        if (auth_alter_client(auth, auth_user, auth_info->action, auth_info->arg) != 0) {
            ICECAST_LOG_ERROR("Can not alter client.");
        }
    }

    return AUTH_OK;
Philipp Schafft's avatar
Philipp Schafft committed
62
63
}

Marvin Scholz's avatar
Marvin Scholz committed
64
65
static void clear_auth (auth_t *auth)
{
Philipp Schafft's avatar
Philipp Schafft committed
66
    auth_static_t *auth_info = auth->state;
67
68
69
    if (!auth_info)
        return;

70
71
72
    free(auth_info->username);
    free(auth_info->password);
    free(auth_info->arg);
Philipp Schafft's avatar
Philipp Schafft committed
73
74
75
76
    free(auth_info);
    auth->state = NULL;
}

Marvin Scholz's avatar
Marvin Scholz committed
77
78
static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode)
{
79
    auth_static_t *auth_info = auth->state;
Marvin Scholz's avatar
Marvin Scholz committed
80
    xmlNodePtr    newnode;
81

82
    newnode = xmlNewChild(srcnode, NULL, XMLSTR("user"), NULL);
83
    xmlNewTextChild(newnode, NULL, XMLSTR("username"), XMLSTR(auth_info->username));
84
85
86
87

    return AUTH_OK;
}

Marvin Scholz's avatar
Marvin Scholz committed
88
89
int  auth_get_static_auth (auth_t *authenticator, config_options_t *options)
{
Philipp Schafft's avatar
Philipp Schafft committed
90
    auth_static_t *auth_info;
Marvin Scholz's avatar
Marvin Scholz committed
91
    int           need_user;
Philipp Schafft's avatar
Philipp Schafft committed
92
93
94
95
96
97

    if (strcmp(authenticator->type, AUTH_TYPE_STATIC) == 0) {
        need_user = 1;
    } else if (strcmp(authenticator->type, AUTH_TYPE_LEGACY_PASSWORD) == 0) {
        need_user = 0;
    } else {
98
        ICECAST_LOG_ERROR("Unknown type.");
Philipp Schafft's avatar
Philipp Schafft committed
99
100
101
102
103
104
105
106
        return -1;
    }

    auth_info = calloc(1, sizeof(auth_static_t));
    if (!auth_info)
        return -1;

    authenticator->authenticate_client = static_auth;
107
    authenticator->listuser = static_userlist;
Philipp Schafft's avatar
Philipp Schafft committed
108
109
    authenticator->free = clear_auth;
    authenticator->state = auth_info;
110
    authenticator->immediate = 1;
Philipp Schafft's avatar
Philipp Schafft committed
111
112
113

    while (options) {
        if (strcmp(options->name, "username") == 0) {
Marvin Scholz's avatar
Marvin Scholz committed
114
115
            if (auth_info->username)
                free(auth_info->username);
Philipp Schafft's avatar
Philipp Schafft committed
116
117
            auth_info->username = strdup(options->value);
        } else if (strcmp(options->name, "password") == 0) {
Marvin Scholz's avatar
Marvin Scholz committed
118
119
            if (auth_info->password)
                free(auth_info->password);
Philipp Schafft's avatar
Philipp Schafft committed
120
            auth_info->password = strdup(options->value);
121
122
123
124
125
126
127
128
129
        } else if (strcmp(options->name, "action") == 0) {
            auth_info->action = auth_str2alter(options->value);
            if (auth_info->action == AUTH_ALTER_NOOP) {
                ICECAST_LOG_ERROR("Invalid action given.");
                clear_auth(authenticator);
                return -1;
            }
        } else if (strcmp(options->name, "argument") == 0) {
            replace_string(&(auth_info->arg), options->value);
Philipp Schafft's avatar
Philipp Schafft committed
130
131
132
133
134
135
136
        } else {
            ICECAST_LOG_ERROR("Unknown option: %s", options->name);
        }
        options = options->next;
    }

    if (need_user && !auth_info->username) {
137
        ICECAST_LOG_ERROR("Username required, but not given.");
Philipp Schafft's avatar
Philipp Schafft committed
138
139
140
        clear_auth(authenticator);
        return -1;
    } else if (!auth_info->password) {
141
        ICECAST_LOG_ERROR("Password required, but not given.");
Philipp Schafft's avatar
Philipp Schafft committed
142
143
144
145
146
147
        clear_auth(authenticator);
        return -1;
    }

    return 0;
}