Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 160203
Collapse All | Expand All

(-)privoxy~/GNUmakefile.in (-2 / +2 lines)
Lines 187-193 Link Here
187
C_SRC  = actions.c cgi.c cgiedit.c cgisimple.c deanimate.c encode.c \
187
C_SRC  = actions.c cgi.c cgiedit.c cgisimple.c deanimate.c encode.c \
188
         errlog.c filters.c gateway.c jbsockets.c jcc.c killpopup.c \
188
         errlog.c filters.c gateway.c jbsockets.c jcc.c killpopup.c \
189
         list.c loadcfg.c loaders.c miscutil.c parsers.c ssplit.c \
189
         list.c loadcfg.c loaders.c miscutil.c parsers.c ssplit.c \
190
         urlmatch.c
190
         urlmatch.c addrlist.c jb_socket_set.c
191
191
192
C_OBJS = $(C_SRC:.c=.@OBJEXT@)
192
C_OBJS = $(C_SRC:.c=.@OBJEXT@)
193
C_HDRS = $(C_SRC:.c=.h) project.h actionlist.h
193
C_HDRS = $(C_SRC:.c=.h) project.h actionlist.h
Lines 241-247 Link Here
241
SPECIAL_CFLAGS = @SPECIAL_CFLAGS@
241
SPECIAL_CFLAGS = @SPECIAL_CFLAGS@
242
242
243
# Add your flags here 
243
# Add your flags here 
244
OTHER_CFLAGS =   
244
OTHER_CFLAGS = -DINET6
245
245
246
CFLAGS = @CFLAGS@ @CPPFLAGS@ $(OTHER_CFLAGS) $(SPECIAL_CFLAGS) -Wall \
246
CFLAGS = @CFLAGS@ @CPPFLAGS@ $(OTHER_CFLAGS) $(SPECIAL_CFLAGS) -Wall \
247
         @STATIC_PCRE_ONLY@ -Ipcre 
247
         @STATIC_PCRE_ONLY@ -Ipcre 
(-)privoxy~/addrlist.c (+198 lines)
Line 0 Link Here
1
const char addrlist_rcs[] = "$Id: $";
2
/*********************************************************************
3
 *
4
 * File        :  $Source: $
5
 *
6
 * Purpose     :  Declares functions to handle lists of network addresses.
7
 *                Functions declared include:
8
 *                   `destroy_addr_list', head_addr_list and `tail_addr_list'
9
 *
10
 * Copyright   :  Written by and Copyright (C) 2002 Lionel Elie Mamane
11
 *                <lionel@mamane.lu>
12
 *
13
 *                This program is free software; you can redistribute it
14
 *                and/or modify it under the terms of the GNU General
15
 *                Public License as published by the Free Software
16
 *                Foundation; either version 2 of the License, or (at
17
 *                your option) any later version.
18
 *
19
 *                This program is distributed in the hope that it will
20
 *                be useful, but WITHOUT ANY WARRANTY; without even the
21
 *                implied warranty of MERCHANTABILITY or FITNESS FOR A
22
 *                PARTICULAR PURPOSE.  See the GNU General Public
23
 *                License for more details.
24
 *
25
 *                The GNU General Public License should be included with
26
 *                this file.  If not, you can view it at
27
 *                http://www.gnu.org/copyleft/gpl.html
28
 *                or write to the Free Software Foundation, Inc., 59
29
 *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30
 *
31
 * Revisions   :
32
 *    $Log: addrlist.c,v $
33
 *
34
 *********************************************************************/
35
36
#include "addrlist.h"
37
#include <sys/types.h>
38
#include <sys/socket.h>
39
#include <netdb.h>
40
#include <string.h>
41
42
/*********************************************************************
43
 *
44
 * Function    :  acceptable
45
 *
46
 * Description :  Test wheter an address is acceptable for our use
47
 *                Currently, this means either an IPv4 or an IPv6 address
48
 *
49
 * Parameters  :
50
 *          0  :  addr = the address to test
51
 *
52
 * Returns     :  0             = false / no
53
 *                anything else = true / yes
54
 *
55
 *********************************************************************/
56
static int acceptable (struct sockaddr_storage *addr)
57
{
58
   switch(addr->ss_family)
59
   {
60
   case AF_INET:
61
#ifdef INET6
62
   case AF_INET6:
63
#endif
64
      return !0;
65
   default:
66
      return 0;
67
   }
68
}
69
70
/*********************************************************************
71
 *
72
 * Function    :  skim
73
 *
74
 * Description :  Get the first acceptable address in head position
75
 *                Assumes there is one
76
 *
77
 * Parameters  :
78
 *          0  :  l = the list to skim
79
 *
80
 * Returns     :  the skimmed list
81
 *
82
 *********************************************************************/
83
static addr_list *skim (addr_list *l)
84
{
85
   if (acceptable((struct sockaddr_storage*)l->ai_addr))
86
      return l;
87
   return skim(l->ai_next);
88
}
89
90
/*********************************************************************
91
 *
92
 * Function    :  tail_addr_list
93
 *
94
 * Description :  Get the tail of an address list
95
 *
96
 * Parameters  :
97
 *          0  :  l = the list to get the tail of
98
 *
99
 * Returns     :  the tail of the list
100
 *                If the list has no tail (i.e. is nil), unspecified
101
 *                behaviour
102
 *
103
 *********************************************************************/
104
addr_list *tail_addr_list(addr_list *l)
105
{
106
   return skim(l)->ai_next;
107
}
108
109
/*********************************************************************
110
 *
111
 * Function    :  head_addr_list
112
 *
113
 * Description :  Get the head of an address list
114
 *
115
 * Parameters  :
116
 *          0  :  l = the list to get the head of
117
 *
118
 * Returns     :  the head of the list
119
 *                If the list has no head (i.e. is nil), unspecified
120
 *                behaviour
121
 *
122
 *********************************************************************/
123
struct sockaddr_storage *head_addr_list(addr_list *l)
124
{
125
   return (struct sockaddr_storage *)skim(l)->ai_addr;
126
}
127
128
/*********************************************************************
129
 *
130
 * Function    :  cpy_head_addr_list
131
 *
132
 * Description :  Copy the head of an address list to the given destination
133
 *
134
 * Parameters  :
135
 *          0  :  l = the list to get the head of
136
 *          1  :  r = where to put the result
137
 *
138
 * Returns     :  Nothing
139
 *                If the list has no head (i.e. is nil), unspecified
140
 *                behaviour
141
 *
142
 *********************************************************************/
143
void cpy_head_addr_list(addr_list *l, struct sockaddr_storage *r, size_t *addrlen)
144
{
145
   addr_list *sl = skim(l);
146
   memcpy(r, sl->ai_addr, sl->ai_addrlen);
147
   *addrlen = sl->ai_addrlen;
148
}
149
150
/*********************************************************************
151
 *
152
 * Function    :  destroy_addr_list
153
 *
154
 * Description :  Unallocate memory allocated to an address list
155
 *
156
 * Parameters  :
157
 *          0  :  l = the list to unallocate
158
 *
159
 * Returns     :  nothing
160
 *
161
 *********************************************************************/
162
void destroy_addr_list(addr_list *l)
163
{
164
   freeaddrinfo(l);
165
}
166
167
/*********************************************************************
168
 *
169
 * Function    :  is_nil_addr_list
170
 *
171
 * Description :  Test wheter a list is nil (empty)
172
 *
173
 * Parameters  :
174
 *          0  :  l = the list to test
175
 *
176
 * Returns     :  0             = false if list has a head,
177
 *                anything else = true if list is nil
178
 *
179
 *********************************************************************/
180
int is_nil_addr_list(addr_list *l)
181
{
182
   /* We are searching for a witness of non-nilness (modulo acceptability)
183
    * If none is found, the list is nil
184
    */
185
   if (l==NULL)
186
      /* Empty list*/
187
      return !0;
188
   if (acceptable(head_addr_list(l)))
189
      /* Witness found */
190
      return 0;
191
   return is_nil_addr_list(l->ai_next);
192
}
193
194
/*
195
  Local Variables:
196
  tab-width: 3
197
  end:
198
*/
(-)privoxy~/addrlist.h (+56 lines)
Line 0 Link Here
1
#ifndef ADDR_LIST_H_INCLUDED
2
#define ADDR_LIST_H_INCLUDED
3
#define ADDR_LIST_H_VERSION "$Id: $"
4
/*********************************************************************
5
 *
6
 * File        :  $Source: $
7
 *
8
 * Purpose     :  Declares functions to handle lists of network addresses.
9
 *                Functions declared include:
10
 *                   `destroy_addr_list', head_addr_list and `tail_addr_list'
11
 *
12
 * Copyright   :  Written by and Copyright (C) 2002 Lionel Elie Mamane
13
 *                <lionel@mamane.lu>
14
 *
15
 *                This program is free software; you can redistribute it
16
 *                and/or modify it under the terms of the GNU General
17
 *                Public License as published by the Free Software
18
 *                Foundation; either version 2 of the License, or (at
19
 *                your option) any later version.
20
 *
21
 *                This program is distributed in the hope that it will
22
 *                be useful, but WITHOUT ANY WARRANTY; without even the
23
 *                implied warranty of MERCHANTABILITY or FITNESS FOR A
24
 *                PARTICULAR PURPOSE.  See the GNU General Public
25
 *                License for more details.
26
 *
27
 *                The GNU General Public License should be included with
28
 *                this file.  If not, you can view it at
29
 *                http://www.gnu.org/copyleft/gpl.html
30
 *                or write to the Free Software Foundation, Inc., 59
31
 *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32
 *
33
 * Revisions   :
34
 *    $Log: addrlist.h,v $
35
 *
36
 *********************************************************************/
37
38
#include <sys/socket.h>
39
40
typedef struct addrinfo addr_list;
41
42
addr_list *tail_addr_list(addr_list *l);
43
struct sockaddr_storage *head_addr_list(addr_list *l);
44
void cpy_head_addr_list(addr_list *l, struct sockaddr_storage *r, size_t *addrlen);
45
void destroy_addr_list(addr_list *l);
46
int is_nil_addr_list(addr_list *l);
47
48
#define freez_addr_list(X)  { if(X) { destroy_addr_list(X); X = NULL ; } }
49
50
#endif /* ndef LIST_H_INCLUDED */
51
52
/*
53
  Local Variables:
54
  tab-width: 3
55
  end:
56
*/
(-)privoxy~/cgi.c (-3 / +4 lines)
Lines 14-19 Link Here
14
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
14
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
15
 *                Privoxy team. http://www.privoxy.org/
15
 *                Privoxy team. http://www.privoxy.org/
16
 *
16
 *
17
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
18
 *                for IPv6 support on 8 December 2002, 24 January 2003.
19
 *
17
 *                Based on the Internet Junkbuster originally written
20
 *                Based on the Internet Junkbuster originally written
18
 *                by and Copyright (C) 1997 Anonymous Coders and 
21
 *                by and Copyright (C) 1997 Anonymous Coders and 
19
 *                Junkbusters Corporation.  http://www.junkbusters.com
22
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 2250-2256 Link Here
2250
 *********************************************************************/
2253
 *********************************************************************/
2251
struct map *default_exports(const struct client_state *csp, const char *caller)
2254
struct map *default_exports(const struct client_state *csp, const char *caller)
2252
{
2255
{
2253
   char buf[20];
2254
   jb_err err;
2256
   jb_err err;
2255
   struct map * exports;
2257
   struct map * exports;
2256
   int local_help_exists = 0;
2258
   int local_help_exists = 0;
Lines 2286-2293 Link Here
2286
   if (!err) err = map_block_killer(exports, "can-toggle");
2288
   if (!err) err = map_block_killer(exports, "can-toggle");
2287
#endif
2289
#endif
2288
2290
2289
   snprintf(buf, 20, "%d", csp->config->hport);
2291
   if (!err) err = map(exports, "my-port", 1, csp->my_port_str, 1);
2290
   if (!err) err = map(exports, "my-port", 1, buf, 1);
2291
2292
2292
   if(!strcmp(CODE_STATUS, "stable"))
2293
   if(!strcmp(CODE_STATUS, "stable"))
2293
   {
2294
   {
(-)privoxy~/errlog.c (+7 lines)
Lines 739-744 Link Here
739
            break;
739
            break;
740
         case 'E':
740
         case 'E':
741
            /* Non-standard: Print error code from errno */
741
            /* Non-standard: Print error code from errno */
742
            /* TODO
743
             * This is not only not standard, but clashes
744
             * with the E modifier on the GNU (and possibly
745
             * other systems): It means double (floating point)
746
             * number in exponential notation, with capital E
747
             * for mantiss / exponenent separator
748
             */
742
#ifdef _WIN32
749
#ifdef _WIN32
743
            ival = WSAGetLastError();
750
            ival = WSAGetLastError();
744
            sval = w32_socket_strerr(ival, tempbuf);
751
            sval = w32_socket_strerr(ival, tempbuf);
(-)privoxy~/filters.c (-54 / +330 lines)
Lines 15-20 Link Here
15
 * Copyright   :  Written by and Copyright (C) 2001, 2004 the SourceForge
15
 * Copyright   :  Written by and Copyright (C) 2001, 2004 the SourceForge
16
 *                Privoxy team. http://www.privoxy.org/
16
 *                Privoxy team. http://www.privoxy.org/
17
 *
17
 *
18
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
19
 *                for IPv6 support on 8 December 2002, 24 January 2003.
20
 *
18
 *                Based on the Internet Junkbuster originally written
21
 *                Based on the Internet Junkbuster originally written
19
 *                by and Copyright (C) 1997 Anonymous Coders and
22
 *                by and Copyright (C) 1997 Anonymous Coders and
20
 *                Junkbusters Corporation.  http://www.junkbusters.com
23
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 471-476 Link Here
471
#include <ctype.h>
474
#include <ctype.h>
472
#include <string.h>
475
#include <string.h>
473
#include <assert.h>
476
#include <assert.h>
477
#ifdef INET6
478
#include <netdb.h>
479
#endif
474
480
475
#ifndef _WIN32
481
#ifndef _WIN32
476
#ifndef __OS2__
482
#ifndef __OS2__
Lines 505-521 Link Here
505
511
506
const char filters_h_rcs[] = FILTERS_H_VERSION;
512
const char filters_h_rcs[] = FILTERS_H_VERSION;
507
513
508
/* Fix a problem with Solaris.  There should be no effect on other
514
#ifdef FEATURE_ACL
509
 * platforms.
515
/*********************************************************************
510
 * Solaris's isspace() is a macro which uses it's argument directly
516
 *
511
 * as an array index.  Therefore we need to make sure that high-bit
517
 * Function    :  addr_equal_under_mask
512
 * characters generate +ve values, and ideally we also want to make
518
 *
513
 * the argument match the declared parameter type of "int".
519
 * Description :  Are these addresses equal modulo this mask?
514
 */
520
 *                Assumes the second argument is already in
515
#define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
521
 *                mask-normal form
522
 *
523
 * Parameters  :
524
 *          0  :  addr1 = First address to compare
525
 *          1  :  addr2 = Second address to compare
526
 *                        MUST be in mask-normal form
527
 *          2  :  mask = for IPv4 addresses, a bitmask
528
 *                       for IPv6 addresses, a prefixlen in bits
529
 *
530
 * Returns     : 0 = FALSE (not equal) and non-zero = TRUE (equal)
531
 *
532
 *********************************************************************/
533
static
534
int
535
addr_equal_under_mask(struct sockaddr_storage *addr1, struct sockaddr_storage *addr2, unsigned long  mask)
536
{
537
   if (!mask)
538
       return 1;
516
539
540
   /* only identical families can be compared */
541
   /* TODO: Should we code the special case of "IPv4 addresses as IPv6 addresses"? */
542
   if (addr1->ss_family != addr2-> ss_family)
543
     {
544
       /*fprintf(stderr, "equal_under_mask: diff sa_family: %d %d\n",
545
         sa1->sa_family, sa2-> sa_family); */
546
       return 0;
547
     }
548
  
549
   switch (addr1->ss_family)
550
      {
551
      case AF_INET:
552
         {
553
            /* IPv4 - mask is a bitmask */
554
            struct sockaddr_in *sin1 = (struct sockaddr_in *)addr1;
555
            struct sockaddr_in *sin2 = (struct sockaddr_in *)addr2;
556
            
557
            /*fprintf(stderr, "AF_INET: %08x %08x %08x\n", 
558
              sin1->sin_addr.s_addr,
559
              sin2->sin_addr.s_addr,
560
              mask); */
561
            return (sin1->sin_addr.s_addr & mask) == sin2->sin_addr.s_addr;
562
         }
563
         break;
564
#ifdef INET6
565
      case AF_INET6:
566
         {
567
            /* IPv6 - mask is a prefixlength in bits. */
568
            struct sockaddr_in6 *sin1 = (struct sockaddr_in6 *)addr1;
569
            struct sockaddr_in6 *sin2 = (struct sockaddr_in6 *)addr2;
570
            char bitmask;
571
            char *a1, *a2;
572
            const int maskbytes = mask / 8;
573
            static char m[] = { 0x00, 0x80, 0xC0, 0xE0,
574
                                0xF0, 0xF8, 0xFC, 0xFE };
575
/*             { */
576
/*                int i; */
577
/*                fprintf(stderr, "PF_INET6: "); */
578
/*                for (i = 0; i < 16; i++) { */
579
/*                   fprintf(stderr, "%02x ", sin1->sin6_addr.s6_addr[i]); */
580
/*                } */
581
/*                fprintf(stderr, "   "); */
582
/*                for (i = 0; i < 16; i++) { */
583
/*                   fprintf(stderr, "%02x ", sin2->sin6_addr.s6_addr[i]); */
584
/*                } */
585
/*                fprintf(stderr, "mask %d scopeids %x %x\n", mask, sin1->sin6_scope_id, sin2->sin6_scope_id); */
586
/*             } */
587
            /* should we compare scope ids and such too? */
588
            /*
589
             * LEM: I see no reason for this comparison
590
             * Quite the contrary: A client coming to us with
591
             * a small-scope address should be able to a bigger-scope
592
             * address.
593
             */
594
/*             if (sin1->sin6_scope_id != sin2->sin6_scope_id) */
595
/*                return 0; */
596
597
            if (mask > 128ul)
598
            {
599
               log_error(LOG_LEVEL_ERROR, "%s%d", "Tried to compare IPv6 addresses with invalid prefixlen: ", mask);
600
               return 0;
601
            }
602
603
            a1 = sin1->sin6_addr.s6_addr;
604
            a2 = sin2->sin6_addr.s6_addr;
605
606
            if (memcmp(a1, a2, maskbytes) != 0)
607
               return 0;
608
609
            mask %= 8;
610
            /* This special case is necessary for when mask==128
611
               else, we would go over the array size in a1/a2
612
             */
613
            if (mask==0)
614
               return 1;
615
616
            bitmask = m[mask];
617
618
            return (a1[maskbytes] & bitmask) == a2[maskbytes];
619
      }
620
         break;
621
#endif
622
      default:
623
         return 0;
624
      }
625
}
517
626
518
#ifdef FEATURE_ACL
519
/*********************************************************************
627
/*********************************************************************
520
 *
628
 *
521
 * Function    :  block_acl
629
 * Function    :  block_acl
Lines 545-551 Link Here
545
   /* search the list */
653
   /* search the list */
546
   while (acl != NULL)
654
   while (acl != NULL)
547
   {
655
   {
548
      if ((csp->ip_addr_long & acl->src->mask) == acl->src->addr)
656
      if (addr_equal_under_mask(&csp->ip_addr_addr, &acl->src->addr, acl->src->mask))
549
      {
657
      {
550
         if (dst == NULL)
658
         if (dst == NULL)
551
         {
659
         {
Lines 555-562 Link Here
555
               return(0);
663
               return(0);
556
            }
664
            }
557
         }
665
         }
558
         else if ( ((dst->addr & acl->dst->mask) == acl->dst->addr)
666
         else if ( addr_equal_under_mask(&dst->addr, &acl->dst->addr, acl->dst->mask)
559
           && ((dst->port == acl->dst->port) || (acl->dst->port == 0)))
667
                   && ((dst->port == acl->dst->port) || (acl->dst->port == 0)))
560
         {
668
         {
561
            if (acl->action == ACL_PERMIT)
669
            if (acl->action == ACL_PERMIT)
562
            {
670
            {
Lines 575-655 Link Here
575
683
576
}
684
}
577
685
578
579
/*********************************************************************
686
/*********************************************************************
580
 *
687
 *
581
 * Function    :  acl_addr
688
 * Function    :  fill_acl_addr_mask
582
 *
689
 *
583
 * Description :  Called from `load_config' to parse an ACL address.
690
 * Description :  Fill in the mask-related members of a
691
 *                struct access_control_addr
584
 *
692
 *
585
 * Parameters  :
693
 * Parameters  :
586
 *          1  :  aspec = String specifying ACL address.
694
 *          0  :  aca = struct access_control_addr to fill in.
587
 *          2  :  aca = struct access_control_addr to fill in.
695
 *          1  :  masklength = mask length.
588
 *
696
 *
589
 * Returns     :  0 => Ok, everything else is an error.
697
 * Returns     :  nothing
590
 *
698
 *
591
 *********************************************************************/
699
 *********************************************************************/
592
int acl_addr(char *aspec, struct access_control_addr *aca)
700
void fill_acl_addr_mask(struct access_control_addr *aca, int masklength)
593
{
701
{
594
   int i, masklength, port;
702
   int pf;
595
   char *p;
596
703
597
   masklength = 32;
704
   pf = aca->addr.ss_family;
598
   port       =  0;
599
705
600
   if ((p = strchr(aspec, '/')) != NULL)
706
   switch (pf)
601
   {
707
   {
602
      *p++ = '\0';
708
   case PF_INET:
603
709
      /* build the netmask */
604
      if (ijb_isdigit(*p) == 0)
710
      if (masklength == -1)
711
         masklength = 32;
712
      aca->mask = 0;
713
      for(pf=1; pf <= masklength ; ++pf)
605
      {
714
      {
606
         return(-1);
715
         aca->mask |= (1 << (32 - pf));
607
      }
716
      }
608
      masklength = atoi(p);
717
      aca->mask = htonl(aca->mask);
609
   }
718
      
719
      /* now mask off the host portion of the ip address
720
       * (i.e. save on the network portion of the address).
721
       */
722
      ((struct sockaddr_in*) &aca->addr)->sin_addr.s_addr &= aca->mask;
723
      aca->port = ((struct sockaddr_in*) &aca->addr)->sin_port;
724
      break;
725
#ifdef INET6
726
   case PF_INET6:
727
      {
728
         static char m[] = { 0x00, 0x80, 0xC0, 0xE0,
729
                             0xF0, 0xF8, 0xFC, 0xFE };
730
         int i;
731
         struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&aca->addr;
610
732
611
   if ((masklength < 0) || (masklength > 32))
733
         aca->mask = (masklength == -1) ? masklength : 128 ;
612
   {
734
         /* now mask off the host portion of the ip address
613
      return(-1);
735
          * (i.e. save on the network portion of the address).
736
          */
737
         i = aca->mask / 8;
738
         if (i < 16)
739
         {
740
            sa6->sin6_addr.s6_addr[i] &= m[aca->mask % 8];
741
            /* The following loop is not strictly necessary,
742
               because of the way addr_equal_under_mask is
743
               written. Better safe than sorry, though:
744
               New code might make the full mask-normal
745
               form assumption.
746
             */
747
            for(++i; i < 16 ; ++i)
748
               sa6->sin6_addr.s6_addr[i] = 0;
749
         }
750
         aca -> port = sa6->sin6_port;
751
         break;
752
      }
753
#endif
754
   default:
755
      /* FATAL because access_control_addr's are created only with adresses
756
         deemed 'acceptable' by the addr_list stuff, thus currently IPv4 and
757
         IPv6.
758
       */
759
      log_error(LOG_LEVEL_FATAL,"%s%d","Unknown address family in ACL address: ",pf);
614
   }
760
   }
761
}
615
762
616
   if ((p = strchr(aspec, ':')) != NULL)
763
/*********************************************************************
617
   {
764
 *
618
      *p++ = '\0';
765
 * Function    :  acl_addrs
766
 *
767
 * Description :  Parse an ACL address (adress + mask prefix)
768
 *                Resolve the parsed address
769
 *                Describe errors in *proxy_args.
770
 *
771
 * Parameters  :
772
 *          0  :  aspec = the string containing the ACL address/mask
773
 *          1  :  masklength = pointer used to return the mask
774
 *          2  :  proxy_args = Pointer to string to append description of errors to.
775
 *          3  :  type = type of ACL adress (source / destination).
776
 *                       Used for error reporting.
777
 *
778
 * Returns     :  the list of adresses the ACL address resolves to
779
 *
780
 *********************************************************************/
781
static addr_list *acl_addrs(char *aspec, int *masklength, char**proxy_args, const char *type)
782
{
783
   char *host;
784
   char *port;
785
   int pf;
619
786
620
      if (ijb_isdigit(*p) == 0)
787
   pf = -1;
621
      {
788
   if (parse_pf_ip_netmask(aspec, &host, &port, &pf, masklength) != 0)
622
         return(-1);
789
   {
623
      }
790
      log_error(LOG_LEVEL_ERROR, "Invalid %s IP for (deny|permit)-access "
624
      port = atoi(p);
791
                "directive in configuration file: \"%s\"", type, aspec);
792
      string_append(proxy_args,"<br>\nWARNING: Invalid ");
793
      string_append(proxy_args, type);
794
      string_append(proxy_args," IP for (deny|permit)-access directive"
795
                    " in configuration file: \"");
796
      string_append(proxy_args, aspec);
797
      string_append(proxy_args,"\"<br><br>\n");
798
      return NULL;
625
   }
799
   }
626
800
627
   aca->port = port;
801
   return resolve_hostname_to_ip(host, port, pf);
802
}
628
803
629
   aca->addr = ntohl(resolve_hostname_to_ip(aspec));
804
/*********************************************************************
805
 *
806
 * Function    :  add_one_to_acl_list
807
 *
808
 * Description :  Add one entry to an access_control_list.
809
 *
810
 * Parameters  :
811
 *          0  :  l = the list to add to
812
 *          1  :  action = ACL_DENY or ACL_PERMIT
813
 *          2  :  src_addrs = the head of this list will be used as source
814
 *                            in the ACL entry.
815
 *          3  :  dst_addrs = the head of this list will be used as destination
816
 *                            in the ACL entry.
817
 *                            NULL for none
818
 *          4  :  src_masklength = mask length for the source
819
 *          5  :  src_masklength = mask length for the destination
820
 *
821
 * Returns     :  the new list
822
 *
823
 *********************************************************************/
824
struct access_control_list *add_one_to_acl_list(struct access_control_list *l, short action,
825
                                                addr_list *src_addrs, addr_list *dst_addrs,
826
                                                int src_masklength, int dst_masklength)
827
{
828
   struct access_control_list *cur_acl;
829
   /* allocate a new node */
830
   cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
630
831
631
   if (aca->addr == INADDR_NONE)
832
   if (cur_acl == NULL)
632
   {
833
   {
633
      return(-1);
834
      log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
835
      /* Never get here - LOG_LEVEL_FATAL causes program exit */
836
      return l;
634
   }
837
   }
635
838
636
   /* build the netmask */
839
   cur_acl->action = action;
637
   aca->mask = 0;
840
638
   for (i=1; i <= masklength ; i++)
841
   cpy_head_addr_list(src_addrs, &cur_acl->src->addr, &cur_acl->src->addrlen);
842
   fill_acl_addr_mask(cur_acl->src, src_masklength);
843
   if (dst_addrs != NULL)
639
   {
844
   {
640
      aca->mask |= (1 << (32 - i));
845
      cpy_head_addr_list(dst_addrs, &cur_acl->dst->addr, &cur_acl->dst->addrlen);
846
      fill_acl_addr_mask(cur_acl->src, src_masklength);
641
   }
847
   }
642
848
643
   /* now mask off the host portion of the ip address
849
   /*
644
    * (i.e. save on the network portion of the address).
850
    * Add it to the list.  Note we reverse the list to get the
851
    * behaviour the user expects.  With both the ACL and
852
    * actions file, the last match wins.  However, the internal
853
    * implementations are different:  The actions file is stored
854
    * in the same order as the file, and scanned completely.
855
    * With the ACL, we reverse the order as we load it, then
856
    * when we scan it we stop as soon as we get a match.
645
    */
857
    */
646
   aca->addr = aca->addr & aca->mask;
858
   cur_acl->next  = l;
647
859
648
   return(0);
860
   return cur_acl;
861
}
862
863
/*********************************************************************
864
 *
865
 * Function    :  add_to_acl_list
866
 *
867
 * Description :  Add entries to an access_control_list.
868
 *                Describe errors in *proxy_args.
869
 *
870
 * Parameters  :
871
 *          0  :  l = the list to add to
872
 *          1  :  action = ACL_DENY or ACL_PERMIT
873
 *          2  :  src_spec = String giving the source of the acl entry
874
 *          3  :  dst_spec = String giving the destination of the acl entry,
875
 *                           or NULL
876
 *          4  :  proxy_args = Pointer to string to append description of errors to.
877
 *
878
 * Returns     :  the new list
879
 *
880
 *********************************************************************/
881
struct access_control_list *add_to_acl_list(struct access_control_list *l,
882
                                            short action,
883
                                            char *src_spec,
884
                                            char *dst_spec,
885
                                            char **proxy_args)
886
{
887
   int src_masklength, dst_masklength;
888
   addr_list *src_addrs, *dst_addrs;
889
   addr_list *src_addrs_remaining, *dst_addrs_remaining;
890
891
   src_addrs = acl_addrs(src_spec, &src_masklength, proxy_args, "source");
892
   if (is_nil_addr_list(src_addrs))
893
   {
894
      log_error(LOG_LEVEL_ERROR, "Source of ACL resolves to no address",dst_spec);
895
      return l;
896
   }
897
   if (dst_spec != NULL)
898
   {
899
      dst_addrs = acl_addrs(dst_spec, &dst_masklength, proxy_args, "destination");
900
      if (is_nil_addr_list(dst_addrs))
901
      {
902
         log_error(LOG_LEVEL_ERROR, "Destination of ACL resolves to no address",dst_spec);
903
         destroy_addr_list(src_addrs);
904
         return l;
905
      }
906
   }
907
   else
908
      dst_addrs = NULL;
909
910
   for(src_addrs_remaining = src_addrs;
911
       is_nil_addr_list(src_addrs);
912
       src_addrs_remaining=tail_addr_list(src_addrs_remaining))
913
   {
914
      if (dst_addrs == NULL)
915
         l = add_one_to_acl_list(l, action, src_addrs_remaining, NULL, src_masklength,0);
916
      else for(dst_addrs_remaining = dst_addrs;
917
               is_nil_addr_list(dst_addrs);
918
               dst_addrs_remaining=tail_addr_list(dst_addrs_remaining))
919
         l = add_one_to_acl_list(l, action, src_addrs_remaining, dst_addrs_remaining,
920
                                 src_masklength, dst_masklength);
921
   }
922
   destroy_addr_list(src_addrs);
923
   destroy_addr_list(dst_addrs);
649
924
925
   return l;
650
}
926
}
651
#endif /* def FEATURE_ACL */
652
927
928
#endif /* def FEATURE_ACL */
653
929
654
/*********************************************************************
930
/*********************************************************************
655
 *
931
 *
(-)privoxy~/filters.h (-1 / +8 lines)
Lines 15-20 Link Here
15
 * Copyright   :  Written by and Copyright (C) 2001, 2004 the SourceForge
15
 * Copyright   :  Written by and Copyright (C) 2001, 2004 the SourceForge
16
 *                Privoxy team. http://www.privoxy.org/
16
 *                Privoxy team. http://www.privoxy.org/
17
 *
17
 *
18
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
19
 *                for IPv6 support on 8 December 2002, 24 January 2003.
20
 *
18
 *                Based on the Internet Junkbuster originally written
21
 *                Based on the Internet Junkbuster originally written
19
 *                by and Copyright (C) 1997 Anonymous Coders and 
22
 *                by and Copyright (C) 1997 Anonymous Coders and 
20
 *                Junkbusters Corporation.  http://www.junkbusters.com
23
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 234-240 Link Here
234
 */
237
 */
235
#ifdef FEATURE_ACL
238
#ifdef FEATURE_ACL
236
extern int block_acl(struct access_control_addr *dst, struct client_state *csp);
239
extern int block_acl(struct access_control_addr *dst, struct client_state *csp);
237
extern int acl_addr(char *aspec, struct access_control_addr *aca);
240
extern struct access_control_list *add_to_acl_list(struct access_control_list *l,
241
                                                   short action,
242
                                                   char *src_spec,
243
                                                   char *dst_spec,
244
                                                   char **proxy_args);
238
#endif /* def FEATURE_ACL */
245
#endif /* def FEATURE_ACL */
239
extern int match_portlist(const char *portlist, int port);
246
extern int match_portlist(const char *portlist, int port);
240
247
(-)privoxy~/gateway.c (-66 / +106 lines)
Lines 10-15 Link Here
10
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
10
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11
 *                Privoxy team. http://www.privoxy.org/
11
 *                Privoxy team. http://www.privoxy.org/
12
 *
12
 *
13
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
14
 *                for IPv6 support on 8 December 2002, 24 January 2003.
15
 *
13
 *                Based on the Internet Junkbuster originally written
16
 *                Based on the Internet Junkbuster originally written
14
 *                by and Copyright (C) 1997 Anonymous Coders and
17
 *                by and Copyright (C) 1997 Anonymous Coders and
15
 *                Junkbusters Corporation.  http://www.junkbusters.com
18
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 203-214 Link Here
203
 * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
206
 * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket file descriptor.
204
 *
207
 *
205
 *********************************************************************/
208
 *********************************************************************/
206
jb_socket forwarded_connect(const struct forward_spec * fwd,
209
jb_socket forwarded_connect(const struct forward_spec *fwd,
207
                            struct http_request *http,
210
                            struct http_request *http,
208
                            struct client_state *csp)
211
                            struct client_state *csp)
209
{
212
{
210
   const char * dest_host;
213
   const char * dest_host;
211
   int dest_port;
214
   const char * dest_port_str;
215
   unsigned long dest_port;
216
   int dest_pf;
212
217
213
   /* Figure out if we need to connect to the web server or a HTTP proxy. */
218
   /* Figure out if we need to connect to the web server or a HTTP proxy. */
214
   if (fwd->forward_host)
219
   if (fwd->forward_host)
Lines 216-234 Link Here
216
      /* HTTP proxy */
221
      /* HTTP proxy */
217
      dest_host = fwd->forward_host;
222
      dest_host = fwd->forward_host;
218
      dest_port = fwd->forward_port;
223
      dest_port = fwd->forward_port;
224
      dest_port_str = fwd->forward_port_str;
225
      dest_pf = fwd->forward_family;
219
   }
226
   }
220
   else
227
   else
221
   {
228
   {
222
      /* Web server */
229
      /* Web server */
223
      dest_host = http->host;
230
      dest_host = http->host;
224
      dest_port = http->port;
231
      dest_port = http->port;
232
      dest_port_str = http->port_str;
233
      dest_pf = PF_UNSPEC;
225
   }
234
   }
226
235
227
   /* Connect, maybe using a SOCKS proxy */
236
   /* Connect, maybe using a SOCKS proxy */
228
   switch (fwd->type)
237
   switch (fwd->type)
229
   {
238
   {
230
      case SOCKS_NONE:
239
      case SOCKS_NONE:
231
         return (connect_to(dest_host, dest_port, csp));
240
         return (connect_to(dest_host, dest_port_str, dest_port, dest_pf, csp));
232
241
233
      case SOCKS_4:
242
      case SOCKS_4:
234
      case SOCKS_4A:
243
      case SOCKS_4A:
Lines 262-335 Link Here
262
 * Returns     :  JB_INVALID_SOCKET => failure, else a socket file descriptor.
271
 * Returns     :  JB_INVALID_SOCKET => failure, else a socket file descriptor.
263
 *
272
 *
264
 *********************************************************************/
273
 *********************************************************************/
265
static jb_socket socks4_connect(const struct forward_spec * fwd,
274
static jb_socket socks4_connect_one_ip(const struct forward_spec * fwd,
266
                                const char * target_host,
275
                                       unsigned long web_server_addr,
267
                                int target_port,
276
                                       int target_port,
268
                                struct client_state *csp)
277
                                       struct client_state *csp,
278
                                       size_t csiz,
279
                                       char *cbuf)
269
{
280
{
270
   int web_server_addr;
271
   char cbuf[BUFFER_SIZE];
272
   char sbuf[BUFFER_SIZE];
281
   char sbuf[BUFFER_SIZE];
273
   struct socks_op    *c = (struct socks_op    *)cbuf;
274
   struct socks_reply *s = (struct socks_reply *)sbuf;
282
   struct socks_reply *s = (struct socks_reply *)sbuf;
275
   size_t n;
283
   struct socks_reply *c = (struct socks_reply *)cbuf;
276
   size_t csiz;
277
   jb_socket sfd;
284
   jb_socket sfd;
278
   int err = 0;
279
   char *errstr;
285
   char *errstr;
280
286
281
   if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0'))
282
   {
283
      log_error(LOG_LEVEL_CONNECT, "socks4_connect: NULL gateway host specified");
284
      err = 1;
285
   }
286
287
   if (fwd->gateway_port <= 0)
288
   {
289
      log_error(LOG_LEVEL_CONNECT, "socks4_connect: invalid gateway port specified");
290
      err = 1;
291
   }
292
293
   if (err)
294
   {
295
      errno = EINVAL;
296
      return(JB_INVALID_SOCKET);
297
   }
298
299
   /* build a socks request for connection to the web server */
300
301
   strcpy((char *)&(c->userid), socks_userid);
302
303
   csiz = sizeof(*c) + sizeof(socks_userid) - 1;
304
305
   switch (fwd->type)
306
   {
307
      case SOCKS_4:
308
         web_server_addr = htonl(resolve_hostname_to_ip(target_host));
309
         if (web_server_addr == INADDR_NONE)
310
         {
311
            log_error(LOG_LEVEL_CONNECT, "socks4_connect: could not resolve target host %s", target_host);
312
            return(JB_INVALID_SOCKET);
313
         }
314
         break;
315
      case SOCKS_4A:
316
         web_server_addr = 0x00000001;
317
         n = csiz + strlen(target_host) + 1;
318
         if (n > sizeof(cbuf))
319
         {
320
            errno = EINVAL;
321
            return(JB_INVALID_SOCKET);
322
         }
323
         strcpy(cbuf + csiz, target_host);
324
         csiz = n;
325
         break;
326
      default:
327
         /* Should never get here */
328
         log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
329
         errno = EINVAL;
330
         return(JB_INVALID_SOCKET);
331
   }
332
333
   c->vn          = 4;
287
   c->vn          = 4;
334
   c->cd          = 1;
288
   c->cd          = 1;
335
   c->dstport[0]  = (target_port       >> 8  ) & 0xff;
289
   c->dstport[0]  = (target_port       >> 8  ) & 0xff;
Lines 340-346 Link Here
340
   c->dstip[3]    = (web_server_addr         ) & 0xff;
294
   c->dstip[3]    = (web_server_addr         ) & 0xff;
341
295
342
   /* pass the request to the socks server */
296
   /* pass the request to the socks server */
343
   sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp);
297
   sfd = connect_to(fwd->gateway_host, fwd->gateway_port_str, fwd->gateway_port, PF_INET ,csp);
344
298
345
   if (sfd == JB_INVALID_SOCKET)
299
   if (sfd == JB_INVALID_SOCKET)
346
   {
300
   {
Lines 395-400 Link Here
395
349
396
}
350
}
397
351
352
static jb_socket socks4_connect(const struct forward_spec * fwd,
353
                                const char * target_host,
354
                                int target_port,
355
                                struct client_state *csp)
356
{
357
   char cbuf[BUFFER_SIZE];
358
   struct socks_op    *c = (struct socks_op    *)cbuf;
359
   size_t csiz;
360
   int err = 0;
361
362
   /**
363
    * SOCKS4 is IPv4-specific. At least I think so.
364
    */
365
   if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0'))
366
   {
367
      log_error(LOG_LEVEL_CONNECT, "socks4_connect: NULL gateway host specified");
368
      err = 1;
369
   }
370
371
   if (fwd->gateway_port <= 0)
372
   {
373
      log_error(LOG_LEVEL_CONNECT, "socks4_connect: invalid gateway port specified");
374
      err = 1;
375
   }
376
377
   if (err)
378
   {
379
      errno = EINVAL;
380
      return(JB_INVALID_SOCKET);
381
   }
382
383
   /* build a socks request for connection to the web server */
384
385
   strcpy((char *)&(c->userid), socks_userid);
386
387
   csiz = sizeof(*c) + sizeof(socks_userid) - 1;
388
389
   switch (fwd->type)
390
   {
391
      case SOCKS_4:
392
      {
393
         addr_list *web_server_addrs = resolve_hostname_to_ip(target_host,NULL,PF_INET);
394
         jb_socket return_value = JB_INVALID_SOCKET;
395
         if (is_nil_addr_list(web_server_addrs))
396
         {
397
            log_error(LOG_LEVEL_CONNECT, "socks4_connect: could not resolve target host %s", target_host);
398
         }
399
         else
400
         {
401
            addr_list *addrs_to_try;
402
            
403
            for(addrs_to_try = web_server_addrs;
404
                !is_nil_addr_list(addrs_to_try);
405
                addrs_to_try = tail_addr_list(addrs_to_try))
406
            {
407
               const unsigned long web_server_addr = ((struct sockaddr_in*) head_addr_list(addrs_to_try))->sin_addr.s_addr;
408
               return_value=socks4_connect_one_ip(fwd, web_server_addr, target_port, csp, csiz, cbuf);
409
               if(return_value != JB_INVALID_SOCKET)
410
                  break;
411
            }
412
         }
413
         destroy_addr_list(web_server_addrs);
414
         return return_value;
415
         break;
416
      }
417
      case SOCKS_4A:
418
      {
419
         size_t n;
420
         n = csiz + strlen(target_host) + 1;
421
         if (n > sizeof(cbuf))
422
         {
423
            errno = EINVAL;
424
            return(JB_INVALID_SOCKET);
425
         }
426
         strcpy(cbuf + csiz, target_host);
427
         csiz = n;
428
         return socks4_connect_one_ip(fwd, 0x00000001, target_port, csp, csiz, cbuf);
429
         break;
430
      }
431
      default:
432
         /* Should never get here */
433
         log_error(LOG_LEVEL_FATAL, "SOCKS4 impossible internal error - bad SOCKS type.");
434
         errno = EINVAL;
435
         return(JB_INVALID_SOCKET);
436
   }
437
}
398
438
399
/*
439
/*
400
  Local Variables:
440
  Local Variables:
(-)privoxy~/jb_socket_set.c (+174 lines)
Line 0 Link Here
1
const char jb_socket_set_rcs[] = "$Id: $";
2
/*********************************************************************
3
 *
4
 * File        :  $Source: $
5
 *
6
 * Purpose     :  Declares functions to handle sets of sockets
7
 *
8
 * Copyright   :  Written by and Copyright (C) 2002 Lionel Elie Mamane
9
 *                <lionel@mamane.lu>
10
 *
11
 *                This program is free software; you can redistribute it
12
 *                and/or modify it under the terms of the GNU General
13
 *                Public License as published by the Free Software
14
 *                Foundation; either version 2 of the License, or (at
15
 *                your option) any later version.
16
 *
17
 *                This program is distributed in the hope that it will
18
 *                be useful, but WITHOUT ANY WARRANTY; without even the
19
 *                implied warranty of MERCHANTABILITY or FITNESS FOR A
20
 *                PARTICULAR PURPOSE.  See the GNU General Public
21
 *                License for more details.
22
 *
23
 *                The GNU General Public License should be included with
24
 *                this file.  If not, you can view it at
25
 *                http://www.gnu.org/copyleft/gpl.html
26
 *                or write to the Free Software Foundation, Inc., 59
27
 *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28
 *
29
 * Revisions   :
30
 *    $Log: jb_socket_set.c,v $
31
 *
32
 *********************************************************************/
33
34
#include "jb_socket_set.h"
35
#include <sys/time.h>
36
#include <sys/types.h>
37
#include <unistd.h>
38
#include "project.h"
39
40
/*********************************************************************
41
 *
42
 * Function    :  jb_socket_set_add
43
 *
44
 * Description :  Add a socket to the set
45
 *
46
 * Parameters  :
47
 *          0  :  l = the set to add to
48
 *          1  :  the elemen to add to the set
49
 *
50
 * Returns     :  0 on success
51
 *                non-0 on failure
52
 *
53
 *********************************************************************/
54
55
int jb_socket_set_add(jb_socket_set *l, jb_socket e)
56
{
57
   if (l->data==NULL)
58
   {
59
      l->size=2;
60
      l->data=malloc(l->size * sizeof(jb_socket));
61
      if (l->data==NULL)
62
      {
63
         l->size = 0;
64
         return -1;
65
      }
66
      l->occupied=0;
67
   }
68
   l->data[(l->occupied)++] = e;
69
   if (l->occupied == l->size)
70
   {
71
      jb_socket *new_data;
72
      l->size *= 2;
73
      new_data = realloc(l->data,l->size * sizeof(jb_socket));
74
      if (new_data == NULL)
75
      {
76
         /* Not enough memory to continue. Cancel changes. */
77
         l->data[--(l->occupied)] = JB_INVALID_SOCKET;
78
         l->size /= 2;
79
         return -1;
80
      }
81
      l->data = new_data;
82
   }
83
   l->data[l->occupied] = JB_INVALID_SOCKET;
84
   return 0;
85
}
86
87
/*********************************************************************
88
 *
89
 * Function    :  destroy_jb_socket_set
90
 *
91
 * Description :  Unallocate memory allocated to a socket set
92
 *
93
 * Parameters  :
94
 *          0  :  l = the set to unallocate
95
 *
96
 * Returns     :  nothing
97
 *
98
 *********************************************************************/
99
void destroy_jb_socket_set(jb_socket_set *l)
100
{
101
   free(l->data);
102
   init_jb_socket_set(l);
103
}
104
/*********************************************************************
105
 *
106
 * Function    :  is_empty_jb_socket_set
107
 *
108
 * Description :  Test wheter a set is empty
109
 *
110
 * Parameters  :
111
 *          0  :  l = the set to test
112
 *
113
 * Returns     :  0             = false if set has a head,
114
 *                anything else = true if set is nil
115
 *
116
 *********************************************************************/
117
int is_nil_jb_socket_set(jb_socket_set *l)
118
{
119
   return (l->occupied == 0);
120
}
121
122
/*********************************************************************
123
 *
124
 * Function    :  init_jb_socket_set
125
 *
126
 * Description :  Init a set to empty
127
 *
128
 * Parameters  :
129
 *          0  :  l = the set to init
130
 *
131
 *********************************************************************/
132
void init_jb_socket_set(jb_socket_set *l)
133
{
134
   l->data=NULL;
135
   l->size=0;
136
   l->occupied=0;
137
}
138
139
/*********************************************************************
140
 *
141
 * Function    :  jb_socket_set_iteration_begin
142
 *
143
 * Description :  Return an iterator on the set
144
 *
145
 * Parameters  :
146
 *          0  :  l = the set
147
 *
148
 *********************************************************************/
149
jb_socket_set_iterate_state jb_socket_set_iteration_begin(jb_socket_set *l)
150
{
151
   return l->data;
152
}
153
154
/*********************************************************************
155
 *
156
 * Function    :  jb_socket_set_iteration_next
157
 *
158
 * Description :  Return value pointed to by iterator and step
159
 *                iterator to next position
160
 *
161
 * Parameters  :
162
 *          0  :  s = the iterator
163
 *
164
 *********************************************************************/
165
jb_socket jb_socket_set_iteration_next(jb_socket_set_iterate_state*s)
166
{
167
   return(*((*s)++));
168
}
169
170
/*
171
  Local Variables:
172
  tab-width: 3
173
  end:
174
*/
(-)privoxy~/jb_socket_set.h (+71 lines)
Line 0 Link Here
1
#ifndef JB_SOCKET_SET_H_INCLUDED
2
#define JB_SOCKET_SET_H_INCLUDED
3
#define JB_SOCKET_SET_H_VERSION "$Id: $"
4
/*********************************************************************
5
 *
6
 * File        :  $Source: $
7
 *
8
 * Purpose     :  Declares functions to handle sets of sockets
9
 *
10
 * Copyright   :  Written by and Copyright (C) 2002 Lionel Elie Mamane
11
 *                <lionel@mamane.lu>
12
 *
13
 *                This program is free software; you can redistribute it
14
 *                and/or modify it under the terms of the GNU General
15
 *                Public License as published by the Free Software
16
 *                Foundation; either version 2 of the License, or (at
17
 *                your option) any later version.
18
 *
19
 *                This program is distributed in the hope that it will
20
 *                be useful, but WITHOUT ANY WARRANTY; without even the
21
 *                implied warranty of MERCHANTABILITY or FITNESS FOR A
22
 *                PARTICULAR PURPOSE.  See the GNU General Public
23
 *                License for more details.
24
 *
25
 *                The GNU General Public License should be included with
26
 *                this file.  If not, you can view it at
27
 *                http://www.gnu.org/copyleft/gpl.html
28
 *                or write to the Free Software Foundation, Inc., 59
29
 *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
30
 *
31
 * Revisions   :
32
 *    $Log: jb_socket_set.h,v $
33
 *
34
 *********************************************************************/
35
#include <sys/time.h>
36
#include <sys/types.h>
37
#include <unistd.h>
38
#include "project.h"
39
40
struct jb_socket_set_struct
41
{
42
   unsigned int size; /* size allocated*/
43
   unsigned int occupied; /* size occupied - 1 == index of final JB_INVALID_SOCKET
44
                             == number of sockets in the set */
45
   jb_socket *data; /* Array containing the sockets, JB_INVALID_SOCKET-terminated */
46
};
47
48
typedef struct jb_socket_set_struct jb_socket_set;
49
typedef const jb_socket* jb_socket_set_iterate_state;
50
51
void init_jb_socket_set(jb_socket_set*);
52
53
jb_socket_set_iterate_state jb_socket_set_iteration_begin(jb_socket_set *);
54
jb_socket jb_socket_set_iteration_next(jb_socket_set_iterate_state*);
55
56
int jb_socket_set_add(jb_socket_set*, jb_socket);
57
58
void destroy_jb_socket_set(jb_socket_set *l);
59
int is_empty_jb_socket_set(jb_socket_set *l);
60
61
#define freez_jb_socket_set(X)  { if(X) { destroy_jb_socket_set(X); X = NULL ; } }
62
63
int jb_select(jb_socket_set *readfds, jb_socket_set *writefds, jb_socket_set *exceptfds, struct timeval *timeout);
64
65
#endif /* ndef JB_SOCKET_SET_H_INCLUDED */
66
67
/*
68
  Local Variables:
69
  tab-width: 3
70
  end:
71
*/
(-)privoxy~/jbsockets.c (-264 / +333 lines)
Lines 11-16 Link Here
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
12
 *                Privoxy team. http://www.privoxy.org/
12
 *                Privoxy team. http://www.privoxy.org/
13
 *
13
 *
14
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
15
 *                for IPv6 support on 8-9 December 2002, 24 January 2003,
16
 *                13 February 2003.
17
 *
14
 *                Based on the Internet Junkbuster originally written
18
 *                Based on the Internet Junkbuster originally written
15
 *                by and Copyright (C) 1997 Anonymous Coders and 
19
 *                by and Copyright (C) 1997 Anonymous Coders and 
16
 *                Junkbusters Corporation.  http://www.junkbusters.com
20
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 275-280 Link Here
275
#include "jbsockets.h"
279
#include "jbsockets.h"
276
#include "filters.h"
280
#include "filters.h"
277
#include "errlog.h"
281
#include "errlog.h"
282
#include "addrlist.h"
278
283
279
const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
284
const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
280
285
Lines 287-427 Link Here
287
 *                that this is allowed according to ACL.
292
 *                that this is allowed according to ACL.
288
 *
293
 *
289
 * Parameters  :
294
 * Parameters  :
290
 *          1  :  host = hostname to connect to
295
 *          0  :  host = hostname to connect to
291
 *          2  :  portnum = port to connent on
296
 *          1  :  port = port to connect on, as string
297
 *          2  :  portnum = port to connect on, as integer
292
 *          3  :  csp = Current client state (buffers, headers, etc...)
298
 *          3  :  csp = Current client state (buffers, headers, etc...)
293
 *                      Not modified, only used for source IP and ACL.
294
 *
299
 *
295
 * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket
300
 * Returns     :  JB_INVALID_SOCKET => failure, else it is the socket
296
 *                file descriptor.
301
 *                file descriptor.
297
 *
302
 *
298
 *********************************************************************/
303
 *********************************************************************/
299
jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
304
jb_socket connect_to_one_ip(struct sockaddr_storage *addr, size_t addrlen, const char *host, unsigned long portnum, struct client_state *csp)
300
{
305
{
301
   struct sockaddr_in inaddr;
302
   jb_socket fd;
303
   int addr;
304
   fd_set wfds;
305
   struct timeval tv[1];
306
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
307
   int   flags;
308
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
309
310
#ifdef FEATURE_ACL
306
#ifdef FEATURE_ACL
311
   struct access_control_addr dst[1];
307
   if (csp)
312
#endif /* def FEATURE_ACL */
313
314
   memset((char *)&inaddr, 0, sizeof inaddr);
315
316
   if ((addr = resolve_hostname_to_ip(host)) == INADDR_NONE)
317
   {
308
   {
318
      csp->http->host_ip_addr_str = strdup("unknown");
309
      struct access_control_addr dst[1];
319
      return(JB_INVALID_SOCKET);
310
      char hostname[NI_MAXHOST];
320
   }
311
      char port[NI_MAXSERV];
312
      if (getnameinfo((struct sockaddr*)addr, addrlen, hostname, NI_MAXHOST,
313
                      port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) != 0)
314
      {
315
         log_error(LOG_LEVEL_ERROR, "connect: Could not get string address and port back from sockaddr because %E");
316
         strncpy(hostname,"unknown",NI_MAXHOST);
317
         strncpy(port,"unknown",NI_MAXSERV);
318
      }
321
319
322
#ifdef FEATURE_ACL
320
      csp->http->host_ip_addr_str = strdup(hostname);
323
   dst->addr = ntohl((unsigned long) addr);
324
   dst->port = portnum;
325
321
326
   if (block_acl(dst, csp))
322
      dst->addr = *addr;
327
   {
323
      dst->addrlen = addrlen;
324
      dst->port = portnum;
325
326
      if (block_acl(dst, csp))
327
      {
328
#ifdef __OS2__
328
#ifdef __OS2__
329
      errno = SOCEPERM;
329
         errno = SOCEPERM;
330
#else
330
#else
331
      errno = EPERM;
331
         errno = EPERM;
332
#endif
332
#endif
333
      return(JB_INVALID_SOCKET);
333
         return(JB_INVALID_SOCKET);
334
   }
334
      }
335
#endif /* def FEATURE_ACL */
336
335
337
   inaddr.sin_addr.s_addr = addr;
338
   inaddr.sin_family      = AF_INET;
339
   csp->http->host_ip_addr_str = strdup(inet_ntoa(inaddr.sin_addr));
340
336
341
#ifndef _WIN32
342
   if (sizeof(inaddr.sin_port) == sizeof(short))
343
#endif /* ndef _WIN32 */
344
   {
345
      inaddr.sin_port = htons((unsigned short) portnum);
346
   }
337
   }
347
#ifndef _WIN32
338
#endif /* def FEATURE_ACL */
348
   else
339
349
   {
340
   {
350
      inaddr.sin_port = htonl((unsigned long)portnum);
341
      jb_socket fd;
351
   }
352
#endif /* ndef _WIN32 */
353
342
354
#ifdef _WIN32
343
#ifdef _WIN32
355
   if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) == JB_INVALID_SOCKET)
344
      if ((fd = socket(addr->ss_family, SOCK_STREAM, 0)) == JB_INVALID_SOCKET)
356
#else
345
#else
357
   if ((fd = socket(inaddr.sin_family, SOCK_STREAM, 0)) < 0)
346
      if ((fd = socket(addr->ss_family, SOCK_STREAM, 6)) < 0)
358
#endif
347
#endif
359
   {
348
      {
360
      return(JB_INVALID_SOCKET);
349
         return(JB_INVALID_SOCKET);
361
   }
350
      }
362
351
363
#ifdef TCP_NODELAY
352
#ifdef TCP_NODELAY
364
   {  /* turn off TCP coalescence */
353
      {  /* turn off TCP coalescence */
365
      int mi = 1;
354
         int mi = 1;
366
      setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
355
         setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
367
   }
356
      }
368
#endif /* def TCP_NODELAY */
357
#endif /* def TCP_NODELAY */
369
358
370
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
359
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
371
   if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
360
      {
372
   {
361
         int flags;
373
      flags |= O_NDELAY;
362
374
      fcntl(fd, F_SETFL, flags);
363
         if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
375
   }
364
         {
365
            flags |= O_NDELAY;
366
            fcntl(fd, F_SETFL, flags);
367
         }
368
      }
376
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
369
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
377
370
378
   while (connect(fd, (struct sockaddr *) & inaddr, sizeof inaddr) == JB_INVALID_SOCKET)
371
      while (connect(fd, (struct sockaddr *) addr, addrlen) == JB_INVALID_SOCKET)
379
   {
372
      {
380
#ifdef _WIN32
373
#ifdef _WIN32
381
      if (errno == WSAEINPROGRESS)
374
         if (errno == WSAEINPROGRESS)
382
#elif __OS2__ 
375
#elif __OS2__ 
383
      if (sock_errno() == EINPROGRESS)
376
         if (sock_errno() == EINPROGRESS)
384
#else /* ifndef _WIN32 */
377
#else /* ifndef _WIN32 */
385
      if (errno == EINPROGRESS)
378
         if (errno == EINPROGRESS)
386
#endif /* ndef _WIN32 || __OS2__ */
379
#endif /* ndef _WIN32 || __OS2__ */
387
      {
380
         {
388
         break;
381
            break;
389
      }
382
         }
390
383
391
#ifdef __OS2__ 
384
#ifdef __OS2__ 
392
      if (sock_errno() != EINTR)
385
         if (sock_errno() != EINTR)
393
#else
386
#else
394
      if (errno != EINTR)
387
         if (errno != EINTR)
395
#endif /* __OS2__ */
388
#endif /* __OS2__ */
389
         {
390
            close_socket(fd);
391
            return(JB_INVALID_SOCKET);
392
         }
393
      }
394
395
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
396
      {
396
      {
397
         close_socket(fd);
397
         int flags;
398
         return(JB_INVALID_SOCKET);
398
         if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
399
         {
400
            flags &= ~O_NDELAY;
401
            fcntl(fd, F_SETFL, flags);
402
         }
399
      }
403
      }
400
   }
404
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
401
405
406
      {
407
         fd_set wfds;
408
         struct timeval tv[1];
409
410
         /* wait for connection to complete */
411
         FD_ZERO(&wfds);
412
         FD_SET(fd, &wfds);
413
414
         tv->tv_sec  = 30;
415
         tv->tv_usec = 0;
416
417
         /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
418
         if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
419
         {
420
            close_socket(fd);
421
            return(JB_INVALID_SOCKET);
422
         }
402
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
423
#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
403
   if (flags != -1)
424
         else
404
   {
425
         {
405
      flags &= ~O_NDELAY;
426
            int connect_result;
406
      fcntl(fd, F_SETFL, flags);
427
            socklen_t connect_result_len = sizeof connect_result;
407
   }
428
429
            if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &connect_result, &connect_result_len) != 0)
430
            {
431
               log_error(LOG_LEVEL_ERROR, "Could not determine whether connection to %s port %d was successful because %E. Assuming failure.",
432
                         csp->http->host_ip_addr_str, portnum);
433
               close_socket(fd);
434
               return(JB_INVALID_SOCKET);
435
            }
436
            else if( connect_result != 0 )
437
            {
438
               log_error(LOG_LEVEL_CONNECT, "Connection to %s port %d failed because %s.",
439
                         csp->http->host_ip_addr_str, portnum, strerror(connect_result));
440
               close_socket(fd);
441
               return(JB_INVALID_SOCKET);
442
            }
443
         }
408
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
444
#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
445
      }
446
      return(fd);
447
   }
448
}
409
449
410
   /* wait for connection to complete */
450
jb_socket connect_to(const char *host, const char *port, unsigned long portnum, int pf, struct client_state *csp)
411
   FD_ZERO(&wfds);
451
{
412
   FD_SET(fd, &wfds);
452
   jb_socket fd = JB_INVALID_SOCKET;
453
   struct sockaddr_storage addr;
454
   addr_list *addrs, *addrs_to_try;
413
455
414
   tv->tv_sec  = 30;
456
   addrs = resolve_hostname_to_ip(host,port,pf);
415
   tv->tv_usec = 0;
416
457
417
   /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
458
   if (is_nil_addr_list(addrs))
418
   if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
419
   {
459
   {
420
      close_socket(fd);
460
      errno = EINVAL;
421
      return(JB_INVALID_SOCKET);
461
      return fd;
462
   }
463
464
   for(addrs_to_try=addrs;
465
       !is_nil_addr_list(addrs_to_try);
466
       addrs_to_try = tail_addr_list(addrs_to_try))
467
   {
468
      size_t addrlen;
469
      memset((char *)&addr, 0, sizeof addr);
470
      cpy_head_addr_list(addrs_to_try, &addr,&addrlen);
471
      fd = connect_to_one_ip(&addr, addrlen, host, portnum, csp);
472
      if (fd != JB_INVALID_SOCKET)
473
         break;
422
   }
474
   }
423
   return(fd);
424
475
476
   if (fd == JB_INVALID_SOCKET)
477
   {
478
      csp->http->host_ip_addr_str = strdup("unknown");
479
   }
480
481
   destroy_addr_list(addrs);
482
   return fd;
425
}
483
}
426
484
427
485
Lines 561-615 Link Here
561
619
562
/*********************************************************************
620
/*********************************************************************
563
 *
621
 *
564
 * Function    :  bind_port
622
 * Function    :  bind_port_one_ip
565
 *
623
 *
566
 * Description :  Call socket, set socket options, and listen.
624
 * Description :  Call socket, set socket options, and listen.
567
 *                Called by listen_loop to "boot up" our proxy address.
568
 *
625
 *
569
 * Parameters  :
626
 * Parameters  :
570
 *          1  :  hostnam = TCP/IP address to bind/listen to
627
 *          0  :  addr = TCP/IP address and port to bind/listen to
571
 *          2  :  portnum = port to listen on
628
 *          1  :  fds = jb_socket_set where the new socket should go
572
 *          3  :  pfd = pointer used to return file descriptor.
573
 *
629
 *
574
 * Returns     :  if success, returns 0 and sets *pfd.
630
 * Returns     :  if success returns 0 and adds sockets to fds.
575
 *                if failure, returns -3 if address is in use,
631
 *                if failure, returns -3 if address is in use,
576
 *                                    -2 if address unresolvable,
632
 *                                    -2 if memory error
577
 *                                    -1 otherwise
633
 *                                    -1 otherwise
578
 *********************************************************************/
634
 *********************************************************************/
579
int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
635
int bind_port_one_ip(struct sockaddr *addr, const socklen_t addr_len, jb_socket_set *fds)
580
{
636
{
581
   struct sockaddr_in inaddr;
582
   jb_socket fd;
637
   jb_socket fd;
638
   int flags;
583
#ifndef _WIN32
639
#ifndef _WIN32
584
   int one = 1;
640
   int one = 1;
585
#endif /* ndef _WIN32 */
641
#endif /* ndef _WIN32 */
586
642
587
   *pfd = JB_INVALID_SOCKET;
643
   fd = JB_INVALID_SOCKET;
588
589
   memset((char *)&inaddr, '\0', sizeof inaddr);
590
591
   inaddr.sin_family      = AF_INET;
592
   inaddr.sin_addr.s_addr = resolve_hostname_to_ip(hostnam);
593
594
   if (inaddr.sin_addr.s_addr == INADDR_NONE)
595
   {
596
      return(-2);
597
   }
598
599
#ifndef _WIN32
600
   if (sizeof(inaddr.sin_port) == sizeof(short))
601
#endif /* ndef _WIN32 */
602
   {
603
      inaddr.sin_port = htons((unsigned short) portnum);
604
   }
605
#ifndef _WIN32
606
   else
607
   {
608
      inaddr.sin_port = htonl((unsigned long) portnum);
609
   }
610
#endif /* ndef _WIN32 */
611
644
612
   fd = socket(AF_INET, SOCK_STREAM, 0);
645
   fd = socket(addr->sa_family, SOCK_STREAM, 6);
613
646
614
#ifdef _WIN32
647
#ifdef _WIN32
615
   if (fd == JB_INVALID_SOCKET)
648
   if (fd == JB_INVALID_SOCKET)
Lines 635-642 Link Here
635
    */
668
    */
636
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
669
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
637
#endif /* ndef _WIN32 */
670
#endif /* ndef _WIN32 */
638
671
   /* As we are now listening on more than one socket,
639
   if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
672
    * this is important: The only way to be sure accept
673
    * won't block!!
674
    */
675
   if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
676
   {
677
      flags |= O_NONBLOCK;
678
      fcntl(fd, F_SETFL, flags);
679
   }
680
   
681
   if (bind (fd, addr, addr_len) < 0)
640
   {
682
   {
641
#ifdef _WIN32
683
#ifdef _WIN32
642
      errno = WSAGetLastError();
684
      errno = WSAGetLastError();
Lines 655-661 Link Here
655
      }
697
      }
656
   }
698
   }
657
699
658
   while (listen(fd, 5) == -1)
700
   while (listen(fd, 25) == -1)
659
   {
701
   {
660
      if (errno != EINTR)
702
      if (errno != EINTR)
661
      {
703
      {
Lines 663-669 Link Here
663
      }
705
      }
664
   }
706
   }
665
707
666
   *pfd = fd;
708
   if (jb_socket_set_add(fds,fd) != 0)
709
   {
710
      close_socket(fd);
711
      return -2;
712
   }
667
   return 0;
713
   return 0;
668
714
669
}
715
}
Lines 671-676 Link Here
671
717
672
/*********************************************************************
718
/*********************************************************************
673
 *
719
 *
720
 * Function    :  bind_port
721
 *
722
 * Description :  Call bind_port_one_ip on all addresses host resolves to
723
 *                Called by listen_loop to "boot up" our proxy address.
724
 *
725
 * Parameters  :
726
 *          0  :  host = TCP/IP hostname to bind/listen to
727
 *          1  :  port = port to listen to, as string
728
 *          2  :  fds = socket set the sockets should be added to
729
 *
730
 * Returns     :  if success on at least one address resolving from hostnam,
731
 *                 returns 0 and adds sockets to fds.
732
 *                if failure, returns non-zero
733
 *********************************************************************/
734
int bind_port(const char *host, const char *port, int pf, jb_socket_set *fds)
735
{
736
   int result;
737
   int failure = 1;
738
   struct sockaddr_storage addr;
739
   struct sockaddr * const addr_addr = (struct sockaddr *)&addr;
740
   addr_list *addrs, *addrs_to_try;
741
742
   const char * const log_host = (host != NULL) ? host : "ADDR_ANY";
743
744
   addrs = resolve_hostname_to_ip(host,port,pf);
745
746
   if (is_nil_addr_list(addrs))
747
      log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s: " 
748
                "Name resolution didn't give any address",
749
                log_host, port);
750
751
   log_error(LOG_LEVEL_INFO, "Binding to %s:%s...",  log_host, port);
752
753
   for(addrs_to_try=addrs;
754
       !is_nil_addr_list(addrs_to_try);
755
       addrs_to_try = tail_addr_list(addrs_to_try))
756
   {
757
      char numeric_hostname[NI_MAXHOST];
758
      char numeric_port[NI_MAXSERV];
759
      size_t addrlen;
760
      memset((char *)addr_addr, 0, sizeof addr);
761
      cpy_head_addr_list(addrs_to_try, &addr, &addrlen);
762
      result = getnameinfo(addr_addr, addrlen, numeric_hostname, NI_MAXHOST,
763
                           numeric_port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
764
      if (result != 0)
765
      {
766
         log_error(LOG_LEVEL_ERROR, "bind: Could not get string address and port back from sockaddr because %E");
767
         strncpy(numeric_hostname,"unknown",NI_MAXHOST);
768
         strncpy(numeric_port,"unknown",NI_MAXSERV);
769
      }
770
      result = bind_port_one_ip(addr_addr, addrlen, fds);
771
      if( result == 0 )
772
      {
773
         failure = 0;
774
         log_error(LOG_LEVEL_INFO, "Successfully bound to %s:%s", numeric_hostname, numeric_port);
775
      }
776
      else
777
      {
778
         switch(result)
779
         {
780
         case -3 :
781
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s (%s:%s): "
782
                      "There may be another Privoxy or some other "
783
                      "proxy running on port %s",
784
                      log_host, port, numeric_hostname, numeric_port, numeric_port);
785
            break;
786
         case -2 :
787
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s (%s:%s): "
788
                      "Out of memory",
789
                      log_host, port, numeric_hostname, numeric_port);
790
            break;
791
         default :
792
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s: because %E",
793
                      log_host, numeric_port);
794
         }
795
      }
796
   }
797
798
   destroy_addr_list(addrs);
799
   return failure;
800
}
801
802
803
/*********************************************************************
804
 *
674
 * Function    :  accept_connection
805
 * Function    :  accept_connection
675
 *
806
 *
676
 * Description :  Accepts a connection on a socket.  Socket must have
807
 * Description :  Accepts a connection on a socket.  Socket must have
Lines 687-694 Link Here
687
 *********************************************************************/
818
 *********************************************************************/
688
int accept_connection(struct client_state * csp, jb_socket fd)
819
int accept_connection(struct client_state * csp, jb_socket fd)
689
{
820
{
690
   struct sockaddr_in client, server;
821
   struct sockaddr_storage client, server;
691
   struct hostent *host = NULL;
692
   jb_socket afd;
822
   jb_socket afd;
693
#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
823
#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
694
   /* Wierdness - fix a warning. */
824
   /* Wierdness - fix a warning. */
Lines 696-710 Link Here
696
#else
826
#else
697
   socklen_t c_length, s_length;
827
   socklen_t c_length, s_length;
698
#endif
828
#endif
699
#if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) ||  defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
829
   int flags;
700
   struct hostent result;
701
#if defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
702
   struct hostent_data hdata;
703
#else
704
   char hbuf[HOSTENT_BUFFER_SIZE];
705
   int thd_err;
706
#endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
707
#endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
708
830
709
   c_length = s_length = sizeof(client);
831
   c_length = s_length = sizeof(client);
710
832
Lines 724-729 Link Here
724
      return 0;
846
      return 0;
725
   }
847
   }
726
#endif
848
#endif
849
   /* If we inherited O_NONBLOCK from the listening fd, unset it */
850
   if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
851
   {
852
      flags &= ~O_NONBLOCK;
853
      fcntl(fd, F_SETFL, flags);
854
   }
727
855
728
   /* 
856
   /* 
729
    * Determine the IP-Adress that the client used to reach us
857
    * Determine the IP-Adress that the client used to reach us
Lines 731-779 Link Here
731
    */
859
    */
732
   if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
860
   if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
733
   {
861
   {
734
      csp->my_ip_addr_str = strdup(inet_ntoa(server.sin_addr));
862
      char hostname[NI_MAXHOST];
735
#if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
863
      char port[NI_MAXSERV];
736
      gethostbyaddr_r((const char *)&server.sin_addr,
864
737
                      sizeof(server.sin_addr), AF_INET,
865
      if (getnameinfo((struct sockaddr *)&server, s_length, hostname, NI_MAXHOST,
738
                      &result, hbuf, HOSTENT_BUFFER_SIZE,
866
                      port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) != 0)
739
                      &host, &thd_err);
740
#elif defined(HAVE_GETHOSTBYADDR_R_7_ARGS)
741
      host = gethostbyaddr_r((const char *)&server.sin_addr,
742
                      sizeof(server.sin_addr), AF_INET,
743
                      &result, hbuf, HOSTENT_BUFFER_SIZE, &thd_err);
744
#elif defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
745
      if (0 == gethostbyaddr_r((const char *)&server.sin_addr,
746
                               sizeof(server.sin_addr), AF_INET,
747
                               &result, &hdata))
748
      {
867
      {
749
         host = &result;
868
         log_error(LOG_LEVEL_ERROR, "accept: Could not get string address and port back from server sockaddr because %E");
869
         strncpy(hostname,"unknown IP",NI_MAXHOST);
870
         strncpy(port,"unknown port",NI_MAXSERV);
750
      }
871
      }
751
      else
872
      csp->my_ip_addr_str = strdup(hostname);
873
      csp->my_port_str = strdup(port);
874
875
      if (getnameinfo((struct sockaddr *)&server, s_length, hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD) != 0)
752
      {
876
      {
753
         host = NULL;
877
         log_error(LOG_LEVEL_ERROR, "accept: Could not get my own hostname because %E");
878
         strncpy(hostname,"unknown host",NI_MAXHOST);
754
      }
879
      }
755
#elif FEATURE_PTHREAD
880
      csp->my_hostname = strdup(hostname);
756
      pthread_mutex_lock(&gethostbyaddr_mutex);
881
   }
757
      host = gethostbyaddr((const char *)&server.sin_addr, 
882
   else
758
                           sizeof(server.sin_addr), AF_INET);
883
   {
759
      pthread_mutex_unlock(&gethostbyaddr_mutex);
884
      log_error(LOG_LEVEL_ERROR, "accept: Could not get sockaddr from socket fd because %E");
760
#else
885
   }
761
      host = gethostbyaddr((const char *)&server.sin_addr, 
886
762
                           sizeof(server.sin_addr), AF_INET);
887
   csp->cfd    = afd;
763
#endif
888
   {
764
      if (host == NULL)
889
      char hostname[NI_MAXHOST];
890
891
      if (getnameinfo((struct sockaddr *)&client, c_length, hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
765
      {
892
      {
766
         log_error(LOG_LEVEL_ERROR, "Unable to get my own hostname: %E\n");
893
         log_error(LOG_LEVEL_ERROR, "accept: Could not get client IP address string because %E");
894
         strncpy(hostname,"unknown IP",NI_MAXHOST);
767
      }
895
      }
768
      else
896
      csp->my_ip_addr_str = strdup(hostname);
897
898
      if (getnameinfo((struct sockaddr *)&server, s_length, hostname, NI_MAXHOST, NULL, 0, 0) != 0)
769
      {
899
      {
770
         csp->my_hostname = strdup(host->h_name);
900
         log_error(LOG_LEVEL_ERROR, "accept: Could not get my own hostname because %E");
901
         strncpy(hostname,"unknown host",NI_MAXHOST);
771
      }
902
      }
903
      csp->ip_addr_str = strdup(hostname);
772
   }
904
   }
773
905
   csp->ip_addr_addr = client;
774
   csp->cfd    = afd;
775
   csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
776
   csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
777
906
778
   return 1;
907
   return 1;
779
908
Lines 784-891 Link Here
784
 *
913
 *
785
 * Function    :  resolve_hostname_to_ip
914
 * Function    :  resolve_hostname_to_ip
786
 *
915
 *
787
 * Description :  Resolve a hostname to an internet tcp/ip address.
916
 * Description :  Resolve a hostname to a list of internet tcp/ip addresses.
788
 *                NULL or an empty string resolve to INADDR_ANY.
789
 *
917
 *
790
 * Parameters  :
918
 * Parameters  :
791
 *          1  :  host = hostname to resolve
919
 *          0  :  host = hostname to resolve
920
 *          1  :  result = where to store the result
921
 *          2  :  pf = preferred address family. PF_UNSPEC for no preference (recommended).
792
 *
922
 *
793
 * Returns     :  INADDR_NONE => failure, INADDR_ANY or tcp/ip address if succesful.
923
 * Returns     :  A (possibly empty) list of adresses
794
 *
924
 *
795
 *********************************************************************/
925
 *********************************************************************/
796
unsigned long resolve_hostname_to_ip(const char *host)
926
addr_list *resolve_hostname_to_ip(const char *host, const char *port, int pf)
797
{
927
 {
798
   struct sockaddr_in inaddr;
928
   /* TODO 
799
   struct hostent *hostp;
929
    * Do all supported platforms have "getaddrinfo"?
930
    */
931
    
932
   struct addrinfo hints, *res0;
933
   int result;
800
   unsigned int dns_retries = 0;
934
   unsigned int dns_retries = 0;
801
#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS) || defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
802
   struct hostent result;
803
#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS) || defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
804
   char hbuf[HOSTENT_BUFFER_SIZE];
805
   int thd_err;
806
#else /* defined(HAVE_GETHOSTBYNAME_R_3_ARGS) */
807
   struct hostent_data hdata;
808
#endif /* def HAVE_GETHOSTBYNAME_R_(6|5)_ARGS */
809
#endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
810
935
811
   if ((host == NULL) || (*host == '\0'))
936
   memset(&hints, 0, sizeof(hints));
812
   {
937
   hints.ai_family = pf;
813
      return(INADDR_ANY);
938
   hints.ai_socktype = SOCK_STREAM;
814
   }
939
  
815
940
   while ((result = getaddrinfo(host, port, &hints, &res0)) 
816
   memset((char *) &inaddr, 0, sizeof inaddr);
941
          && (result == EAI_AGAIN) && (dns_retries++ < 10)) {
817
942
      log_error(LOG_LEVEL_ERROR, "Timeout #%u while trying to resolve %s. Trying again.",
818
   if ((inaddr.sin_addr.s_addr = inet_addr(host)) == -1)
943
                dns_retries, host);
819
   {
820
#if defined(HAVE_GETHOSTBYNAME_R_6_ARGS)
821
       while ( gethostbyname_r(host, &result, hbuf,
822
                      HOSTENT_BUFFER_SIZE, &hostp, &thd_err)
823
               && (thd_err == TRY_AGAIN) && (dns_retries++ < 10) )
824
      {   
825
         log_error(LOG_LEVEL_ERROR, "Timeout #%u while trying to resolve %s. Trying again.",
826
                                                dns_retries, host);
827
      }
828
#elif defined(HAVE_GETHOSTBYNAME_R_5_ARGS)
829
      hostp = gethostbyname_r(host, &result, hbuf,
830
                      HOSTENT_BUFFER_SIZE, &thd_err);
831
#elif defined(HAVE_GETHOSTBYNAME_R_3_ARGS)
832
      if (0 == gethostbyname_r(host, &result, &hdata))
833
      {
834
         hostp = &result;
835
      }
836
      else
837
      {
838
         hostp = NULL;
839
      }
840
#elif FEATURE_PTHREAD
841
      pthread_mutex_lock(&gethostbyname_mutex);
842
      while ( NULL == (hostp = gethostbyname(host))
843
            && (h_errno == TRY_AGAIN) && (dns_retries++ < 10) )
844
      {   
845
         log_error(LOG_LEVEL_ERROR, "Timeout #%u while trying to resolve %s. Trying again.",
846
                                                dns_retries, host);
847
      }
848
      pthread_mutex_unlock(&gethostbyname_mutex);
849
#else
850
      while ( NULL == (hostp = gethostbyname(host))
851
            && (h_errno == TRY_AGAIN) && (dns_retries++ < 10) )
852
      {
853
         log_error(LOG_LEVEL_ERROR, "Timeout #%u while trying to resolve %s. Trying again.",
854
                                                dns_retries, host);
855
      }
856
#endif /* def HAVE_GETHOSTBYNAME_R_(6|5|3)_ARGS */
857
      /*
858
       * On Mac OSX, if a domain exists but doesn't have a type A
859
       * record associated with it, the h_addr member of the struct
860
       * hostent returned by gethostbyname is NULL, even if h_length
861
       * is 4. Therefore the second test below.
862
       */
863
      if (hostp == NULL || hostp->h_addr == NULL)
864
      {
865
         errno = EINVAL;
866
         log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s", host);
867
         return(INADDR_NONE);
868
      }
869
      if (hostp->h_addrtype != AF_INET)
870
      {
871
#ifdef _WIN32
872
         errno = WSAEPROTOTYPE;
873
#else
874
         errno = EPROTOTYPE;
875
#endif 
876
         log_error(LOG_LEVEL_ERROR, "hostname %s resolves to unknown address type.", host);
877
         return(INADDR_NONE);
878
      }
879
      memcpy(
880
         (char *) &inaddr.sin_addr,
881
         (char *) hostp->h_addr,
882
         sizeof(inaddr.sin_addr)
883
      );
884
   }
944
   }
885
   return(inaddr.sin_addr.s_addr);
945
   if ( result != 0 )
886
946
     {
887
}
947
      log_error(LOG_LEVEL_ERROR, "could not resolve hostname %s because %s", host,gai_strerror(result));
888
948
      if (result == EAI_SYSTEM)
949
         log_error(LOG_LEVEL_ERROR, "The system error is %E");
950
      return NULL;
951
     }
952
   else
953
      if (res0==0)
954
         log_error(LOG_LEVEL_ERROR, "Problem in resolving hostname %s: succeeded, but no information returned", host);
955
  
956
   return res0;
957
 }
889
958
890
/*
959
/*
891
  Local Variables:
960
  Local Variables:
(-)privoxy~/jbsockets.h (-3 / +8 lines)
Lines 13-18 Link Here
13
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
13
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
14
 *                Privoxy team. http://www.privoxy.org/
14
 *                Privoxy team. http://www.privoxy.org/
15
 *
15
 *
16
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
17
 *                for IPv6 support on 8 December 2002, 24 January 2003.
18
 *
16
 *                Based on the Internet Junkbuster originally written
19
 *                Based on the Internet Junkbuster originally written
17
 *                by and Copyright (C) 1997 Anonymous Coders and 
20
 *                by and Copyright (C) 1997 Anonymous Coders and 
18
 *                Junkbusters Corporation.  http://www.junkbusters.com
21
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 104-112 Link Here
104
extern "C" {
107
extern "C" {
105
#endif
108
#endif
106
109
110
#include "addrlist.h"
111
107
struct client_state;
112
struct client_state;
108
113
109
extern jb_socket connect_to(const char *host, int portnum, struct client_state *csp);
114
extern jb_socket connect_to(const char *host, const char *port, unsigned long portnum, int pf, struct client_state *csp);
110
#ifdef AMIGA
115
#ifdef AMIGA
111
extern int write_socket(jb_socket fd, const char *buf, ssize_t n);
116
extern int write_socket(jb_socket fd, const char *buf, ssize_t n);
112
#else
117
#else
Lines 115-124 Link Here
115
extern int read_socket(jb_socket fd, char *buf, int n);
120
extern int read_socket(jb_socket fd, char *buf, int n);
116
extern void close_socket(jb_socket fd);
121
extern void close_socket(jb_socket fd);
117
122
118
extern int bind_port(const char *hostnam, int portnum, jb_socket *pfd);
123
extern int bind_port(const char *host, const char *port, int pf, jb_socket_set *fds);
119
extern int accept_connection(struct client_state * csp, jb_socket fd);
124
extern int accept_connection(struct client_state * csp, jb_socket fd);
120
125
121
extern unsigned long resolve_hostname_to_ip(const char *host);
126
extern addr_list *resolve_hostname_to_ip(const char *host, const char *port, int pf);
122
127
123
/* Revision control strings from this header and associated .c file */
128
/* Revision control strings from this header and associated .c file */
124
extern const char jbsockets_rcs[];
129
extern const char jbsockets_rcs[];
(-)privoxy~/jcc.c (-41 / +108 lines)
Lines 750-755 Link Here
750
#include "cgi.h"
750
#include "cgi.h"
751
#include "loadcfg.h"
751
#include "loadcfg.h"
752
#include "urlmatch.h"
752
#include "urlmatch.h"
753
#include "jb_socket_set.h"
753
754
754
const char jcc_h_rcs[] = JCC_H_VERSION;
755
const char jcc_h_rcs[] = JCC_H_VERSION;
755
const char project_h_rcs[] = PROJECT_H_VERSION;
756
const char project_h_rcs[] = PROJECT_H_VERSION;
Lines 2309-2369 Link Here
2309
 * Returns     :  Port that was opened.
2310
 * Returns     :  Port that was opened.
2310
 *
2311
 *
2311
 *********************************************************************/
2312
 *********************************************************************/
2312
static jb_socket bind_port_helper(struct configuration_spec * config)
2313
static void bind_port_helper(struct configuration_spec * config, jb_socket_set *bfds)
2313
{
2314
{
2314
   int result;
2315
   int result;
2315
   jb_socket bfd;
2316
   struct bind_spec *bs;
2317
   unsigned int bs_index;
2318
   int never_bound;
2316
2319
2317
   if ( (config->haddr != NULL)
2320
   never_bound = 1;
2318
     && (config->haddr[0] == '1')
2321
   for (bs_index = 0; bs_index < config->hspecs_occupied;++bs_index)
2319
     && (config->haddr[1] == '2')
2320
     && (config->haddr[2] == '7')
2321
     && (config->haddr[3] == '.') )
2322
   {
2323
      log_error(LOG_LEVEL_INFO, "Listening on port %d for local connections only",
2324
                config->hport);
2325
   }
2326
   else if (config->haddr == NULL)
2327
   {
2328
      log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses",
2329
                config->hport);
2330
   }
2331
   else
2332
   {
2322
   {
2333
      log_error(LOG_LEVEL_INFO, "Listening on port %d on IP address %s",
2323
      bs = &config->hspecs[bs_index];
2334
                config->hport, config->haddr);
2324
      
2335
   }
2325
      /* This check misses about a trillion zillion different manners to describe
2326
         the local interface in IPv6. Who cares? */
2327
      if ( (bs->haddr != NULL)
2328
           && (((bs->haddr[0] == '1')
2329
                && (bs->haddr[1] == '2')
2330
                && (bs->haddr[2] == '7')
2331
                && (bs->haddr[3] == '.'))
2332
               || ((bs->haddr[0] == ':')
2333
                   && (bs->haddr[1] == ':')
2334
                   && (bs->haddr[2] == '1'))))
2335
      {
2336
         log_error(LOG_LEVEL_INFO, "Listening on port %s for local connections only",
2337
                   bs->hport);
2338
      }
2339
      else if (bs->haddr == NULL || bs->haddr[0]=='\0')
2340
      {
2341
         log_error(LOG_LEVEL_INFO, "Listening on port %s on all IP addresses",
2342
                   bs->hport);
2343
      }
2344
      else
2345
      {
2346
         log_error(LOG_LEVEL_INFO, "Listening on port %s on IP address %s",
2347
                   bs->hport, bs->haddr);
2348
      }
2336
2349
2337
   result = bind_port(config->haddr, config->hport, &bfd);
2350
      result = bind_port(bs->haddr, bs->hport, bs->pf, bfds);
2338
2351
2339
   if (result < 0)
2352
      if (result != 0)
2340
   {
2341
      switch(result)
2342
      {
2353
      {
2354
         switch(result)
2355
         {
2343
         case -3 :
2356
         case -3 :
2344
            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: "
2357
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s: "
2345
               "There may be another Privoxy or some other "
2358
               "There may be another Privoxy or some other "
2346
               "proxy running on port %d",
2359
               "proxy running on port %s",
2347
               (NULL != config->haddr) ? config->haddr : "INADDR_ANY",
2360
               (NULL != bs->haddr) ? bs->haddr : "INADDR_ANY",
2348
                      config->hport, config->hport);
2361
                      bs->hport, bs->hport);
2362
            break;
2349
2363
2350
         case -2 :
2364
         case -2 :
2351
            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: " 
2365
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s: " 
2352
               "The hostname is not resolvable",
2366
               "The hostname is not resolvable",
2353
               (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
2367
               (NULL != bs->haddr) ? bs->haddr : "INADDR_ANY", bs->hport);
2368
            break;
2354
2369
2355
         default :
2370
         default :
2356
            log_error(LOG_LEVEL_FATAL, "can't bind to %s:%d: because %E",
2371
            log_error(LOG_LEVEL_ERROR, "can't bind to %s:%s: because %E",
2357
               (NULL != config->haddr) ? config->haddr : "INADDR_ANY", config->hport);
2372
               (NULL != bs->haddr) ? bs->haddr : "INADDR_ANY", bs->hport);
2373
         }
2358
      }
2374
      }
2375
      else
2376
         never_bound = 0;
2377
   }
2359
2378
2379
   if(never_bound)
2380
   {
2381
      log_error(LOG_LEVEL_FATAL, "Couldn't bind at all - bailing out");
2360
      /* shouldn't get here */
2382
      /* shouldn't get here */
2361
      return JB_INVALID_SOCKET;
2362
   }
2383
   }
2363
2364
   config->need_bind = 0;
2384
   config->need_bind = 0;
2365
2366
   return bfd;
2367
}
2385
}
2368
2386
2369
2387
Lines 2392-2403 Link Here
2392
static void listen_loop(void)
2410
static void listen_loop(void)
2393
{
2411
{
2394
   struct client_state *csp = NULL;
2412
   struct client_state *csp = NULL;
2395
   jb_socket bfd;
2413
   jb_socket_set bfds;
2414
   fd_set bfds_fs;
2415
   jb_socket_set_iterate_state bfds_iterate_state;
2416
   jb_socket bfd_current;
2396
   struct configuration_spec * config;
2417
   struct configuration_spec * config;
2397
2418
2419
   init_jb_socket_set(&bfds);
2420
2398
   config = load_config();
2421
   config = load_config();
2399
2422
2400
   bfd = bind_port_helper(config);
2423
   bind_port_helper(config,&bfds);
2424
   bfd_current=JB_INVALID_SOCKET;
2401
2425
2402
#ifdef FEATURE_GRACEFUL_TERMINATION
2426
#ifdef FEATURE_GRACEFUL_TERMINATION
2403
   while (!g_terminate)
2427
   while (!g_terminate)
Lines 2471-2484 Link Here
2471
          * that this will hurt people's feelings.
2495
          * that this will hurt people's feelings.
2472
          */
2496
          */
2473
2497
2474
         close_socket(bfd);
2498
         jb_socket_set_iterate_state s;
2499
         jb_socket bfd;
2500
         s=jb_socket_set_iteration_begin(&bfds);
2501
         for(bfd=jb_socket_set_iteration_next(&s);bfd!=JB_INVALID_SOCKET;bfd=jb_socket_set_iteration_next(&s))
2502
         {
2503
            close_socket(bfd);
2504
         }
2505
         destroy_jb_socket_set(&bfds);
2506
         bind_port_helper(config,&bfds);
2507
         /* We have a new set of fd's to accept. Restart iteration over bfds. */
2508
         bfd_current = JB_INVALID_SOCKET;
2509
      }
2475
2510
2476
         bfd = bind_port_helper(config);
2511
      /* Here: select call on listening sockets: bfd=sockets */
2512
      if (bfd_current == JB_INVALID_SOCKET)
2513
      {
2514
         jb_socket max;
2515
         log_error(LOG_LEVEL_CONNECT, "select connections ... ");
2516
         bfds_iterate_state=jb_socket_set_iteration_begin(&bfds);
2517
         FD_ZERO(&bfds_fs);
2518
         max = 0;
2519
         for(bfd_current=jb_socket_set_iteration_next(&bfds_iterate_state);
2520
             bfd_current!=JB_INVALID_SOCKET;
2521
             bfd_current=jb_socket_set_iteration_next(&bfds_iterate_state))
2522
         {
2523
            FD_SET(bfd_current,&bfds_fs);
2524
            if (bfd_current >= max)
2525
               max = bfd_current + 1;
2526
         }
2527
         if(!select(max,&bfds_fs,NULL,NULL,NULL))
2528
         {
2529
            log_error(LOG_LEVEL_CONNECT, "select failed: %E");
2530
            bfd_current=JB_INVALID_SOCKET;
2531
            continue;
2532
         }
2533
         log_error(LOG_LEVEL_CONNECT, "OK");
2534
         bfds_iterate_state=jb_socket_set_iteration_begin(&bfds);
2535
         bfd_current=jb_socket_set_iteration_next(&bfds_iterate_state);
2536
      }
2537
      if (!FD_ISSET(bfd_current,&bfds_fs))
2538
      {
2539
         bfd_current=jb_socket_set_iteration_next(&bfds_iterate_state);
2540
         freez(csp);
2541
         continue;
2477
      }
2542
      }
2478
2543
2479
      log_error(LOG_LEVEL_CONNECT, "accept connection ... ");
2544
      log_error(LOG_LEVEL_CONNECT, "accept connection ... ");
2480
2545
2481
      if (!accept_connection(csp, bfd))
2546
      if (!accept_connection(csp, bfd_current))
2482
      {
2547
      {
2483
         log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
2548
         log_error(LOG_LEVEL_CONNECT, "accept failed: %E");
2484
2549
Lines 2496-2501 Link Here
2496
         log_error(LOG_LEVEL_CONNECT, "OK");
2561
         log_error(LOG_LEVEL_CONNECT, "OK");
2497
      }
2562
      }
2498
2563
2564
      bfd_current=jb_socket_set_iteration_next(&bfds_iterate_state);
2565
2499
#ifdef FEATURE_TOGGLE
2566
#ifdef FEATURE_TOGGLE
2500
      if (global_toggle_state)
2567
      if (global_toggle_state)
2501
      {
2568
      {
(-)privoxy~/loadcfg.c (-217 / +225 lines)
Lines 11-16 Link Here
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
12
 *                Privoxy team. http://www.privoxy.org/
12
 *                Privoxy team. http://www.privoxy.org/
13
 *
13
 *
14
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
15
 *                for IPv6 support on 8 December 2002, 24 January 2003.
16
 *
14
 *                Based on the Internet Junkbuster originally written
17
 *                Based on the Internet Junkbuster originally written
15
 *                by and Copyright (C) 1997 Anonymous Coders and
18
 *                by and Copyright (C) 1997 Anonymous Coders and
16
 *                Junkbusters Corporation.  http://www.junkbusters.com
19
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 402-407 Link Here
402
#include "encode.h"
405
#include "encode.h"
403
#include "urlmatch.h"
406
#include "urlmatch.h"
404
#include "cgi.h"
407
#include "cgi.h"
408
#include "parsers.h"
405
409
406
const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
410
const char loadcfg_h_rcs[] = LOADCFG_H_VERSION;
407
411
Lines 521-528 Link Here
521
      struct forward_spec * next_fwd = cur_fwd->next;
525
      struct forward_spec * next_fwd = cur_fwd->next;
522
      free_url_spec(cur_fwd->url);
526
      free_url_spec(cur_fwd->url);
523
527
524
      freez(cur_fwd->gateway_host);
528
      freez(cur_fwd->gateway_malloc);
525
      freez(cur_fwd->forward_host);
529
      freez(cur_fwd->forward_malloc);
526
      free(cur_fwd);
530
      free(cur_fwd);
527
      cur_fwd = next_fwd;
531
      cur_fwd = next_fwd;
528
   }
532
   }
Lines 539-545 Link Here
539
   freez(config->confdir);
543
   freez(config->confdir);
540
   freez(config->logdir);
544
   freez(config->logdir);
541
545
542
   freez(config->haddr);
546
   if(config -> hspecs != NULL)
547
   {
548
      int i;
549
      for (i=0; i < config->hspecs_occupied; ++i)
550
      {
551
         freez(config->hspecs[i].haddr);
552
         freez(config->hspecs[i].hport);
553
      }
554
   }
555
   freez(config->hspecs);
543
   freez(config->logfile);
556
   freez(config->logfile);
544
557
545
   for (i = 0; i < MAX_AF_FILES; i++)
558
   for (i = 0; i < MAX_AF_FILES; i++)
Lines 606-611 Link Here
606
 * Returns     :  The configuration_spec, or NULL on error.
619
 * Returns     :  The configuration_spec, or NULL on error.
607
 *
620
 *
608
 *********************************************************************/
621
 *********************************************************************/
622
static void fail_load_config_memory(struct file_list *fs, struct configuration_spec *config)
623
{
624
   freez(fs->filename);
625
   freez(fs);
626
   if (config != NULL)
627
   {
628
      if(config -> hspecs != NULL)
629
      {
630
         int i;
631
         for (i=0; i < config->hspecs_occupied; ++i)
632
         {
633
            freez(config->hspecs[i].haddr);
634
            freez(config->hspecs[i].hport);
635
         }
636
      }
637
      freez(config -> hspecs);
638
   }
639
   freez(config);
640
   log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
641
   /* Never get here - LOG_LEVEL_FATAL causes program exit */
642
}
643
609
struct configuration_spec * load_config(void)
644
struct configuration_spec * load_config(void)
610
{
645
{
611
   char buf[BUFFER_SIZE];
646
   char buf[BUFFER_SIZE];
Lines 637-648 Link Here
637
   fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
672
   fs->f = config = (struct configuration_spec *)zalloc(sizeof(*config));
638
673
639
   if (config==NULL)
674
   if (config==NULL)
640
   {
675
      fail_load_config_memory(fs,config);
641
      freez(fs->filename);
642
      freez(fs);
643
      log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
644
      /* Never get here - LOG_LEVEL_FATAL causes program exit */
645
   }
646
676
647
   /*
677
   /*
648
    * This is backwards from how it's usually done.
678
    * This is backwards from how it's usually done.
Lines 659-665 Link Here
659
    * Set to defaults
689
    * Set to defaults
660
    */
690
    */
661
   config->multi_threaded            = 1;
691
   config->multi_threaded            = 1;
662
   config->hport                     = HADDR_PORT;
692
   config->hspecs                    = NULL;
663
   config->buffer_limit              = 4096 * 1024;
693
   config->buffer_limit              = 4096 * 1024;
664
   config->usermanual                = strdup(USER_MANUAL_URL);
694
   config->usermanual                = strdup(USER_MANUAL_URL);
665
   config->proxy_args                = strdup("");
695
   config->proxy_args                = strdup("");
Lines 678-686 Link Here
678
      char cmd[BUFFER_SIZE];
708
      char cmd[BUFFER_SIZE];
679
      char arg[BUFFER_SIZE];
709
      char arg[BUFFER_SIZE];
680
      char tmp[BUFFER_SIZE];
710
      char tmp[BUFFER_SIZE];
681
#ifdef FEATURE_ACL
682
      struct access_control_list *cur_acl;
683
#endif /* def FEATURE_ACL */
684
      struct forward_spec *cur_fwd;
711
      struct forward_spec *cur_fwd;
685
      int vec_count;
712
      int vec_count;
686
      char *vec[3];
713
      char *vec[3];
Lines 791-864 Link Here
791
 * *************************************************************************/
818
 * *************************************************************************/
792
#ifdef FEATURE_ACL
819
#ifdef FEATURE_ACL
793
         case hash_deny_access:
820
         case hash_deny_access:
794
            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
821
            switch (ssplit(arg, " \t", vec, SZ(vec), 1, 1))
795
796
            if ((vec_count != 1) && (vec_count != 2))
797
            {
798
               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
799
                     "deny-access directive in configuration file.");
800
               string_append(&config->proxy_args,
801
                  "<br>\nWARNING: Wrong number of parameters for "
802
                  "deny-access directive in configuration file.<br><br>\n");
803
               continue;
804
            }
805
806
            /* allocate a new node */
807
            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
808
809
            if (cur_acl == NULL)
810
            {
811
               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
812
               /* Never get here - LOG_LEVEL_FATAL causes program exit */
813
               continue;
814
            }
815
            cur_acl->action = ACL_DENY;
816
817
            if (acl_addr(vec[0], cur_acl->src) < 0)
818
            {
819
               log_error(LOG_LEVEL_ERROR, "Invalid source IP for deny-access "
820
                     "directive in configuration file: \"%s\"", vec[0]);
821
               string_append(&config->proxy_args,
822
                  "<br>\nWARNING: Invalid source IP for deny-access directive"
823
                  " in configuration file: \"");
824
               string_append(&config->proxy_args,
825
                  vec[0]);
826
               string_append(&config->proxy_args,
827
                  "\"<br><br>\n");
828
               freez(cur_acl);
829
               continue;
830
            }
831
            if (vec_count == 2)
832
            {
822
            {
833
               if (acl_addr(vec[1], cur_acl->dst) < 0)
823
               case 1:
834
               {
824
                  config->acl = add_to_acl_list(config->acl, ACL_DENY, vec[0], NULL, &config->proxy_args);
835
                  log_error(LOG_LEVEL_ERROR, "Invalid destination IP for deny-access "
825
                  break;
836
                        "directive in configuration file: \"%s\"", vec[0]);
826
               case 2:
837
                  string_append(&config->proxy_args,
827
                  config->acl = add_to_acl_list(config->acl, ACL_DENY, vec[0], vec[1], &config->proxy_args);
838
                     "<br>\nWARNING: Invalid destination IP for deny-access directive"
828
                  break;
839
                     " in configuration file: \"");
829
               default:
840
                  string_append(&config->proxy_args,
830
                  log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
841
                     vec[0]);
831
                            "deny-access directive in configuration file.");
842
                  string_append(&config->proxy_args,
832
                  string_append(&config->proxy_args,
843
                     "\"<br><br>\n");
833
                                "<br>\nWARNING: Wrong number of parameters for "
844
                  freez(cur_acl);
834
                                "deny-access directive in configuration file.<br><br>\n");
845
                  continue;
846
               }
847
            }
835
            }
848
849
            /*
850
             * Add it to the list.  Note we reverse the list to get the
851
             * behaviour the user expects.  With both the ACL and
852
             * actions file, the last match wins.  However, the internal
853
             * implementations are different:  The actions file is stored
854
             * in the same order as the file, and scanned completely.
855
             * With the ACL, we reverse the order as we load it, then
856
             * when we scan it we stop as soon as we get a match.
857
             */
858
            cur_acl->next  = config->acl;
859
            config->acl = cur_acl;
860
861
            continue;
836
            continue;
837
862
#endif /* def FEATURE_ACL */
838
#endif /* def FEATURE_ACL */
863
839
864
/* *************************************************************************
840
/* *************************************************************************
Lines 978-993 Link Here
978
954
979
            if (strcmp(p, ".") != 0)
955
            if (strcmp(p, ".") != 0)
980
            {
956
            {
981
               cur_fwd->forward_host = strdup(p);
957
               cur_fwd->forward_malloc = strdup(p);
958
               cur_fwd->forward_family = -1;
982
959
983
               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
960
               parse_pf_ip(cur_fwd->forward_malloc,
984
               {
961
                           &cur_fwd->forward_host,
985
                  *p++ = '\0';
962
                           &cur_fwd->forward_port_str,
986
                  cur_fwd->forward_port = atoi(p);
963
                           &cur_fwd->forward_family);
987
               }
964
               cur_fwd->forward_port = atoi(cur_fwd->forward_port_str);
988
965
989
               if (cur_fwd->forward_port <= 0)
966
               if (cur_fwd->forward_port <= 0)
990
               {
967
               {
968
                  cur_fwd->forward_port_str = "8000";
991
                  cur_fwd->forward_port = 8000;
969
                  cur_fwd->forward_port = 8000;
992
               }
970
               }
993
            }
971
            }
Lines 1041-1055 Link Here
1041
1019
1042
            if (strcmp(p, ".") != 0)
1020
            if (strcmp(p, ".") != 0)
1043
            {
1021
            {
1044
               cur_fwd->gateway_host = strdup(p);
1022
               /* SOCKS is IPv4-specific */
1023
               int pf = PF_INET;
1045
1024
1046
               if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
1025
               cur_fwd->gateway_malloc = strdup(p);
1026
               if (parse_pf_ip(cur_fwd->gateway_malloc,
1027
                               &cur_fwd->gateway_host,
1028
                               &cur_fwd->gateway_port_str,
1029
                               &pf) != 0)
1047
               {
1030
               {
1048
                  *p++ = '\0';
1031
                 log_error(LOG_LEVEL_ERROR, "Could not parse forward-socks4 host: %s",p);
1049
                  cur_fwd->gateway_port = atoi(p);
1032
                 cur_fwd->gateway_host = NULL;
1033
                 cur_fwd->gateway_port_str = NULL;
1034
                 freez(cur_fwd->gateway_malloc);
1035
                 continue;
1050
               }
1036
               }
1037
1038
               cur_fwd->gateway_port = atoi(cur_fwd->gateway_port_str);
1039
1051
               if (cur_fwd->gateway_port <= 0)
1040
               if (cur_fwd->gateway_port <= 0)
1052
               {
1041
               {
1042
                  cur_fwd->gateway_port_str = "1080";
1053
                  cur_fwd->gateway_port = 1080;
1043
                  cur_fwd->gateway_port = 1080;
1054
               }
1044
               }
1055
            }
1045
            }
Lines 1059-1074 Link Here
1059
1049
1060
            if (strcmp(p, ".") != 0)
1050
            if (strcmp(p, ".") != 0)
1061
            {
1051
            {
1062
               cur_fwd->forward_host = strdup(p);
1052
               cur_fwd->forward_malloc = strdup(p);
1053
               cur_fwd->forward_family = -1;
1063
1054
1064
               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
1055
               parse_pf_ip(cur_fwd->forward_malloc,
1056
                           &cur_fwd->forward_host,
1057
                           &cur_fwd->forward_port_str,
1058
                           &cur_fwd->forward_family);
1059
               cur_fwd->forward_port = atoi(cur_fwd->forward_port_str);
1060
1061
               if (cur_fwd->forward_port <= 0)
1065
               {
1062
               {
1066
                  *p++ = '\0';
1063
                  cur_fwd->forward_port_str = "8000";
1067
                  cur_fwd->forward_port = atoi(p);
1064
                  cur_fwd->forward_port = 8000;
1068
               }
1065
               }
1069
1066
1067
               cur_fwd->forward_port = atoi(p);
1068
1070
               if (cur_fwd->forward_port <= 0)
1069
               if (cur_fwd->forward_port <= 0)
1071
               {
1070
               {
1071
                  cur_fwd->forward_port_str = "8000";
1072
                  cur_fwd->forward_port = 8000;
1072
                  cur_fwd->forward_port = 8000;
1073
               }
1073
               }
1074
            }
1074
            }
Lines 1120-1135 Link Here
1120
            /* Parse the SOCKS proxy host[:port] */
1120
            /* Parse the SOCKS proxy host[:port] */
1121
            p = vec[1];
1121
            p = vec[1];
1122
1122
1123
            cur_fwd->gateway_host = strdup(p);
1124
1125
            if (NULL != (p = strchr(cur_fwd->gateway_host, ':')))
1126
            {
1127
               *p++ = '\0';
1128
               cur_fwd->gateway_port = atoi(p);
1129
            }
1130
            if (cur_fwd->gateway_port <= 0)
1131
            {
1123
            {
1132
               cur_fwd->gateway_port = 1080;
1124
               /* SOCKS is IPv4-specific */
1125
               int pf = PF_INET;
1126
1127
               cur_fwd->gateway_malloc = strdup(p);
1128
               if (parse_pf_ip(cur_fwd->gateway_malloc,
1129
                               &cur_fwd->gateway_host,
1130
                               &cur_fwd->gateway_port_str,
1131
                               &pf) != 0)
1132
               {
1133
                 log_error(LOG_LEVEL_ERROR, "Could not parse forward-socks4a host: %s",p);
1134
                 cur_fwd->gateway_host = NULL;
1135
                 cur_fwd->gateway_port_str = NULL;
1136
                 freez(cur_fwd->gateway_malloc);
1137
                 continue;
1138
               }
1139
1140
               cur_fwd->gateway_port = atoi(cur_fwd->gateway_port_str);
1141
1142
               if (cur_fwd->gateway_port <= 0)
1143
               {
1144
                  cur_fwd->gateway_port_str = "1080";
1145
                  cur_fwd->gateway_port = 1080;
1146
               }
1133
            }
1147
            }
1134
1148
1135
            /* Parse the parent HTTP proxy host[:port] */
1149
            /* Parse the parent HTTP proxy host[:port] */
Lines 1137-1152 Link Here
1137
1151
1138
            if (strcmp(p, ".") != 0)
1152
            if (strcmp(p, ".") != 0)
1139
            {
1153
            {
1140
               cur_fwd->forward_host = strdup(p);
1154
               cur_fwd->forward_malloc = strdup(p);
1155
               cur_fwd->forward_family = -1;
1141
1156
1142
               if (NULL != (p = strchr(cur_fwd->forward_host, ':')))
1157
               parse_pf_ip(cur_fwd->forward_malloc,
1158
                           &cur_fwd->forward_host,
1159
                           &cur_fwd->forward_port_str,
1160
                           &cur_fwd->forward_family);
1161
               cur_fwd->forward_port = atoi(cur_fwd->forward_port_str);
1162
1163
               if (cur_fwd->forward_port <= 0)
1143
               {
1164
               {
1144
                  *p++ = '\0';
1165
                  cur_fwd->forward_port_str = "8000";
1145
                  cur_fwd->forward_port = atoi(p);
1166
                  cur_fwd->forward_port = 8000;
1146
               }
1167
               }
1147
1168
1169
               cur_fwd->forward_port = atoi(p);
1170
1148
               if (cur_fwd->forward_port <= 0)
1171
               if (cur_fwd->forward_port <= 0)
1149
               {
1172
               {
1173
                  cur_fwd->forward_port_str = "8000";
1150
                  cur_fwd->forward_port = 8000;
1174
                  cur_fwd->forward_port = 8000;
1151
               }
1175
               }
1152
            }
1176
            }
Lines 1179-1188 Link Here
1179
 * listen-address [ip][:port]
1203
 * listen-address [ip][:port]
1180
 * *************************************************************************/
1204
 * *************************************************************************/
1181
         case hash_listen_address :
1205
         case hash_listen_address :
1182
            freez(config->haddr);
1206
         {
1183
            config->haddr = strdup(arg);
1207
            struct bind_spec *bs;
1208
            char *arg_cpy;
1209
            if (config->hspecs == NULL)
1210
            {
1211
               /* This is the first we'll bind to */
1212
               config->hspecs = calloc(2,sizeof(struct bind_spec));
1213
               if (config->hspecs == NULL)
1214
                  fail_load_config_memory(fs,config);
1215
               config->hspecs_size = 2;
1216
               config->hspecs_occupied = 0;
1217
            }
1218
            
1219
            arg_cpy = strdup(arg);
1220
            if (arg_cpy == NULL)
1221
               fail_load_config_memory(fs,config);
1222
            if (config->hspecs_occupied == config->hspecs_size)
1223
              {
1224
                struct bind_spec *new_hspecs;
1225
                config->hspecs_size *= 2;
1226
                new_hspecs = realloc(config->hspecs,config->hspecs_size * sizeof(struct bind_spec));
1227
                if (new_hspecs == NULL)
1228
                  {
1229
                    /* Not enough memory to continue. Cancel changes. */
1230
                    config->hspecs_size /= 2;
1231
                    fail_load_config_memory(fs,config);
1232
                  }
1233
                config->hspecs = new_hspecs;
1234
              }
1235
            bs = &config->hspecs[(config->hspecs_occupied)++];
1236
            bs->pf = -1;
1237
            parse_pf_ip(arg,&bs->haddr,&bs->hport,&bs->pf);
1238
            if (*bs->haddr == '\0')
1239
            {
1240
               bs->haddr = NULL;
1241
            }
1242
            else
1243
            {
1244
               (bs->haddr = strdup(bs->haddr));
1245
            }
1246
            bs->hport = strdup(bs->hport);
1184
            continue;
1247
            continue;
1185
1248
         }
1186
/* *************************************************************************
1249
/* *************************************************************************
1187
 * logdir directory-name
1250
 * logdir directory-name
1188
 * *************************************************************************/
1251
 * *************************************************************************/
Lines 1205-1279 Link Here
1205
 * *************************************************************************/
1268
 * *************************************************************************/
1206
#ifdef FEATURE_ACL
1269
#ifdef FEATURE_ACL
1207
         case hash_permit_access:
1270
         case hash_permit_access:
1208
            vec_count = ssplit(arg, " \t", vec, SZ(vec), 1, 1);
1271
            switch (ssplit(arg, " \t", vec, SZ(vec), 1, 1))
1209
1210
            if ((vec_count != 1) && (vec_count != 2))
1211
            {
1212
               log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
1213
                     "permit-access directive in configuration file.");
1214
               string_append(&config->proxy_args,
1215
                  "<br>\nWARNING: Wrong number of parameters for "
1216
                  "permit-access directive in configuration file.<br><br>\n");
1217
1218
               continue;
1219
            }
1220
1221
            /* allocate a new node */
1222
            cur_acl = (struct access_control_list *) zalloc(sizeof(*cur_acl));
1223
1224
            if (cur_acl == NULL)
1225
            {
1226
               log_error(LOG_LEVEL_FATAL, "can't allocate memory for configuration");
1227
               /* Never get here - LOG_LEVEL_FATAL causes program exit */
1228
               continue;
1229
            }
1230
            cur_acl->action = ACL_PERMIT;
1231
1232
            if (acl_addr(vec[0], cur_acl->src) < 0)
1233
            {
1234
               log_error(LOG_LEVEL_ERROR, "Invalid source IP for permit-access "
1235
                     "directive in configuration file: \"%s\"", vec[0]);
1236
               string_append(&config->proxy_args,
1237
                  "<br>\nWARNING: Invalid source IP for permit-access directive"
1238
                  " in configuration file: \"");
1239
               string_append(&config->proxy_args,
1240
                  vec[0]);
1241
               string_append(&config->proxy_args,
1242
                  "\"<br><br>\n");
1243
               freez(cur_acl);
1244
               continue;
1245
            }
1246
            if (vec_count == 2)
1247
            {
1272
            {
1248
               if (acl_addr(vec[1], cur_acl->dst) < 0)
1273
               case 1:
1249
               {
1274
                  config->acl = add_to_acl_list(config->acl, ACL_PERMIT, vec[0], NULL, &config->proxy_args);
1250
                  log_error(LOG_LEVEL_ERROR, "Invalid destination IP for "
1275
                  break;
1251
                        "permit-access directive in configuration file: \"%s\"",
1276
               case 2:
1252
                        vec[0]);
1277
                  config->acl = add_to_acl_list(config->acl, ACL_PERMIT, vec[0], vec[1], &config->proxy_args);
1253
                  string_append(&config->proxy_args,
1278
                  break;
1254
                     "<br>\nWARNING: Invalid destination IP for permit-access directive"
1279
               default:
1255
                     " in configuration file: \"");
1280
                  log_error(LOG_LEVEL_ERROR, "Wrong number of parameters for "
1256
                  string_append(&config->proxy_args,
1281
                            "permit-access directive in configuration file.");
1257
                     vec[0]);
1258
                  string_append(&config->proxy_args,
1282
                  string_append(&config->proxy_args,
1259
                     "\"<br><br>\n");
1283
                                "<br>\nWARNING: Wrong number of parameters for "
1260
                  freez(cur_acl);
1284
                                "permit-access directive in configuration file.<br><br>\n");
1261
                  continue;
1262
               }
1263
            }
1285
            }
1264
1265
            /*
1266
             * Add it to the list.  Note we reverse the list to get the
1267
             * behaviour the user expects.  With both the ACL and
1268
             * actions file, the last match wins.  However, the internal
1269
             * implementations are different:  The actions file is stored
1270
             * in the same order as the file, and scanned completely.
1271
             * With the ACL, we reverse the order as we load it, then
1272
             * when we scan it we stop as soon as we get a match.
1273
             */
1274
            cur_acl->next  = config->acl;
1275
            config->acl = cur_acl;
1276
1277
            continue;
1286
            continue;
1278
#endif /* def FEATURE_ACL */
1287
#endif /* def FEATURE_ACL */
1279
1288
Lines 1513-1544 Link Here
1513
   }
1522
   }
1514
#endif /* def FEATURE_COOKIE_JAR */
1523
#endif /* def FEATURE_COOKIE_JAR */
1515
1524
1516
   if ( NULL == config->haddr )
1525
   if ( config->hspecs == NULL )
1517
   {
1518
      config->haddr = strdup( HADDR_DEFAULT );
1519
   }
1520
1521
   if ( NULL != config->haddr )
1522
   {
1526
   {
1523
      if (NULL != (p = strchr(config->haddr, ':')))
1527
      /* No listen-address set. The default is localhost on port 8118, on IPv4
1524
      {
1528
         and (if INET6 is defined) IPv6.
1525
         *p++ = '\0';
1529
       */
1526
         if (*p)
1530
      struct bind_spec *bs;
1527
         {
1531
#ifdef INET6
1528
            config->hport = atoi(p);
1532
      config->hspecs = calloc(2,sizeof(struct bind_spec));
1529
         }
1533
      if (config->hspecs == NULL)
1530
      }
1534
         fail_load_config_memory(fs,config);
1531
1535
      config->hspecs_size=2;
1532
      if (config->hport <= 0)
1536
      config->hspecs_occupied=1;
1533
      {
1537
      bs = &config->hspecs[0];
1534
         *--p = ':';
1538
      bs->haddr = strdup("::1");
1535
         log_error(LOG_LEVEL_FATAL, "invalid bind port spec %s", config->haddr);
1539
      bs->hport = strdup("8118");
1536
         /* Never get here - LOG_LEVEL_FATAL causes program exit */
1540
      bs->pf = PF_UNSPEC;
1537
      }
1541
#else
1538
      if (*config->haddr == '\0')
1542
      config->hspecs = calloc(1,sizeof(struct bind_spec));
1539
      {
1543
      if (config->hspecs == NULL)
1540
         config->haddr = NULL;
1544
         fail_load_config_memory(fs,config);
1541
      }
1545
      config->hspecs_size=1;
1546
      config->hspecs_occupied=0;
1547
#endif
1548
      bs = &config->hspecs[config->hspecs_occupied++];
1549
      bs->haddr = strdup("127.0.0.1");
1550
      bs->hport = strdup("8118");
1551
      bs->pf = PF_UNSPEC;
1542
   }
1552
   }
1543
1553
1544
   /*
1554
   /*
Lines 1580-1610 Link Here
1580
      struct configuration_spec * oldcfg = (struct configuration_spec *)
1590
      struct configuration_spec * oldcfg = (struct configuration_spec *)
1581
                                           current_configfile->f;
1591
                                           current_configfile->f;
1582
      /*
1592
      /*
1583
       * Check if config->haddr,hport == oldcfg->haddr,hport
1593
       * Check if the listening addresses have changed
1584
       *
1585
       * The following could be written more compactly as a single,
1586
       * (unreadably long) if statement.
1587
       */
1594
       */
1588
      config->need_bind = 0;
1595
      config->need_bind = 0;
1589
      if (config->hport != oldcfg->hport)
1596
      if (config -> hspecs_occupied == oldcfg -> hspecs_occupied)
1590
      {
1591
         config->need_bind = 1;
1592
      }
1593
      else if (config->haddr == NULL)
1594
      {
1597
      {
1595
         if (oldcfg->haddr != NULL)
1598
         int bs_index;
1599
         struct bind_spec *hspec;
1600
         struct bind_spec *oldhspec;
1601
         hspec = config -> hspecs;
1602
         oldhspec = oldcfg -> hspecs;
1603
         for(bs_index = 0; bs_index < oldcfg->hspecs_occupied; ++bs_index)
1596
         {
1604
         {
1597
            config->need_bind = 1;
1605
           if (strcmp(hspec[bs_index].haddr,oldhspec[bs_index].haddr) != 0
1606
               || strcmp(hspec[bs_index].hport,oldhspec[bs_index].hport) != 0
1607
               || hspec[bs_index].pf != hspec[bs_index].pf)
1608
           {
1609
              config -> need_bind = 1;
1610
              break;
1611
           }
1598
         }
1612
         }
1599
      }
1613
      }
1600
      else if (oldcfg->haddr == NULL)
1614
      else
1601
      {
1615
         config-> need_bind = 1;
1602
         config->need_bind = 1;
1603
      }
1604
      else if (0 != strcmp(config->haddr, oldcfg->haddr))
1605
      {
1606
         config->need_bind = 1;
1607
      }
1608
1616
1609
      current_configfile->unloader = unload_configfile;
1617
      current_configfile->unloader = unload_configfile;
1610
   }
1618
   }
(-)privoxy~/loaders.c (+4 lines)
Lines 11-16 Link Here
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
12
 *                Privoxy team. http://www.privoxy.org/
12
 *                Privoxy team. http://www.privoxy.org/
13
 *
13
 *
14
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
15
 *                for IPv6 support on 8 December 2002, 24 January 2003.
16
 *
14
 *                Based on the Internet Junkbuster originally written
17
 *                Based on the Internet Junkbuster originally written
15
 *                by and Copyright (C) 1997 Anonymous Coders and
18
 *                by and Copyright (C) 1997 Anonymous Coders and
16
 *                Junkbusters Corporation.  http://www.junkbusters.com
19
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 465-470 Link Here
465
468
466
         freez(csp->ip_addr_str);
469
         freez(csp->ip_addr_str);
467
         freez(csp->my_ip_addr_str);
470
         freez(csp->my_ip_addr_str);
471
         freez(csp->my_port_str);
468
         freez(csp->my_hostname);
472
         freez(csp->my_hostname);
469
         freez(csp->x_forwarded);
473
         freez(csp->x_forwarded);
470
         freez(csp->iob->buf);
474
         freez(csp->iob->buf);
(-)privoxy~/miscutil.h (+9 lines)
Lines 162-167 Link Here
162
162
163
#include "project.h"
163
#include "project.h"
164
164
165
/* Fix a problem with Solaris.  There should be no effect on other
166
 * platforms.
167
 * Solaris's isspace() is a macro which uses it's argument directly
168
 * as an array index.  Therefore we need to make sure that high-bit
169
 * characters generate +ve values, and ideally we also want to make
170
 * the argument match the declared parameter type of "int".
171
 */
172
#define ijb_isdigit(__X) isdigit((int)(unsigned char)(__X))
173
165
#if defined(__cplusplus)
174
#if defined(__cplusplus)
166
extern "C" {
175
extern "C" {
167
#endif
176
#endif
(-)privoxy~/parsers.c (+164 lines)
Lines 16-21 Link Here
16
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
16
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
17
 *                Privoxy team. http://www.privoxy.org/
17
 *                Privoxy team. http://www.privoxy.org/
18
 *
18
 *
19
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
20
 *                for IPv6 support on 24 January 2003.
21
 *
19
 *                Based on the Internet Junkbuster originally written
22
 *                Based on the Internet Junkbuster originally written
20
 *                by and Copyright (C) 1997 Anonymous Coders and
23
 *                by and Copyright (C) 1997 Anonymous Coders and
21
 *                Junkbusters Corporation.  http://www.junkbusters.com
24
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 1938-1943 Link Here
1938
   return JB_ERR_OK;
1941
   return JB_ERR_OK;
1939
}
1942
}
1940
1943
1944
/*********************************************************************
1945
 *
1946
 * Function    :  parse_pf_ip_netmask
1947
 *
1948
 * Description :  Parse an IPv{4,6} litteral or hostname
1949
 *                with optional port and optional explicit family
1950
 *                and optional netmask
1951
 *
1952
 * Parameters  :
1953
 *          0  :  string = the string to parse
1954
 *          1  :  host = Is set to point to the hostname or IP literal
1955
 *                       part
1956
 *          2  :  port = Is set to point to the port part,
1957
 *                       or NULL if no port in string
1958
 *          3  :  pf = pointer used to return the address family
1959
 *                     pf is a value-result argument:
1960
 *                     If it is set to -1, then parse_pf_ip will set it
1961
 *                      to the address family of the pf_ip string
1962
 *                     else, it won't touch it, and fail if the two
1963
 *                      cannot match
1964
 *          4  :  pointer used to return the mask length
1965
 *                Set to -1 if no mask
1966
 *
1967
 * Returns     :  0 on success
1968
 *
1969
 *********************************************************************/
1970
int parse_pf_ip_netmask(char *string, char **host, char **port, int *pf, int *masklength)
1971
{
1972
   int i;
1973
   char *p;
1974
1975
   *masklength = -1;
1976
1977
   if ((p = strchr(string, '/')) != NULL)
1978
   {
1979
      *p++ = '\0';
1980
1981
      if (ijb_isdigit(*p) == 0)
1982
      {
1983
         return -1;
1984
      }
1985
      i = atoi(p);
1986
      if ( i < 0 )
1987
         return -1;
1988
      *masklength = i;
1989
   }
1990
1991
   return parse_pf_ip(string, host, port, pf);
1992
}
1993
1994
/*********************************************************************
1995
 *
1996
 * Function    :  parse_pf_ip
1997
 *
1998
 * Description :  Parse an IPv{4,6} litteral or hostname
1999
 *                with optional port and optional explicit family
2000
 *
2001
 * Parameters  :
2002
 *          0  :  string = the string to parse
2003
 *          1  :  host = Is set to point to the hostname or IP literal
2004
 *                       part
2005
 *          2  :  port = Is set to point to the port part,
2006
 *                       or NULL if no port in string
2007
 *          3  :  pf = pointer used to return the address family
2008
 *                     pf is a value-result argument:
2009
 *                     If it is set to -1, then parse_pf_ip will set it
2010
 *                      to the address family of the pf_ip string
2011
 *                     else, it won't touch it, and fail if the two
2012
 *                      cannot match
2013
 *
2014
 * Returns     :  0 on success
2015
 *
2016
 *********************************************************************/
2017
int parse_pf_ip(char *string, char **host, char **port, int *pf)
2018
{
2019
   if (pf != NULL && *pf == -1)
2020
      *pf = PF_UNSPEC;
2021
2022
   /* See if we want to override the default protocol family */
2023
   if (strncmpic(string, "ipv4:", 5) == 0)
2024
   {
2025
      string += 5;
2026
      if (pf!=NULL)
2027
      {
2028
         if(*pf==PF_INET || *pf==PF_UNSPEC)
2029
            *pf = AF_INET;
2030
         else
2031
         {
2032
            log_error(LOG_LEVEL_ERROR,"%s","IPv4 address found where other awaited");
2033
            return -2;
2034
         }
2035
      }
2036
   }
2037
   else if (strncmpic(string, "ipv6:", 5) == 0)
2038
   {
2039
#ifdef INET6
2040
      string += 5;
2041
      if(*pf==PF_INET6 || *pf==PF_UNSPEC)
2042
         *pf = AF_INET6;
2043
      else
2044
      {
2045
        log_error(LOG_LEVEL_ERROR,"%s","IPv6 address found where other awaited");
2046
        return -2;
2047
      }
2048
#else
2049
      log_error(LOG_LEVEL_ERROR,"%s","This privoxy hasn't IPv6 support");
2050
      return -1;
2051
#endif
2052
   }
2053
   return parse_ip(string, host, port);
2054
}
2055
2056
/*********************************************************************
2057
 *
2058
 * Function    :  parse_ip
2059
 *
2060
 * Description :  Parse an IPv{4,6} litteral or hostname
2061
 *                with optional port
2062
 *
2063
 * Parameters  :
2064
 *          0  :  string = the string to parse
2065
 *          1  :  host = Is set to point to the hostname or IP literal
2066
 *                       part
2067
 *          2  :  port = Is set to point to the port part,
2068
 *                       or NULL if no port in string
2069
 * Returns     :  0 on success
2070
 *
2071
 *********************************************************************/
2072
int parse_ip(char *string, char **host, char **port)
2073
{
2074
   char *p;
2075
   int skip;
2076
2077
   /* allow IPv6 address literal: [numbers:with:colons]:port/mask */
2078
   if (string[0] == '[' && (p = strchr(string, ']')))
2079
   {
2080
      *p++ = '\0';
2081
      skip = 1;
2082
   }
2083
   else
2084
   {
2085
      p = string;
2086
      skip = 0;
2087
   }
2088
2089
   if (host != NULL)
2090
      *host = string + skip;
2091
2092
   for(;*p != '\0'; ++p)
2093
   {
2094
      if (*p == ':')
2095
      {
2096
         *p++ = '\0';
2097
         break;
2098
      }
2099
   }
2100
   if (port != NULL)
2101
      *port = p;
2102
   return 0;
2103
}
2104
1941
2105
1942
/*********************************************************************
2106
/*********************************************************************
1943
 *
2107
 *
(-)privoxy~/parsers.h (+7 lines)
Lines 19-24 Link Here
19
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
19
 * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
20
 *                Privoxy team. http://www.privoxy.org/
20
 *                Privoxy team. http://www.privoxy.org/
21
 *
21
 *
22
 *                Modified by Lionel Elie Mamane <lionel@mamane.lu>
23
 *                for IPv6 support on 24 January 2003.
24
 *
22
 *                Based on the Internet Junkbuster originally written
25
 *                Based on the Internet Junkbuster originally written
23
 *                by and Copyright (C) 1997 Anonymous Coders and 
26
 *                by and Copyright (C) 1997 Anonymous Coders and 
24
 *                Junkbusters Corporation.  http://www.junkbusters.com
27
 *                Junkbusters Corporation.  http://www.junkbusters.com
Lines 270-275 Link Here
270
extern jb_err server_last_modified   (struct client_state *csp, char **header);
273
extern jb_err server_last_modified   (struct client_state *csp, char **header);
271
extern jb_err server_content_disposition(struct client_state *csp, char **header);
274
extern jb_err server_content_disposition(struct client_state *csp, char **header);
272
275
276
extern int parse_pf_ip_netmask(char *string, char **host, char **port, int *pf, int *masklength);
277
extern int parse_pf_ip(char *string, char ** host, char ** port, int *pf);
278
extern int parse_ip(char *string, char ** host, char** port);
279
273
#ifdef FEATURE_FORCE_LOAD
280
#ifdef FEATURE_FORCE_LOAD
274
extern int strclean(const char *string, const char *substring);
281
extern int strclean(const char *string, const char *substring);
275
#endif /* def FEATURE_FORCE_LOAD */
282
#endif /* def FEATURE_FORCE_LOAD */
(-)privoxy~/project.h (-23 / +59 lines)
Lines 607-612 Link Here
607
607
608
#endif /* ndef _WIN32 */
608
#endif /* ndef _WIN32 */
609
609
610
#include "jb_socket_set.h"
611
612
#ifdef INET6
613
/**
614
 * Get from the operating system structures big enough
615
 * to put a network address in, namely sockaddr_storage
616
 */
617
#include <sys/socket.h> 
618
/**
619
 * If no IPv6 support, just use the old sockaddr
620
 */
621
#else
622
#define sockaddr_storage   sockaddr
623
#endif
610
624
611
/**
625
/**
612
 * A standard error code.  This should be JB_ERR_OK or one of the JB_ERR_xxx
626
 * A standard error code.  This should be JB_ERR_OK or one of the JB_ERR_xxx
Lines 681-699 Link Here
681
 */
695
 */
682
#define FOREVER 1
696
#define FOREVER 1
683
697
684
/**
685
 * Default IP address to listen on, as a string.
686
 * Set to "127.0.0.1".
687
 */
688
#define HADDR_DEFAULT   "127.0.0.1"
689
690
/**
691
 * Default port to listen on, as a number.
692
 * Set to 8118.
693
 */
694
#define HADDR_PORT      8118
695
696
697
/* Forward def for struct client_state */
698
/* Forward def for struct client_state */
698
struct configuration_spec;
699
struct configuration_spec;
699
700
Lines 772-784 Link Here
772
   char *ver;      /**< Protocol version */
773
   char *ver;      /**< Protocol version */
773
   int status;     /**< HTTP Status */
774
   int status;     /**< HTTP Status */
774
775
776
   char *host_port_malloc;     /**< malloc used for place wher host and port_str are */
775
   char *host;     /**< Host part of URL */
777
   char *host;     /**< Host part of URL */
776
   int   port;     /**< Port of URL or 80 (default) */
778
   int   port;     /**< Port of URL or 80 (default) */
779
   char *port_str; /**< Port of URL, as string */
777
   char *path;     /**< Path of URL */
780
   char *path;     /**< Path of URL */
778
   char *hostport; /**< host[:port] */
781
   char *hostport; /**< host[:port] */
779
   int   ssl;      /**< Flag if protocol is https */
782
   int   ssl;      /**< Flag if protocol is https */
780
783
781
   char *host_ip_addr_str; /**< String with dotted decimal representation
784
   char *host_ip_addr_str; /**< String with dotted decimal representation (IPv4)
785
                                or hexadecimal colon-separated (IPv6)
782
                                of host's IP. NULL before connect_to() */
786
                                of host's IP. NULL before connect_to() */
783
787
784
   char  *dbuffer; /**< Buffer with '\0'-delimited domain name.           */
788
   char  *dbuffer; /**< Buffer with '\0'-delimited domain name.           */
Lines 1158-1170 Link Here
1158
       As a string. */
1162
       As a string. */
1159
   char *ip_addr_str;
1163
   char *ip_addr_str;
1160
   /** Client PC's IP address, as reported by the accept() function.
1164
   /** Client PC's IP address, as reported by the accept() function.
1161
       As a number. */
1165
       As an address. */
1162
   long  ip_addr_long;
1166
   struct sockaddr_storage ip_addr_addr;
1163
1167
1164
   /** Our IP address. I.e. the IP address that the client used to reach us,
1168
   /** Our IP address. I.e. the IP address that the client used to reach us,
1165
       as a string. */
1169
       as a string. */
1166
   char *my_ip_addr_str;
1170
   char *my_ip_addr_str;
1167
1171
1172
   /** Our  port. I.e. the port the client used to reach us */
1173
   char *my_port_str;
1174
1168
   /** Our hostname. I.e. the reverse DNS of the IP address that the client
1175
   /** Our hostname. I.e. the reverse DNS of the IP address that the client
1169
       used to reach us, as a string. */
1176
       used to reach us, as a string. */
1170
   char *my_hostname;
1177
   char *my_hostname;
Lines 1339-1356 Link Here
1339
   /** Connection type.  Must be SOCKS_NONE, SOCKS_4, or SOCKS_4A. */
1346
   /** Connection type.  Must be SOCKS_NONE, SOCKS_4, or SOCKS_4A. */
1340
   int   type;
1347
   int   type;
1341
1348
1349
   /** pointer returned by the malloc used for gateway_host and gateway_port_str */
1350
   char *gateway_malloc;
1351
1342
   /** SOCKS server hostname.  Only valid if "type" is SOCKS_4 or SOCKS_4A. */
1352
   /** SOCKS server hostname.  Only valid if "type" is SOCKS_4 or SOCKS_4A. */
1343
   char *gateway_host;
1353
   char *gateway_host;
1344
1354
1345
   /** SOCKS server port. */
1355
   /** SOCKS server port. */
1346
   int   gateway_port;
1356
   int   gateway_port;
1347
1357
1358
   /** SOCKS server port, as string. */
1359
   char *gateway_port_str;
1360
1361
   /** pointer returned by the malloc used for forward_host and forward_port_str */
1362
   char *forward_malloc;
1363
1364
   /** Parent HTTP proxy address family. */
1365
   int forward_family;
1366
1348
   /** Parent HTTP proxy hostname, or NULL for none. */
1367
   /** Parent HTTP proxy hostname, or NULL for none. */
1349
   char *forward_host;
1368
   char *forward_host;
1350
1369
1351
   /** Parent HTTP proxy port. */
1370
   /** Parent HTTP proxy port. */
1352
   int   forward_port;
1371
   int   forward_port;
1353
1372
1373
   /** Parent HTTP proxy port as string. */
1374
   char *forward_port_str;
1375
1354
   /** Next entry in the linked list. */
1376
   /** Next entry in the linked list. */
1355
   struct forward_spec *next;
1377
   struct forward_spec *next;
1356
};
1378
};
Lines 1359-1365 Link Here
1359
/**
1381
/**
1360
 * Initializer for a static struct forward_spec.
1382
 * Initializer for a static struct forward_spec.
1361
 */
1383
 */
1362
#define FORWARD_SPEC_INITIALIZER { { URL_SPEC_INITIALIZER }, 0, NULL, 0, NULL, 0, NULL }
1384
#define FORWARD_SPEC_INITIALIZER { { URL_SPEC_INITIALIZER }, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, 0, NULL, NULL}
1363
1385
1364
1386
1365
/**
1387
/**
Lines 1388-1394 Link Here
1388
 */
1410
 */
1389
struct access_control_addr
1411
struct access_control_addr
1390
{
1412
{
1391
   unsigned long addr;  /**< The IP address as an integer. */
1413
   struct sockaddr_storage addr; /**< The IP address. */
1414
   size_t addrlen;
1392
   unsigned long mask;  /**< The network mask as an integer. */
1415
   unsigned long mask;  /**< The network mask as an integer. */
1393
   unsigned long port;  /**< The port number. */
1416
   unsigned long port;  /**< The port number. */
1394
};
1417
};
Lines 1423-1428 Link Here
1423
/** configuration_spec::feature_flags: HTTP-header-based toggle. */
1446
/** configuration_spec::feature_flags: HTTP-header-based toggle. */
1424
#define RUNTIME_FEATURE_HTTP_TOGGLE       4
1447
#define RUNTIME_FEATURE_HTTP_TOGGLE       4
1425
1448
1449
struct bind_spec
1450
{
1451
   /** IP address to bind to. */
1452
   char *haddr;
1453
1454
   /** Port to bind to. */
1455
   char *hport;
1456
1457
   /** Address family */
1458
   int pf;
1459
};
1426
/**
1460
/**
1427
 * Data loaded from the configuration file.
1461
 * Data loaded from the configuration file.
1428
 *
1462
 *
Lines 1486-1496 Link Here
1486
1520
1487
#endif /* def FEATURE_COOKIE_JAR */
1521
#endif /* def FEATURE_COOKIE_JAR */
1488
1522
1489
   /** IP address to bind to.  Defaults to HADDR_DEFAULT == 127.0.0.1. */
1523
   /* IP addresses and ports to bind to.
1490
   const char *haddr;
1524
       Defaults to HSPECS_DEFAULT == {ipv4:127.0.0.1:8118, ipv6:[::1]:8118}. */
1491
1525
   struct bind_spec *hspecs;
1492
   /** Port to bind to.  Defaults to HADDR_PORT == 8118. */
1526
   /* size allocated */
1493
   int         hport;
1527
   unsigned int hspecs_size;
1528
   /* number of entries */
1529
   unsigned int hspecs_occupied;
1494
1530
1495
   /** Size limit for IOB */
1531
   /** Size limit for IOB */
1496
   size_t buffer_limit;
1532
   size_t buffer_limit;
(-)privoxy~/urlmatch.c (-44 / +39 lines)
Lines 137-142 Link Here
137
#include "ssplit.h"
137
#include "ssplit.h"
138
#include "miscutil.h"
138
#include "miscutil.h"
139
#include "errlog.h"
139
#include "errlog.h"
140
#include "parsers.h"
140
141
141
const char urlmatch_h_rcs[] = URLMATCH_H_VERSION;
142
const char urlmatch_h_rcs[] = URLMATCH_H_VERSION;
142
143
Lines 160-166 Link Here
160
   freez(http->cmd);
161
   freez(http->cmd);
161
   freez(http->ocmd);
162
   freez(http->ocmd);
162
   freez(http->gpc);
163
   freez(http->gpc);
163
   freez(http->host);
164
   freez(http->host_port_malloc);
164
   freez(http->url);
165
   freez(http->url);
165
   freez(http->hostport);
166
   freez(http->hostport);
166
   freez(http->path);
167
   freez(http->path);
Lines 302-309 Link Here
302
    */
303
    */
303
   {
304
   {
304
      char *buf;
305
      char *buf;
305
      char *host;
306
      char *port;
307
306
308
      buf = strdup(http->hostport);
307
      buf = strdup(http->hostport);
309
      if (buf == NULL)
308
      if (buf == NULL)
Lines 311-348 Link Here
311
         return JB_ERR_MEMORY;
310
         return JB_ERR_MEMORY;
312
      }
311
      }
313
312
313
      http->host_port_malloc = buf;
314
314
      /* check if url contains username and/or password */
315
      /* check if url contains username and/or password */
315
      host = strchr(buf, '@');
316
      buf = strchr(buf, '@');
316
      if (host != NULL)
317
      if (buf != NULL)
317
      {
318
      {
318
         /* Contains username/password, skip it and the @ sign. */
319
         /* Contains username/password, skip it and the @ sign. */
319
         host++;
320
         buf++;
320
      }
321
      }
321
      else
322
      else
322
      {
323
      {
323
         /* No username or password. */
324
         /* No username or password. */
324
         host = buf;
325
         buf = http->host_port_malloc;
325
      }
326
      }
326
327
327
      /* check if url contains port */
328
      parse_ip(buf,&http->host,&http->port_str);
328
      port = strchr(host, ':');
329
329
      if (port != NULL)
330
      if (*http->port_str != '\0')
330
      {
331
      {
331
         /* Contains port */
332
         http->port = atoi(http->port_str);
332
         /* Terminate hostname and point to start of port string */
333
         *port++ = '\0';
334
         http->port = atoi(port);
335
      }
333
      }
336
      else
334
      else
337
      {
335
      {
338
         /* No port specified. */
336
         /* No port specified. */
337
         http->port_str = (http->ssl ? "143" : "80");
339
         http->port = (http->ssl ? 443 : 80);
338
         http->port = (http->ssl ? 443 : 80);
340
      }
339
      }
341
340
342
      http->host = strdup(host);
343
344
      free(buf);
345
346
      if (http->host == NULL)
341
      if (http->host == NULL)
347
      {
342
      {
348
         return JB_ERR_MEMORY;
343
         return JB_ERR_MEMORY;
Lines 666-674 Link Here
666
 *                               written to system log)
661
 *                               written to system log)
667
 *
662
 *
668
 *********************************************************************/
663
 *********************************************************************/
669
jb_err create_url_spec(struct url_spec * url, const char * buf)
664
jb_err create_url_spec(struct url_spec * url, char * buf)
670
{
665
{
671
   char *p;
672
666
673
   assert(url);
667
   assert(url);
674
   assert(buf);
668
   assert(buf);
Lines 685-705 Link Here
685
   {
679
   {
686
      return JB_ERR_MEMORY;
680
      return JB_ERR_MEMORY;
687
   }
681
   }
688
689
   if ((p = strchr(buf, '/')) != NULL)
690
   {
682
   {
691
      if (NULL == (url->path = strdup(p)))
683
      char *p;
684
685
      if ((p = strchr(buf, '/')) != NULL)
692
      {
686
      {
693
         freez(url->spec);
687
         if (NULL == (url->path = strdup(p)))
694
         return JB_ERR_MEMORY;
688
         {
689
            freez(url->spec);
690
            return JB_ERR_MEMORY;
691
         }
692
         url->pathlen = strlen(url->path);
693
         *p = '\0';
694
      }
695
      else
696
      {
697
         url->path    = NULL;
698
         url->pathlen = 0;
695
      }
699
      }
696
      url->pathlen = strlen(url->path);
697
      *p = '\0';
698
   }
699
   else
700
   {
701
      url->path    = NULL;
702
      url->pathlen = 0;
703
   }
700
   }
704
   if (url->path)
701
   if (url->path)
705
   {
702
   {
Lines 739-752 Link Here
739
         return JB_ERR_PARSE;
736
         return JB_ERR_PARSE;
740
      }
737
      }
741
   }
738
   }
742
   if ((p = strchr(buf, ':')) == NULL)
739
743
   {
744
      url->port = 0;
745
   }
746
   else
747
   {
740
   {
748
      *p++ = '\0';
741
     char *p;
749
      url->port = atoi(p);
742
     parse_ip(buf,&buf,&p);
743
     url->port = atoi(p);
750
   }
744
   }
751
745
752
   if (buf[0] != '\0')
746
   if (buf[0] != '\0')
Lines 779-790 Link Here
779
         return JB_ERR_MEMORY;
773
         return JB_ERR_MEMORY;
780
      }
774
      }
781
775
782
      /* 
783
       * Map to lower case
784
       */
785
      for (p = url->dbuffer; *p ; p++)
786
      {
776
      {
787
         *p = tolower((int)(unsigned char)*p);
777
         char* p;
778
         /* map to lower case */
779
         for (p = url->dbuffer; *p ; p++)
780
         {
781
            *p = tolower((int)(unsigned char)*p);
782
         }
788
      }
783
      }
789
784
790
      /* 
785
      /* 
(-)privoxy~/urlmatch.h (-1 / +1 lines)
Lines 83-89 Link Here
83
extern int url_match(const struct url_spec *pattern,
83
extern int url_match(const struct url_spec *pattern,
84
                     const struct http_request *url);
84
                     const struct http_request *url);
85
85
86
extern jb_err create_url_spec(struct url_spec * url, const char * buf);
86
extern jb_err create_url_spec(struct url_spec * url, char * buf);
87
extern void free_url_spec(struct url_spec *url);
87
extern void free_url_spec(struct url_spec *url);
88
88
89
89

Return to bug 160203