summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/c-modules/authany/mod_authany.c
blob: a5e146c662d7da6fbfc79cb605ad73b7cd7da869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#if CONFIG_FOR_HTTPD_TEST

Alias /authany @DocumentRoot@
<Location /authany>
   require user any-user
   AuthType Basic
   AuthName authany
   <IfDefine !APACHE1>
      <IfVersion >= 2.3>
         AuthBasicProvider any
      </IfVersion>
   </IfDefine>
</Location>

#endif

#include "ap_mmn.h"

/* do not accept empty "" strings */
#define strtrue(s) (s && *s)

#if AP_MODULE_MAGIC_AT_LEAST(20060110, 0)

#include "ap_provider.h"
#include "mod_auth.h"

static authn_status authn_check_password(request_rec *r, const char *user,
                                         const char *password)
{
    return strtrue(r->user) && strcmp(r->user, "guest") == 0
        ? AUTH_GRANTED : AUTH_DENIED;
}

static const authn_provider authn_any_provider =
{
    &authn_check_password
};

static authz_status any_check_authorization(request_rec *r,
                                            const char *requirement,
                                            const void *dummy)
{
#if AP_MODULE_MAGIC_AT_LEAST(20100714,0)
    if (!r->user)
        return AUTHZ_DENIED_NO_USER;
#endif

    return strtrue(r->user) && strcmp(requirement, "any-user") == 0 
        ? AUTHZ_GRANTED : AUTHZ_DENIED;
}

static const authz_provider authz_any_provider =
{
    &any_check_authorization
};

static void extra_hooks(apr_pool_t *p)
{
    ap_register_provider(p, AUTHN_PROVIDER_GROUP,
                         "any", "0", &authn_any_provider);
    ap_register_provider(p, AUTHZ_PROVIDER_GROUP,
                         "user", "0", &authz_any_provider);
}

#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks

#include "apache_httpd_test.h"

#else /* < 2.3 */

#ifdef APACHE2

#include "apr_pools.h"

static void extra_hooks(apr_pool_t *);

#define APACHE_HTTPD_TEST_EXTRA_HOOKS extra_hooks

#else

#define APACHE_HTTPD_TEST_HOOK_ORDER    APR_HOOK_FIRST
#define APACHE_HTTPD_TEST_CHECK_USER_ID authany_handler
#define APACHE_HTTPD_TEST_AUTH_CHECKER  require_any_user

#endif

#include "apache_httpd_test.h"
 
static int require_any_user(request_rec *r)
{
    const apr_array_header_t *requires = ap_requires(r);
    require_line *rq;
    int x;

    if (!requires) {
        return DECLINED;
    }

    rq = (require_line *) requires->elts;

    for (x = 0; x < requires->nelts; x++) {
        const char *line, *requirement;

        line = rq[x].requirement;
        requirement = ap_getword(r->pool, &line, ' ');

        if ((strcmp(requirement, "user") == 0) &&
            (strcmp(line, "any-user") == 0))
        {
            return OK;
        }
    }

    return DECLINED;
}

static int authany_handler(request_rec *r)
{
     const char *sent_pw; 
     int rc = ap_get_basic_auth_pw(r, &sent_pw); 
     char *user;

     if (rc != OK) {
         return rc;
     }

     if (require_any_user(r) != OK) {
         return DECLINED;
     }

#ifdef APACHE1
     user = r->connection->user;
#endif
#ifdef APACHE2
     user = r->user;
#endif

     if (!(strtrue(user) && strtrue(sent_pw))) {
         ap_note_basic_auth_failure(r);  
#ifdef APACHE1
         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                       "Both a username and password must be provided");
#endif
#ifdef APACHE2
         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
                       "Both a username and password must be provided");
#endif
         return HTTP_UNAUTHORIZED;
     }

     return OK;
}

#ifdef APACHE2
static void extra_hooks(apr_pool_t *p)
{
    /* mod_authany and mod_ssl both specify APR_HOOK_FIRST as the
     * ordering of their check-user-id hooks.
     * mod_ssl's must run before mod_authany because it may need to
     * generate the Basic auth information based on the certificate.
     */
    static const char * const modssl_runs_before[] = {"mod_ssl.c", NULL};

    ap_hook_check_user_id(authany_handler, modssl_runs_before, NULL,
                          APR_HOOK_FIRST);
    ap_hook_auth_checker(require_any_user, NULL, NULL, APR_HOOK_FIRST);
}
#endif

#endif

APACHE_HTTPD_TEST_MODULE(authany);