~ubuntu-branches/ubuntu/trusty/nginx/trusty-updates

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_geoip_module.c

  • Committer: Package Import Robot
  • Author(s): Cyril Lavier, Cyril Lavier
  • Date: 2012-06-27 13:52:03 UTC
  • mfrom: (4.2.51 sid)
  • Revision ID: package-import@ubuntu.com-20120627135203-82rzqkajfpo1m77u
Tags: 1.2.1-2
[Cyril Lavier]
* Urgency set to medium, security bug in naxsi module, fix via upstream.
* debian/modules/naxsi:
  + Updated naxsi module to version 0.46-1 fixing the following security
    issue : potential file disclosure in nx_extract.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 
15
15
 
16
16
typedef struct {
17
 
    GeoIP      *country;
18
 
    GeoIP      *org;
19
 
    GeoIP      *city;
 
17
    GeoIP        *country;
 
18
    GeoIP        *org;
 
19
    GeoIP        *city;
 
20
    ngx_array_t  *proxies;    /* array of ngx_cidr_t */
 
21
    ngx_flag_t    proxy_recursive;
20
22
} ngx_http_geoip_conf_t;
21
23
 
22
24
 
23
25
typedef struct {
24
 
    ngx_str_t  *name;
25
 
    uintptr_t   data;
 
26
    ngx_str_t    *name;
 
27
    uintptr_t     data;
26
28
} ngx_http_geoip_var_t;
27
29
 
28
30
 
29
31
typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
30
32
 
 
33
static u_long ngx_http_geoip_addr(ngx_http_request_t *r,
 
34
    ngx_http_geoip_conf_t *gcf);
31
35
static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
32
36
    ngx_http_variable_value_t *v, uintptr_t data);
33
37
static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
44
48
 
45
49
static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
46
50
static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
 
51
static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
47
52
static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
48
53
    void *conf);
49
54
static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
50
55
    void *conf);
51
56
static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
52
57
    void *conf);
 
58
static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
 
59
    void *conf);
 
60
static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
 
61
    ngx_cidr_t *cidr);
53
62
static void ngx_http_geoip_cleanup(void *data);
54
63
 
55
64
 
76
85
      0,
77
86
      NULL },
78
87
 
 
88
    { ngx_string("geoip_proxy"),
 
89
      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
 
90
      ngx_http_geoip_proxy,
 
91
      NGX_HTTP_MAIN_CONF_OFFSET,
 
92
      0,
 
93
      NULL },
 
94
 
 
95
    { ngx_string("geoip_proxy_recursive"),
 
96
      NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
 
97
      ngx_conf_set_flag_slot,
 
98
      NGX_HTTP_MAIN_CONF_OFFSET,
 
99
      offsetof(ngx_http_geoip_conf_t, proxy_recursive),
 
100
      NULL },
 
101
 
79
102
      ngx_null_command
80
103
};
81
104
 
85
108
    NULL,                                  /* postconfiguration */
86
109
 
87
110
    ngx_http_geoip_create_conf,            /* create main configuration */
88
 
    NULL,                                  /* init main configuration */
 
111
    ngx_http_geoip_init_conf,              /* init main configuration */
89
112
 
90
113
    NULL,                                  /* create server configuration */
91
114
    NULL,                                  /* merge server configuration */
182
205
 
183
206
 
184
207
static u_long
185
 
ngx_http_geoip_addr(ngx_http_request_t *r)
 
208
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
186
209
{
187
 
    struct sockaddr_in   *sin;
188
 
#if (NGX_HAVE_INET6)
189
 
    u_char               *p;
190
 
    u_long                addr;
191
 
    struct sockaddr_in6  *sin6;
192
 
#endif
193
 
 
194
 
    switch (r->connection->sockaddr->sa_family) {
195
 
 
196
 
    case AF_INET:
197
 
        sin = (struct sockaddr_in *) r->connection->sockaddr;
198
 
        return ntohl(sin->sin_addr.s_addr);
199
 
 
200
 
#if (NGX_HAVE_INET6)
201
 
 
202
 
    case AF_INET6:
203
 
        sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
204
 
 
205
 
        if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
206
 
            p = sin6->sin6_addr.s6_addr;
207
 
            addr = p[12] << 24;
208
 
            addr += p[13] << 16;
209
 
            addr += p[14] << 8;
210
 
            addr += p[15];
211
 
 
212
 
            return addr;
 
210
    ngx_addr_t           addr;
 
211
    ngx_table_elt_t     *xfwd;
 
212
    struct sockaddr_in  *sin;
 
213
 
 
214
    addr.sockaddr = r->connection->sockaddr;
 
215
    addr.socklen = r->connection->socklen;
 
216
    /* addr.name = r->connection->addr_text; */
 
217
 
 
218
    xfwd = r->headers_in.x_forwarded_for;
 
219
 
 
220
    if (xfwd != NULL && gcf->proxies != NULL) {
 
221
        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data,
 
222
                                           xfwd->value.len, gcf->proxies,
 
223
                                           gcf->proxy_recursive);
 
224
    }
 
225
 
 
226
#if (NGX_HAVE_INET6)
 
227
 
 
228
    if (addr.sockaddr->sa_family == AF_INET6) {
 
229
        struct in6_addr  *inaddr6;
 
230
 
 
231
        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
 
232
 
 
233
        if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
 
234
            return ntohl(*(in_addr_t *) &inaddr6->s6_addr[12]);
213
235
        }
 
236
    }
214
237
 
215
238
#endif
 
239
 
 
240
    if (addr.sockaddr->sa_family != AF_INET) {
 
241
        return INADDR_NONE;
216
242
    }
217
243
 
218
 
    return INADDR_NONE;
 
244
    sin = (struct sockaddr_in *) addr.sockaddr;
 
245
    return ntohl(sin->sin_addr.s_addr);
219
246
}
220
247
 
221
248
 
235
262
        goto not_found;
236
263
    }
237
264
 
238
 
    val = handler(gcf->country, ngx_http_geoip_addr(r));
 
265
    val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
239
266
 
240
267
    if (val == NULL) {
241
268
        goto not_found;
273
300
        goto not_found;
274
301
    }
275
302
 
276
 
    val = handler(gcf->org, ngx_http_geoip_addr(r));
 
303
    val = handler(gcf->org, ngx_http_geoip_addr(r, gcf));
277
304
 
278
305
    if (val == NULL) {
279
306
        goto not_found;
453
480
    gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
454
481
 
455
482
    if (gcf->city) {
456
 
        return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r));
 
483
        return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
457
484
    }
458
485
 
459
486
    return NULL;
490
517
        return NULL;
491
518
    }
492
519
 
 
520
    conf->proxy_recursive = NGX_CONF_UNSET;
 
521
 
493
522
    cln = ngx_pool_cleanup_add(cf->pool, 0);
494
523
    if (cln == NULL) {
495
524
        return NULL;
503
532
 
504
533
 
505
534
static char *
 
535
ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
 
536
{
 
537
    ngx_http_geoip_conf_t  *gcf = conf;
 
538
 
 
539
    ngx_conf_init_value(gcf->proxy_recursive, 0);
 
540
 
 
541
    return NGX_CONF_OK;
 
542
}
 
543
 
 
544
 
 
545
static char *
506
546
ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
507
547
{
508
548
    ngx_http_geoip_conf_t  *gcf = conf;
652
692
}
653
693
 
654
694
 
 
695
static char *
 
696
ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
697
{
 
698
    ngx_http_geoip_conf_t  *gcf = conf;
 
699
 
 
700
    ngx_str_t   *value;
 
701
    ngx_cidr_t  cidr, *c;
 
702
 
 
703
    value = cf->args->elts;
 
704
 
 
705
    if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
 
706
        return NGX_CONF_ERROR;
 
707
    }
 
708
 
 
709
    if (gcf->proxies == NULL) {
 
710
        gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
 
711
        if (gcf->proxies == NULL) {
 
712
            return NGX_CONF_ERROR;
 
713
        }
 
714
    }
 
715
 
 
716
    c = ngx_array_push(gcf->proxies);
 
717
    if (c == NULL) {
 
718
        return NGX_CONF_ERROR;
 
719
    }
 
720
 
 
721
    *c = cidr;
 
722
 
 
723
    return NGX_CONF_OK;
 
724
}
 
725
 
 
726
static ngx_int_t
 
727
ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
 
728
{
 
729
    ngx_int_t  rc;
 
730
 
 
731
    if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
 
732
        cidr->family = AF_INET;
 
733
        cidr->u.in.addr = 0xffffffff;
 
734
        cidr->u.in.mask = 0xffffffff;
 
735
 
 
736
        return NGX_OK;
 
737
    }
 
738
 
 
739
    rc = ngx_ptocidr(net, cidr);
 
740
 
 
741
    if (rc == NGX_ERROR) {
 
742
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
 
743
        return NGX_ERROR;
 
744
    }
 
745
 
 
746
    if (rc == NGX_DONE) {
 
747
        ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
 
748
                           "low address bits of %V are meaningless", net);
 
749
    }
 
750
 
 
751
    return NGX_OK;
 
752
}
 
753
 
 
754
 
655
755
static void
656
756
ngx_http_geoip_cleanup(void *data)
657
757
{