~ubuntu-branches/ubuntu/natty/lighttpd/natty

« back to all changes in this revision

Viewing changes to src/mod_usertrack.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2006-12-08 14:40:42 UTC
  • mto: (6.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20061208144042-ehr7h8c6xmijqipw
Tags: upstream-1.4.13
ImportĀ upstreamĀ versionĀ 1.4.13

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
typedef struct {
26
26
        PLUGIN_DATA;
27
 
        
 
27
 
28
28
        plugin_config **config_storage;
29
 
        
30
 
        plugin_config conf; 
 
29
 
 
30
        plugin_config conf;
31
31
} plugin_data;
32
32
 
33
33
/* init the plugin data */
34
34
INIT_FUNC(mod_usertrack_init) {
35
35
        plugin_data *p;
36
 
        
 
36
 
37
37
        p = calloc(1, sizeof(*p));
38
 
        
 
38
 
39
39
        return p;
40
40
}
41
41
 
42
42
/* detroy the plugin data */
43
43
FREE_FUNC(mod_usertrack_free) {
44
44
        plugin_data *p = p_d;
45
 
        
 
45
 
46
46
        UNUSED(srv);
47
 
        
 
47
 
48
48
        if (!p) return HANDLER_GO_ON;
49
 
        
 
49
 
50
50
        if (p->config_storage) {
51
51
                size_t i;
52
52
                for (i = 0; i < srv->config_context->used; i++) {
53
53
                        plugin_config *s = p->config_storage[i];
54
 
                        
 
54
 
55
55
                        buffer_free(s->cookie_name);
56
56
                        buffer_free(s->cookie_domain);
57
 
                        
 
57
 
58
58
                        free(s);
59
59
                }
60
60
                free(p->config_storage);
61
61
        }
62
 
        
 
62
 
63
63
        free(p);
64
 
        
 
64
 
65
65
        return HANDLER_GO_ON;
66
66
}
67
67
 
70
70
SETDEFAULTS_FUNC(mod_usertrack_set_defaults) {
71
71
        plugin_data *p = p_d;
72
72
        size_t i = 0;
73
 
        
74
 
        config_values_t cv[] = { 
 
73
 
 
74
        config_values_t cv[] = {
75
75
                { "usertrack.cookie-name",       NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 0 */
76
76
                { "usertrack.cookie-max-age",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },        /* 1 */
77
77
                { "usertrack.cookie-domain",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },       /* 2 */
78
 
                
79
 
                { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },   
 
78
 
 
79
                { "usertrack.cookiename",        NULL, T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_CONNECTION },
80
80
                { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
81
81
        };
82
 
        
 
82
 
83
83
        if (!p) return HANDLER_ERROR;
84
 
        
 
84
 
85
85
        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
86
 
        
 
86
 
87
87
        for (i = 0; i < srv->config_context->used; i++) {
88
88
                plugin_config *s;
89
 
                
 
89
 
90
90
                s = calloc(1, sizeof(plugin_config));
91
91
                s->cookie_name    = buffer_init();
92
92
                s->cookie_domain  = buffer_init();
93
93
                s->cookie_max_age = 0;
94
 
                
 
94
 
95
95
                cv[0].destination = s->cookie_name;
96
96
                cv[1].destination = &(s->cookie_max_age);
97
97
                cv[2].destination = s->cookie_domain;
98
 
                
 
98
 
99
99
                p->config_storage[i] = s;
100
 
        
 
100
 
101
101
                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) {
102
102
                        return HANDLER_ERROR;
103
103
                }
104
 
        
 
104
 
105
105
                if (buffer_is_empty(s->cookie_name)) {
106
106
                        buffer_copy_string(s->cookie_name, "TRACKID");
107
107
                } else {
109
109
                        for (j = 0; j < s->cookie_name->used - 1; j++) {
110
110
                                char c = s->cookie_name->ptr[j] | 32;
111
111
                                if (c < 'a' || c > 'z') {
112
 
                                        log_error_write(srv, __FILE__, __LINE__, "sb", 
113
 
                                                        "invalid character in usertrack.cookie-name:", 
 
112
                                        log_error_write(srv, __FILE__, __LINE__, "sb",
 
113
                                                        "invalid character in usertrack.cookie-name:",
114
114
                                                        s->cookie_name);
115
 
                                        
 
115
 
116
116
                                        return HANDLER_ERROR;
117
117
                                }
118
118
                        }
119
119
                }
120
 
                
 
120
 
121
121
                if (!buffer_is_empty(s->cookie_domain)) {
122
122
                        size_t j;
123
123
                        for (j = 0; j < s->cookie_domain->used - 1; j++) {
124
124
                                char c = s->cookie_domain->ptr[j];
125
125
                                if (c <= 32 || c >= 127 || c == '"' || c == '\\') {
126
 
                                        log_error_write(srv, __FILE__, __LINE__, "sb", 
127
 
                                                        "invalid character in usertrack.cookie-domain:", 
 
126
                                        log_error_write(srv, __FILE__, __LINE__, "sb",
 
127
                                                        "invalid character in usertrack.cookie-domain:",
128
128
                                                        s->cookie_domain);
129
 
                                        
 
129
 
130
130
                                        return HANDLER_ERROR;
131
131
                                }
132
132
                        }
133
133
                }
134
134
        }
135
 
                
 
135
 
136
136
        return HANDLER_GO_ON;
137
137
}
138
138
 
141
141
static int mod_usertrack_patch_connection(server *srv, connection *con, plugin_data *p) {
142
142
        size_t i, j;
143
143
        plugin_config *s = p->config_storage[0];
144
 
        
 
144
 
145
145
        PATCH(cookie_name);
146
146
        PATCH(cookie_domain);
147
147
        PATCH(cookie_max_age);
148
 
        
 
148
 
149
149
        /* skip the first, the global context */
150
150
        for (i = 1; i < srv->config_context->used; i++) {
151
151
                data_config *dc = (data_config *)srv->config_context->data[i];
152
152
                s = p->config_storage[i];
153
 
                
 
153
 
154
154
                /* condition didn't match */
155
155
                if (!config_check_cond(srv, con, dc)) continue;
156
 
                
 
156
 
157
157
                /* merge config */
158
158
                for (j = 0; j < dc->value->used; j++) {
159
159
                        data_unset *du = dc->value->data[j];
160
 
                        
 
160
 
161
161
                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-name"))) {
162
162
                                PATCH(cookie_name);
163
163
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("usertrack.cookie-max-age"))) {
167
167
                        }
168
168
                }
169
169
        }
170
 
        
 
170
 
171
171
        return 0;
172
172
}
173
173
#undef PATCH
178
178
        unsigned char h[16];
179
179
        MD5_CTX Md5Ctx;
180
180
        char hh[32];
181
 
        
 
181
 
182
182
        if (con->uri.path->used == 0) return HANDLER_GO_ON;
183
 
        
 
183
 
184
184
        mod_usertrack_patch_connection(srv, con, p);
185
 
        
 
185
 
186
186
        if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Cookie"))) {
187
187
                char *g;
188
188
                /* we have a cookie, does it contain a valid name ? */
189
 
                
190
 
                /* parse the cookie 
191
 
                 * 
 
189
 
 
190
                /* parse the cookie
 
191
                 *
192
192
                 * check for cookiename + (WS | '=')
193
 
                 * 
 
193
                 *
194
194
                 */
195
 
                
 
195
 
196
196
                if (NULL != (g = strstr(ds->value->ptr, p->conf.cookie_name->ptr))) {
197
197
                        char *nc;
198
 
                        
 
198
 
199
199
                        /* skip WS */
200
200
                        for (nc = g + p->conf.cookie_name->used-1; *nc == ' ' || *nc == '\t'; nc++);
201
 
                        
 
201
 
202
202
                        if (*nc == '=') {
203
203
                                /* ok, found the key of our own cookie */
204
 
                                
 
204
 
205
205
                                if (strlen(nc) > 32) {
206
206
                                        /* i'm lazy */
207
207
                                        return HANDLER_GO_ON;
208
208
                                }
209
209
                        }
210
210
                }
211
 
        } 
212
 
        
 
211
        }
 
212
 
213
213
        /* set a cookie */
214
214
        if (NULL == (ds = (data_string *)array_get_unused_element(con->response.headers, TYPE_STRING))) {
215
215
                ds = data_response_init();
217
217
        buffer_copy_string(ds->key, "Set-Cookie");
218
218
        buffer_copy_string_buffer(ds->value, p->conf.cookie_name);
219
219
        buffer_append_string(ds->value, "=");
220
 
        
 
220
 
221
221
 
222
222
        /* taken from mod_auth.c */
223
 
        
 
223
 
224
224
        /* generate shared-secret */
225
225
        MD5_Init(&Md5Ctx);
226
226
        MD5_Update(&Md5Ctx, (unsigned char *)con->uri.path->ptr, con->uri.path->used - 1);
227
227
        MD5_Update(&Md5Ctx, (unsigned char *)"+", 1);
228
 
        
 
228
 
229
229
        /* we assume sizeof(time_t) == 4 here, but if not it ain't a problem at all */
230
230
        ltostr(hh, srv->cur_ts);
231
231
        MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
232
232
        ltostr(hh, rand());
233
233
        MD5_Update(&Md5Ctx, (unsigned char *)hh, strlen(hh));
234
 
        
 
234
 
235
235
        MD5_Final(h, &Md5Ctx);
236
 
        
 
236
 
237
237
        buffer_append_string_encoded(ds->value, (char *)h, 16, ENCODING_HEX);
238
238
        buffer_append_string(ds->value, "; Path=/");
239
239
        buffer_append_string(ds->value, "; Version=1");
240
 
        
 
240
 
241
241
        if (!buffer_is_empty(p->conf.cookie_domain)) {
242
242
                buffer_append_string(ds->value, "; Domain=");
243
243
                buffer_append_string_encoded(ds->value, CONST_BUF_LEN(p->conf.cookie_domain), ENCODING_REL_URI);
244
244
        }
245
 
        
 
245
 
246
246
        if (p->conf.cookie_max_age) {
247
247
                buffer_append_string(ds->value, "; max-age=");
248
248
                buffer_append_long(ds->value, p->conf.cookie_max_age);
249
249
        }
250
 
        
 
250
 
251
251
        array_insert_unique(con->response.headers, (data_unset *)ds);
252
 
        
 
252
 
253
253
        return HANDLER_GO_ON;
254
254
}
255
255
 
258
258
int mod_usertrack_plugin_init(plugin *p) {
259
259
        p->version     = LIGHTTPD_VERSION_ID;
260
260
        p->name        = buffer_init_string("usertrack");
261
 
        
 
261
 
262
262
        p->init        = mod_usertrack_init;
263
263
        p->handle_uri_clean  = mod_usertrack_uri_handler;
264
264
        p->set_defaults  = mod_usertrack_set_defaults;
265
265
        p->cleanup     = mod_usertrack_free;
266
 
        
 
266
 
267
267
        p->data        = NULL;
268
 
        
 
268
 
269
269
        return 0;
270
270
}