LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - httpd_policy.h
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 315
Code covered: 85.4 % Executed lines: 269

       1                 : #ifndef HTTPD_POLICY_H
       2                 : #define HTTPD_POLICY_H
       3                 : 
       4                 : #include "opt_policy.h"
       5                 : 
       6                 : #define HTTPD_POLICY__PATH_LIM_FULL 0
       7                 : #define HTTPD_POLICY__PATH_LIM_BEG  1
       8                 : #define HTTPD_POLICY__PATH_LIM_END  2
       9                 : #define HTTPD_POLICY__PATH_LIM_EQ   3
      10                 : #define HTTPD_POLICY__PATH_LIM_MASK 3
      11                 : #define HTTPD_POLICY_PATH_LIM_NONE       0
      12                 : #define HTTPD_POLICY_PATH_LIM_PATH_FULL (0x4  | HTTPD_POLICY__PATH_LIM_FULL)
      13                 : #define HTTPD_POLICY_PATH_LIM_PATH_BEG  (0x4  | HTTPD_POLICY__PATH_LIM_BEG)
      14                 : #define HTTPD_POLICY_PATH_LIM_PATH_END  (0x4  | HTTPD_POLICY__PATH_LIM_END)
      15                 : #define HTTPD_POLICY_PATH_LIM_PATH_EQ   (0x4  | HTTPD_POLICY__PATH_LIM_EQ)
      16                 : #define HTTPD_POLICY_PATH_LIM_NAME_FULL (0x8  | HTTPD_POLICY__PATH_LIM_FULL)
      17                 : #define HTTPD_POLICY_PATH_LIM_NAME_BEG  (0x8  | HTTPD_POLICY__PATH_LIM_BEG)
      18                 : #define HTTPD_POLICY_PATH_LIM_NAME_END  (0x8  | HTTPD_POLICY__PATH_LIM_END)
      19                 : #define HTTPD_POLICY_PATH_LIM_NAME_EQ   (0x8  | HTTPD_POLICY__PATH_LIM_EQ)
      20                 : #define HTTPD_POLICY_PATH_LIM_EXTN_FULL (0xc  | HTTPD_POLICY__PATH_LIM_FULL)
      21                 : #define HTTPD_POLICY_PATH_LIM_EXTN_BEG  (0xc  | HTTPD_POLICY__PATH_LIM_BEG)
      22                 : #define HTTPD_POLICY_PATH_LIM_EXTN_END  (0xc  | HTTPD_POLICY__PATH_LIM_END)
      23                 : #define HTTPD_POLICY_PATH_LIM_EXTN_EQ   (0xc  | HTTPD_POLICY__PATH_LIM_EQ)
      24                 : #define HTTPD_POLICY_PATH_LIM_EXTS_FULL (0x14 | HTTPD_POLICY__PATH_LIM_FULL)
      25                 : #define HTTPD_POLICY_PATH_LIM_EXTS_BEG  (0x14 | HTTPD_POLICY__PATH_LIM_BEG)
      26                 : #define HTTPD_POLICY_PATH_LIM_EXTS_END  (0x14 | HTTPD_POLICY__PATH_LIM_END)
      27                 : #define HTTPD_POLICY_PATH_LIM_EXTS_EQ   (0x14 | HTTPD_POLICY__PATH_LIM_EQ)
      28                 : #define HTTPD_POLICY_PATH_LIM_BWEN_FULL (0x18 | HTTPD_POLICY__PATH_LIM_FULL)
      29                 : #define HTTPD_POLICY_PATH_LIM_BWEN_BEG  (0x18 | HTTPD_POLICY__PATH_LIM_BEG)
      30                 : #define HTTPD_POLICY_PATH_LIM_BWEN_END  (0x18 | HTTPD_POLICY__PATH_LIM_END)
      31                 : #define HTTPD_POLICY_PATH_LIM_BWEN_EQ   (0x18 | HTTPD_POLICY__PATH_LIM_EQ)
      32                 : #define HTTPD_POLICY_PATH_LIM_BWES_FULL (0x1c | HTTPD_POLICY__PATH_LIM_FULL)
      33                 : #define HTTPD_POLICY_PATH_LIM_BWES_BEG  (0x1c | HTTPD_POLICY__PATH_LIM_BEG)
      34                 : #define HTTPD_POLICY_PATH_LIM_BWES_END  (0x1c | HTTPD_POLICY__PATH_LIM_END)
      35                 : #define HTTPD_POLICY_PATH_LIM_BWES_EQ   (0x1c | HTTPD_POLICY__PATH_LIM_EQ)
      36                 : 
      37                 : /* choosing (1024) as a offset ... kinda hackyish */
      38                 : #define HTTPD_POLICY_REQ_PATH_BEG (1024 +  0)
      39                 : #define HTTPD_POLICY_REQ_PATH_END (1024 +  1)
      40                 : #define HTTPD_POLICY_REQ_PATH_EQ  (1024 +  2)
      41                 : #define HTTPD_POLICY_REQ_NAME_BEG (1024 +  3)
      42                 : #define HTTPD_POLICY_REQ_NAME_END (1024 +  4)
      43                 : #define HTTPD_POLICY_REQ_NAME_EQ  (1024 +  5)
      44                 : #define HTTPD_POLICY_REQ_BWEN_BEG (1024 +  6)
      45                 : #define HTTPD_POLICY_REQ_BWEN_END (1024 +  7)
      46                 : #define HTTPD_POLICY_REQ_BWEN_EQ  (1024 +  8)
      47                 : #define HTTPD_POLICY_REQ_BWES_BEG (1024 +  9)
      48                 : #define HTTPD_POLICY_REQ_BWES_END (1024 + 10)
      49                 : #define HTTPD_POLICY_REQ_BWES_EQ  (1024 + 11)
      50                 : #define HTTPD_POLICY_REQ_EXTN_BEG (1024 + 12)
      51                 : #define HTTPD_POLICY_REQ_EXTN_END (1024 + 13)
      52                 : #define HTTPD_POLICY_REQ_EXTN_EQ  (1024 + 14)
      53                 : #define HTTPD_POLICY_REQ_EXTS_BEG (1024 + 15)
      54                 : #define HTTPD_POLICY_REQ_EXTS_END (1024 + 16)
      55                 : #define HTTPD_POLICY_REQ_EXTS_EQ  (1024 + 17)
      56                 : 
      57                 : typedef struct Httpd_policy_path
      58                 : {
      59                 :  Vstr_base *s1;
      60                 :  void (*ref_func)(Vstr_ref *);
      61                 : } Httpd_policy_path;
      62                 : 
      63                 : extern void httpd_policy_change_con(struct Con *, const Httpd_policy_opts *);
      64                 : extern void httpd_policy_change_req(struct Con *, Httpd_req_data *,
      65                 :                                     const Httpd_policy_opts *);
      66                 :    
      67                 : extern int httpd_policy_build_path(struct Con *, Httpd_req_data *,
      68                 :                                    const Conf_parse *, Conf_token *,
      69                 :                                    int *, int *);
      70                 : extern int httpd_policy_path_make(struct Con *con, Httpd_req_data *req,
      71                 :                                   Conf_parse *, Conf_token *, unsigned int,
      72                 :                                   Vstr_ref **);
      73                 : 
      74                 : extern int httpd_policy_path_eq(const Vstr_base *,
      75                 :                                 const Vstr_base *, size_t *, size_t *);
      76                 : extern int httpd_policy_path_beg_eq(const Vstr_base *,
      77                 :                                     const Vstr_base *, size_t *, size_t *);
      78                 : extern int httpd_policy_path_end_eq(const Vstr_base *,
      79                 :                                     const Vstr_base *, size_t *, size_t *);
      80                 : 
      81                 : extern void httpd_policy_path_mod_name(const Vstr_base *, size_t *, size_t *);
      82                 : extern void httpd_policy_path_mod_dirn(const Vstr_base *, size_t *, size_t *);
      83                 : extern void httpd_policy_path_mod_extn(const Vstr_base *, size_t *, size_t *);
      84                 : extern void httpd_policy_path_mod_exts(const Vstr_base *, size_t *, size_t *);
      85                 : extern void httpd_policy_path_mod_bwen(const Vstr_base *, size_t *, size_t *);
      86                 : extern void httpd_policy_path_mod_bwes(const Vstr_base *, size_t *, size_t *);
      87                 : 
      88                 : extern int  httpd_policy_path_lim_eq(const Vstr_base *, size_t *, size_t *,
      89                 :                                      unsigned int, size_t, Vstr_ref *);
      90                 : 
      91                 : extern int httpd_policy_uri_eq(const Vstr_base *,
      92                 :                                const Vstr_base *, size_t *, size_t *);
      93                 : extern int httpd_policy_uri_beg_eq(const Vstr_base *,
      94                 :                                    const Vstr_base *, size_t *, size_t *);
      95                 : extern int httpd_policy_uri_end_eq(const Vstr_base *,
      96                 :                                    const Vstr_base *, size_t *, size_t *);
      97                 : 
      98                 : extern void httpd_policy_uri_mod_name(const Vstr_base *, size_t *, size_t *);
      99                 : extern void httpd_policy_uri_mod_dirn(const Vstr_base *, size_t *, size_t *);
     100                 : extern void httpd_policy_uri_mod_extn(const Vstr_base *, size_t *, size_t *);
     101                 : extern void httpd_policy_uri_mod_exts(const Vstr_base *, size_t *, size_t *);
     102                 : extern void httpd_policy_uri_mod_bwen(const Vstr_base *, size_t *, size_t *);
     103                 : extern void httpd_policy_uri_mod_bwes(const Vstr_base *, size_t *, size_t *);
     104                 : 
     105                 : extern int  httpd_policy_uri_lim_eq(const Vstr_base *, size_t *, size_t *,
     106                 :                                     unsigned int, int, Vstr_ref *);
     107                 : 
     108                 : extern int httpd_policy_path_req2lim(unsigned int);
     109                 : 
     110                 : extern int httpd_policy_ipv4_make(struct Con *, Httpd_req_data *,
     111                 :                                   Conf_parse *, Conf_token *,
     112                 :                                   unsigned int, struct sockaddr *, int *);
     113                 : extern int httpd_policy_ipv4_cidr_eq(struct Con *, Httpd_req_data *,
     114                 :                                      Opt_policy_ipv4 *, struct sockaddr *);
     115                 : 
     116                 : extern void httpd_policy_exit(Httpd_policy_opts *);
     117                 : extern int httpd_policy_init(Httpd_opts *, Httpd_policy_opts *);
     118                 : extern Opt_serv_policy_opts *httpd_policy_make(Opt_serv_opts *);
     119                 : extern int httpd_policy_copy(Opt_serv_policy_opts *,
     120                 :                              const Opt_serv_policy_opts *);
     121                 : 
     122                 : #if !defined(HTTPD_POLICY_COMPILE_INLINE)
     123                 : # if ! COMPILE_DEBUG
     124                 : #  define HTTPD_POLICY_COMPILE_INLINE 1
     125                 : # else
     126                 : #  define HTTPD_POLICY_COMPILE_INLINE 0
     127                 : # endif
     128                 : #endif
     129                 : 
     130                 : #if defined(VSTR_AUTOCONF_HAVE_INLINE) && HTTPD_POLICY_COMPILE_INLINE
     131                 : 
     132                 : #if COMPILE_DEBUG
     133                 : # define HTTPD_POLICY__ASSERT ASSERT
     134                 : #else
     135                 : # define HTTPD_POLICY__ASSERT(x)
     136                 : #endif
     137                 : 
     138                 : #ifndef HTTPD_POLICY__EI
     139                 : # define HTTPD_POLICY__EI extern inline
     140                 : #endif
     141                 : 
     142                 : #define HTTPD_POLICY__TRUE  1
     143                 : #define HTTPD_POLICY__FALSE 0
     144                 : 
     145                 : HTTPD_POLICY__EI void httpd_policy_change_con(struct Con *con,
     146                 :                                               const Httpd_policy_opts *policy)
     147           45862 : { /* BEG: should be in opt_policy_change_con() */
     148           45862 :   con->evnt->flag_insta_close = policy->s->use_insta_close;
     149                 :   
     150           45862 :   evnt_limit_alt(con->evnt, 0, &policy->s->io_nslimit);
     151           45862 :   evnt_limit_chg(con->evnt, 1,  policy->s->ref_io_limit);
     152                 :   /* END: should be in opt_policy_change_con() */
     153                 :     
     154           45862 :   con->use_sendfile      = policy->use_sendfile;
     155           45862 :   con->use_posix_fadvise = policy->use_posix_fadvise;
     156           45862 :   con->policy            = policy;
     157           45862 : }
     158                 : 
     159                 : HTTPD_POLICY__EI void httpd_policy_change_req(struct Con *con,
     160                 :                                               Httpd_req_data *req,
     161                 :                                               const Httpd_policy_opts *policy)
     162           61562 : {
     163           61562 :   con->evnt->flag_insta_close = policy->s->use_insta_close;
     164                 :     
     165           61562 :   req->parse_accept          = policy->use_err_406;
     166           61562 :   req->parse_accept_language = policy->use_err_406;
     167           61562 :   req->allow_accept_encoding = policy->use_enc_content_replacement;
     168           61562 :   if (req->vhost_prefix_len && !policy->use_vhosts_name)
     169                 :   { /* NOTE: doesn't do chk_host properly */
     170               0 :     vstr_del(req->fname, 1, req->vhost_prefix_len);
     171               0 :     req->vhost_prefix_len = 0;
     172                 :   }
     173           61562 :   if (!req->chked_encoded_path)
     174                 :   {
     175           59354 :     req->chk_encoded_slash   = policy->chk_encoded_slash;
     176           59354 :     req->chk_encoded_dot     = policy->chk_encoded_dot;
     177                 :   }
     178           61562 :   req->policy                = policy;
     179           61562 : }
     180                 : 
     181                 : HTTPD_POLICY__EI int httpd_policy_path_eq(const Vstr_base *s1,
     182                 :                                           const Vstr_base *s2,
     183                 :                                           size_t *p2, size_t *l2)
     184           42312 : {
     185           42312 :   return (vstr_cmp_eq(s1, 1, s1->len, s2, *p2, *l2));
     186                 : }
     187                 : 
     188                 : /* if the s1 is equal to the begining of s2 */
     189                 : HTTPD_POLICY__EI int httpd_policy_path_beg_eq(const Vstr_base *s1,
     190                 :                                               const Vstr_base *s2,
     191                 :                                               size_t *p2, size_t *l2)
     192           95272 : {
     193           95272 :   if (*l2 > s1->len)
     194           13216 :     *l2 = s1->len;
     195           95272 :   return (vstr_cmp_eq(s1, 1, s1->len, s2, *p2, *l2));
     196                 : }
     197                 : 
     198                 : /* if the s1 is equal to the end of s2 */
     199                 : HTTPD_POLICY__EI int httpd_policy_path_end_eq(const Vstr_base *s1,
     200                 :                                               const Vstr_base *s2,
     201                 :                                               size_t *p2, size_t *l2)
     202           37176 : {
     203           37176 :   if (*l2 > s1->len)
     204                 :   {
     205           33944 :     *p2 += (*l2 - s1->len);
     206           33944 :     *l2 = s1->len;
     207                 :   }
     208           37176 :   return (vstr_cmp_eq(s1, 1, s1->len, s2, *p2, *l2));
     209                 : }
     210                 : 
     211                 : HTTPD_POLICY__EI void httpd_policy_path_mod_name(const Vstr_base *s1,
     212                 :                                                  size_t *pos, size_t *len)
     213            3360 : {
     214            3360 :   size_t srch = vstr_srch_chr_rev(s1, *pos, *len, '/');
     215                 : 
     216            3360 :   if (!srch)
     217             992 :     return;
     218                 :   
     219            2368 :   *len -= vstr_sc_posdiff(*pos, srch);
     220            2368 :   *pos += vstr_sc_posdiff(*pos, srch);
     221                 : }
     222                 : 
     223                 : HTTPD_POLICY__EI void httpd_policy_path_mod_dirn(const Vstr_base *s1,
     224                 :                                                  size_t *pos, size_t *len)
     225             160 : {
     226             160 :   size_t srch = vstr_srch_chr_rev(s1, *pos, *len, '/');
     227                 : 
     228             160 :   if (srch)
     229             160 :     *len = vstr_sc_posdiff(*pos, srch);
     230                 :   else
     231               0 :     *len = 0;
     232             160 : }
     233                 : 
     234                 : HTTPD_POLICY__EI void httpd_policy_path_mod_extn(const Vstr_base *s1,
     235                 :                                                  size_t *pos, size_t *len)
     236             768 : {
     237             768 :   size_t srch = 0;
     238                 :   
     239             768 :   httpd_policy_path_mod_name(s1, pos, len);
     240                 : 
     241             768 :   if ((srch = vstr_srch_chr_rev(s1, *pos, *len, '.')))
     242                 :   { /* include '.' */
     243             672 :     *len -= srch - *pos;
     244             672 :     *pos = srch;
     245                 :   }
     246                 :   else
     247                 :   { /* at point just after basename */
     248              96 :     *pos = vstr_sc_poslast(*pos, *len);
     249              96 :     *len = 0;
     250                 :   }
     251             768 : }
     252                 : 
     253                 : HTTPD_POLICY__EI void httpd_policy_path_mod_exts(const Vstr_base *s1,
     254                 :                                                  size_t *pos, size_t *len)
     255             768 : {
     256             768 :   size_t srch = 0;
     257                 :   
     258             768 :   httpd_policy_path_mod_name(s1, pos, len);
     259                 : 
     260             768 :   if ((srch = vstr_srch_chr_fwd(s1, *pos, *len, '.')))
     261                 :   { /* include '.' */
     262             672 :     *len -= srch - *pos;
     263             672 :     *pos = srch;
     264                 :   }
     265                 :   else
     266                 :   { /* at point just after basename */
     267              96 :     *pos = vstr_sc_poslast(*pos, *len);
     268              96 :     *len = 0;
     269                 :   }
     270             768 : }
     271                 : 
     272                 : HTTPD_POLICY__EI void httpd_policy_path_mod_bwen(const Vstr_base *s1,
     273                 :                                                  size_t *pos, size_t *len)
     274             256 : {
     275             256 :   size_t srch = 0;
     276                 : 
     277             256 :   httpd_policy_path_mod_name(s1, pos, len);
     278                 : 
     279             256 :   if ((srch = vstr_srch_chr_rev(s1, *pos, *len, '.')))
     280             160 :     *len = vstr_sc_posdiff(*pos, srch) - 1; /* don't include '.' */
     281             256 : }
     282                 : 
     283                 : HTTPD_POLICY__EI void httpd_policy_path_mod_bwes(const Vstr_base *s1,
     284                 :                                                  size_t *pos, size_t *len)
     285             256 : {
     286             256 :   size_t srch = 0;
     287                 : 
     288             256 :   httpd_policy_path_mod_name(s1, pos, len);
     289                 : 
     290             256 :   if ((srch = vstr_srch_chr_fwd(s1, *pos, *len, '.')))
     291             160 :     *len = vstr_sc_posdiff(*pos, srch) - 1; /* don't include '.' */
     292             256 : }
     293                 : 
     294                 : HTTPD_POLICY__EI int httpd_policy_path_lim_eq(const Vstr_base *s1,
     295                 :                                               size_t *pos, size_t *len,
     296                 :                                               unsigned int lim,
     297                 :                                               size_t vhost_prefix_len,
     298                 :                                               Vstr_ref *ref)
     299          176872 : {
     300          176872 :   const Httpd_policy_path *srch = NULL;
     301                 : 
     302          176872 :   if (lim == HTTPD_POLICY_PATH_LIM_NONE)
     303              96 :     return (HTTPD_POLICY__TRUE);
     304                 :   
     305          176776 :   *len -= vhost_prefix_len;
     306          176776 :   *pos += vhost_prefix_len;
     307                 :       
     308          176776 :   switch (lim)
     309                 :   {
     310               0 :     default: HTTPD_POLICY__ASSERT(HTTPD_POLICY__FALSE);
     311                 : 
     312                 :     case HTTPD_POLICY_PATH_LIM_PATH_FULL:
     313                 :     case HTTPD_POLICY_PATH_LIM_PATH_BEG:
     314                 :     case HTTPD_POLICY_PATH_LIM_PATH_END:
     315                 :     case HTTPD_POLICY_PATH_LIM_PATH_EQ:
     316           87620 :       break;
     317                 :     
     318                 :     case HTTPD_POLICY_PATH_LIM_NAME_FULL:
     319                 :     case HTTPD_POLICY_PATH_LIM_NAME_BEG:
     320                 :     case HTTPD_POLICY_PATH_LIM_NAME_END:
     321                 :     case HTTPD_POLICY_PATH_LIM_NAME_EQ:
     322            1152 :       httpd_policy_path_mod_name(s1, pos, len);
     323            1152 :       break;
     324                 :     
     325                 :     case HTTPD_POLICY_PATH_LIM_EXTN_FULL:
     326                 :     case HTTPD_POLICY_PATH_LIM_EXTN_BEG:
     327                 :     case HTTPD_POLICY_PATH_LIM_EXTN_END:
     328                 :     case HTTPD_POLICY_PATH_LIM_EXTN_EQ:
     329              96 :       httpd_policy_path_mod_extn(s1, pos, len);
     330              96 :       break;
     331                 : 
     332                 :     case HTTPD_POLICY_PATH_LIM_EXTS_FULL:
     333                 :     case HTTPD_POLICY_PATH_LIM_EXTS_BEG:
     334                 :     case HTTPD_POLICY_PATH_LIM_EXTS_END:
     335                 :     case HTTPD_POLICY_PATH_LIM_EXTS_EQ:
     336              96 :       httpd_policy_path_mod_exts(s1, pos, len);
     337              96 :       break;
     338                 : 
     339                 :     case HTTPD_POLICY_PATH_LIM_BWEN_FULL:
     340                 :     case HTTPD_POLICY_PATH_LIM_BWEN_BEG:
     341                 :     case HTTPD_POLICY_PATH_LIM_BWEN_END:
     342                 :     case HTTPD_POLICY_PATH_LIM_BWEN_EQ:
     343              96 :       httpd_policy_path_mod_bwen(s1, pos, len);
     344              96 :       break;
     345                 :       
     346                 :     case HTTPD_POLICY_PATH_LIM_BWES_FULL:
     347                 :     case HTTPD_POLICY_PATH_LIM_BWES_BEG:
     348                 :     case HTTPD_POLICY_PATH_LIM_BWES_END:
     349                 :     case HTTPD_POLICY_PATH_LIM_BWES_EQ:
     350              96 :       httpd_policy_path_mod_bwes(s1, pos, len);
     351                 :       break;
     352                 :   }
     353                 : 
     354          176776 :   if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_FULL)
     355            2016 :     return (HTTPD_POLICY__TRUE);
     356                 :   
     357           87380 :   HTTPD_POLICY__ASSERT(ref);
     358          174760 :   srch = ref->ptr;
     359                 :   
     360                 :   if (0) { }
     361          174760 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_BEG)
     362                 :   {
     363           95272 :     if (!httpd_policy_path_beg_eq(srch->s1, s1, pos, len))
     364           89896 :       goto path_no_match;
     365                 :   }
     366           79488 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_END)
     367                 :   {
     368           37176 :     if (!httpd_policy_path_end_eq(srch->s1, s1, pos, len))
     369           32216 :       goto path_no_match;
     370                 :   }
     371           42312 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_EQ)
     372                 :   {
     373           42312 :     if (!httpd_policy_path_eq(srch->s1, s1, pos, len))
     374           39336 :       goto path_no_match;
     375                 :   }
     376                 :   else
     377               0 :     HTTPD_POLICY__ASSERT(HTTPD_POLICY__FALSE);
     378                 :     
     379           13312 :   vstr_ref_del(ref); ref = NULL;
     380           13312 :   return (HTTPD_POLICY__TRUE);
     381          161448 :  path_no_match:
     382          161448 :   vstr_ref_del(ref); ref = NULL;
     383          161448 :   return (HTTPD_POLICY__FALSE);
     384                 : }
     385                 : 
     386                 : static inline int httpd_policy__uri_eq(const Vstr_base *s1,
     387                 :                                        const Vstr_base *s2,
     388                 :                                        size_t p2, size_t l2, size_t *ret_len)
     389            5184 : {
     390            5184 :   size_t p1 = 1;
     391            5184 :   size_t l1 = s1->len;
     392                 :   
     393           11584 :   while (l1 && (l2 >= l1))
     394                 :   {
     395            5184 :     size_t tmp = vstr_cspn_cstr_chrs_fwd(s2, p2, l1, "%");
     396            5184 :     unsigned int val1 = 0;
     397            5184 :     unsigned int val2 = 0;
     398            5184 :     unsigned int num_flags = VSTR_FLAG02(PARSE_NUM_NO, BEG_ZERO, BEG_PM);
     399                 :     
     400            5184 :     if (tmp)
     401                 :     {
     402            4064 :       if (!vstr_cmp_eq(s1, p1, tmp, s2, p2, tmp))
     403            2944 :         return (HTTPD_POLICY__FALSE);
     404            1120 :       l1 -= tmp; p1 += tmp;
     405            1120 :       l2 -= tmp; p2 += tmp;
     406            1120 :       continue;
     407                 :     }
     408                 : 
     409            1120 :     if (l2 < 3)
     410               0 :       return (HTTPD_POLICY__FALSE);
     411             560 :     HTTPD_POLICY__ASSERT(vstr_export_chr(s2, p2) == '%');
     412                 : 
     413            1120 :     val1 = (unsigned char)vstr_export_chr(s1, p1);
     414            1120 :     val2 = vstr_parse_ushort(s2, p2 + 1, 2, 16 | num_flags, &tmp, NULL);
     415                 : 
     416            1120 :     if ((tmp != 2) || (val1 != val2))
     417            1024 :       return (HTTPD_POLICY__FALSE);
     418                 :     
     419              96 :     l1 -= 1; p1 += 1;
     420              96 :     l2 -= 3; p2 += 3;
     421                 :   }
     422                 : 
     423            1216 :   *ret_len = l2;
     424            1216 :   return (!l1);
     425                 : }
     426                 : 
     427                 : HTTPD_POLICY__EI int httpd_policy_uri_eq(const Vstr_base *s1,
     428                 :                                          const Vstr_base *s2,
     429                 :                                          size_t *p2, size_t *l2)
     430               0 : {
     431               0 :   size_t tmp = 0;
     432               0 :   return (httpd_policy__uri_eq(s1, s2, *p2, *l2, &tmp) && !tmp);
     433                 : }
     434                 : 
     435                 : /* if the s1 is equal to the begining of s2 */
     436                 : HTTPD_POLICY__EI int httpd_policy_uri_beg_eq(const Vstr_base *s1,
     437                 :                                              const Vstr_base *s2,
     438                 :                                              size_t *p2, size_t *l2)
     439             832 : {
     440             832 :   size_t tmp = 0;
     441                 : 
     442             832 :   if (!httpd_policy__uri_eq(s1, s2, *p2, *l2, &tmp))
     443               0 :     return (HTTPD_POLICY__FALSE);
     444                 :   
     445             832 :   if (tmp) *l2 -= tmp;
     446                 :   
     447             832 :   return (HTTPD_POLICY__TRUE);
     448                 : }
     449                 : 
     450                 : /* if the s1 is equal to the end of s2 */
     451                 : HTTPD_POLICY__EI int httpd_policy_uri_end_eq(const Vstr_base *s1,
     452                 :                                              const Vstr_base *s2,
     453                 :                                              size_t *p2, size_t *l2)
     454            1792 : {
     455            1792 :   if (!vstr_srch_chr_fwd(s2, *p2, *l2, '%'))
     456                 :   {
     457            1408 :     if (*l2 > s1->len)
     458                 :     {
     459            1408 :       *p2 += (*l2 - s1->len);
     460            1408 :       *l2 = s1->len;
     461                 :     }
     462            1408 :     return (vstr_cmp_eq(s1, 1, s1->len, s2, *p2, *l2));
     463                 :   }
     464                 : 
     465             384 :   if (*l2 > (s1->len * 3))
     466                 :   {
     467             192 :     *p2 += (*l2 - (s1->len * 3));
     468             192 :     *l2 = (s1->len * 3);
     469                 :   }
     470                 : 
     471            4544 :   while (*l2 >= s1->len)
     472                 :   {
     473            4352 :     size_t tmp = 0;
     474            4352 :     if (httpd_policy__uri_eq(s1, s2, *p2, *l2, &tmp) && !tmp)
     475             384 :       return (HTTPD_POLICY__TRUE);
     476            3968 :     *l2 -= 1; *p2 += 1;
     477                 :   }
     478                 :   
     479               0 :   return (HTTPD_POLICY__FALSE);
     480                 : }
     481                 : 
     482                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_name(const Vstr_base *s1,
     483                 :                                                 size_t *pos, size_t *len)
     484             800 : {
     485             800 :   size_t srch1 = vstr_srch_chr_rev(s1, *pos, *len, '/');
     486             800 :   size_t srch2 = vstr_srch_case_cstr_buf_rev(s1, *pos, *len, "%2f");
     487                 : 
     488             800 :   if (!srch1 && !srch2)
     489               0 :     return;
     490                 : 
     491             800 :   if (srch1 < srch2)
     492               0 :     srch1 = srch2 + 2;
     493                 :   
     494             800 :   *len -= vstr_sc_posdiff(*pos, srch1);
     495             800 :   *pos += vstr_sc_posdiff(*pos, srch1);
     496                 : }
     497                 : 
     498                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_dirn(const Vstr_base *s1,
     499                 :                                                 size_t *pos, size_t *len)
     500             160 : {
     501             160 :   size_t srch1 = vstr_srch_chr_rev(s1, *pos, *len, '/');
     502             160 :   size_t srch2 = vstr_srch_case_cstr_buf_rev(s1, *pos, *len, "%2f");
     503                 : 
     504             160 :   if (!srch1 && !srch2)
     505                 :   {
     506               0 :     *len = 0;
     507               0 :     return;
     508                 :   }
     509                 :   
     510             160 :   if (srch1 < srch2)
     511               0 :     srch1 = srch2 + 2;
     512                 :   
     513             160 :   *len = vstr_sc_posdiff(*pos, srch1);
     514                 : }
     515                 : 
     516                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_extn(const Vstr_base *s1,
     517                 :                                                 size_t *pos, size_t *len)
     518             160 : {
     519             160 :   size_t srch1 = 0;
     520             160 :   size_t srch2 = 0;
     521                 :   
     522             160 :   httpd_policy_uri_mod_name(s1, pos, len);
     523                 : 
     524             160 :   srch1 = vstr_srch_chr_rev(s1, *pos, *len, '.');
     525             160 :   srch2 = vstr_srch_case_cstr_buf_rev(s1, *pos, *len, "%2e");
     526                 :   
     527             160 :   if (srch1 < srch2)
     528              64 :     srch1 = srch2;
     529                 : 
     530             160 :   if (srch1)
     531                 :   { /* include '.' or "%2e" */
     532             160 :     *len -= srch1 - *pos;
     533             160 :     *pos = srch1;
     534                 :   }
     535                 :   else
     536                 :   { /* at point just after basename */
     537               0 :     *pos = vstr_sc_poslast(*pos, *len);
     538               0 :     *len = 0;
     539                 :   }
     540             160 : }
     541                 : 
     542                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_exts(const Vstr_base *s1,
     543                 :                                                 size_t *pos, size_t *len)
     544             160 : {
     545             160 :   size_t srch1 = 0;
     546             160 :   size_t srch2 = 0;
     547                 :   
     548             160 :   httpd_policy_uri_mod_name(s1, pos, len);
     549                 : 
     550             160 :   srch1 = vstr_srch_chr_fwd(s1, *pos, *len, '.');
     551             160 :   srch2 = vstr_srch_case_cstr_buf_fwd(s1, *pos, *len, "%2e");
     552             160 :   if (!srch1) srch1 = srch2;  
     553             160 :   if (!srch2) srch2 = srch1;  
     554                 :   
     555             160 :   if (srch1 > srch2) srch1 = srch2;
     556                 : 
     557             160 :   if (srch1)
     558                 :   { /* include '.' or "%2e" */
     559             160 :     *len -= srch1 - *pos;
     560             160 :     *pos = srch1;
     561                 :   }
     562                 :   else
     563                 :   { /* at point just after basename */
     564               0 :     *pos = vstr_sc_poslast(*pos, *len);
     565               0 :     *len = 0;
     566                 :   }
     567             160 : }
     568                 : 
     569                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_bwen(const Vstr_base *s1,
     570                 :                                                 size_t *pos, size_t *len)
     571             160 : {
     572             160 :   size_t srch1 = 0;
     573             160 :   size_t srch2 = 0;
     574                 : 
     575             160 :   httpd_policy_uri_mod_name(s1, pos, len);
     576                 : 
     577             160 :   srch1 = vstr_srch_chr_rev(s1, *pos, *len, '.');
     578             160 :   srch2 = vstr_srch_case_cstr_buf_rev(s1, *pos, *len, "%2e");
     579                 : 
     580             160 :   if (srch1 < srch2) srch1 = srch2;
     581                 :   
     582             160 :   if (srch1)
     583             160 :     *len = vstr_sc_posdiff(*pos, srch1) - 1; /* don't include '.' */
     584             160 : }
     585                 : 
     586                 : HTTPD_POLICY__EI void httpd_policy_uri_mod_bwes(const Vstr_base *s1,
     587                 :                                                 size_t *pos, size_t *len)
     588             160 : {
     589             160 :   size_t srch1 = 0;
     590             160 :   size_t srch2 = 0;
     591                 : 
     592             160 :   httpd_policy_uri_mod_name(s1, pos, len);
     593                 : 
     594             160 :   srch1 = vstr_srch_chr_fwd(s1, *pos, *len, '.');
     595             160 :   srch2 = vstr_srch_case_cstr_buf_fwd(s1, *pos, *len, "%2e");
     596             160 :   if (!srch1) srch1 = srch2;  
     597             160 :   if (!srch2) srch2 = srch1;
     598                 :   
     599             160 :   if (srch1 > srch2) srch1 = srch2;
     600                 :   
     601             160 :   if (srch1)
     602             160 :     *len = vstr_sc_posdiff(*pos, srch1) - 1; /* don't include '.' */
     603             160 : }
     604                 : 
     605                 : HTTPD_POLICY__EI int httpd_policy_uri_lim_eq(const Vstr_base *s1,
     606                 :                                              size_t *pos, size_t *len,
     607                 :                                              unsigned int lim,
     608                 :                                              int slash_dot_safe, Vstr_ref *ref)
     609            4864 : {
     610            4864 :   const Httpd_policy_path *srch = NULL;
     611                 :   
     612            4864 :   switch (lim)
     613                 :   {
     614               0 :     default: HTTPD_POLICY__ASSERT(HTTPD_POLICY__FALSE);
     615                 :     case HTTPD_POLICY_PATH_LIM_NONE:
     616             864 :       HTTPD_POLICY__ASSERT(!ref);
     617            1728 :       return (HTTPD_POLICY__TRUE);
     618                 : 
     619                 :     case HTTPD_POLICY_PATH_LIM_PATH_FULL:
     620                 :     case HTTPD_POLICY_PATH_LIM_PATH_BEG:
     621                 :     case HTTPD_POLICY_PATH_LIM_PATH_END:
     622                 :     case HTTPD_POLICY_PATH_LIM_PATH_EQ:
     623            1312 :       break;
     624                 :     
     625                 :     case HTTPD_POLICY_PATH_LIM_NAME_FULL:
     626                 :     case HTTPD_POLICY_PATH_LIM_NAME_BEG:
     627                 :     case HTTPD_POLICY_PATH_LIM_NAME_END:
     628                 :     case HTTPD_POLICY_PATH_LIM_NAME_EQ:
     629               0 :       if (slash_dot_safe)
     630               0 :         httpd_policy_path_mod_name(s1, pos, len);
     631                 :       else
     632               0 :         httpd_policy_uri_mod_name(s1, pos, len);
     633               0 :       break;
     634                 :     
     635                 :     case HTTPD_POLICY_PATH_LIM_EXTN_FULL:
     636                 :     case HTTPD_POLICY_PATH_LIM_EXTN_BEG:
     637                 :     case HTTPD_POLICY_PATH_LIM_EXTN_END:
     638                 :     case HTTPD_POLICY_PATH_LIM_EXTN_EQ:
     639             256 :       if (slash_dot_safe)
     640             256 :         httpd_policy_path_mod_extn(s1, pos, len);
     641                 :       else
     642               0 :         httpd_policy_uri_mod_extn(s1, pos, len);
     643             128 :       break;
     644                 : 
     645                 :     case HTTPD_POLICY_PATH_LIM_EXTS_FULL:
     646                 :     case HTTPD_POLICY_PATH_LIM_EXTS_BEG:
     647                 :     case HTTPD_POLICY_PATH_LIM_EXTS_END:
     648                 :     case HTTPD_POLICY_PATH_LIM_EXTS_EQ:
     649             256 :       if (slash_dot_safe)
     650             256 :         httpd_policy_path_mod_exts(s1, pos, len);
     651                 :       else
     652               0 :         httpd_policy_uri_mod_exts(s1, pos, len);
     653             128 :       break;
     654                 : 
     655                 :     case HTTPD_POLICY_PATH_LIM_BWEN_FULL:
     656                 :     case HTTPD_POLICY_PATH_LIM_BWEN_BEG:
     657                 :     case HTTPD_POLICY_PATH_LIM_BWEN_END:
     658                 :     case HTTPD_POLICY_PATH_LIM_BWEN_EQ:
     659               0 :       if (slash_dot_safe)
     660               0 :         httpd_policy_path_mod_bwen(s1, pos, len);
     661                 :       else
     662               0 :         httpd_policy_uri_mod_bwen(s1, pos, len);
     663               0 :       break;
     664                 :       
     665                 :     case HTTPD_POLICY_PATH_LIM_BWES_FULL:
     666                 :     case HTTPD_POLICY_PATH_LIM_BWES_BEG:
     667                 :     case HTTPD_POLICY_PATH_LIM_BWES_END:
     668                 :     case HTTPD_POLICY_PATH_LIM_BWES_EQ:
     669               0 :       if (slash_dot_safe)
     670               0 :         httpd_policy_path_mod_bwes(s1, pos, len);
     671                 :       else
     672               0 :         httpd_policy_uri_mod_bwes(s1, pos, len);
     673                 :       break;
     674                 :   }
     675                 : 
     676            3136 :   if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_FULL)
     677                 :   {
     678             256 :     HTTPD_POLICY__ASSERT(!ref);
     679             512 :     return (HTTPD_POLICY__TRUE);
     680                 :   }
     681                 :   
     682            1312 :   HTTPD_POLICY__ASSERT(ref);
     683            2624 :   srch = ref->ptr;
     684                 :   
     685                 :   if (0) { }
     686            2624 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_BEG)
     687                 :   {
     688             832 :     if (!httpd_policy_uri_beg_eq(srch->s1, s1, pos, len))
     689               0 :       goto path_no_match;
     690                 :   }
     691            1792 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_END)
     692                 :   {
     693            1792 :     if (!httpd_policy_uri_end_eq(srch->s1, s1, pos, len))
     694               0 :       goto path_no_match;
     695                 :   }
     696               0 :   else if ((lim & HTTPD_POLICY__PATH_LIM_MASK) == HTTPD_POLICY__PATH_LIM_EQ)
     697                 :   {
     698               0 :     if (!httpd_policy_uri_eq(srch->s1, s1, pos, len))
     699               0 :       goto path_no_match;
     700                 :   }
     701                 :   else
     702               0 :     HTTPD_POLICY__ASSERT(HTTPD_POLICY__FALSE);
     703                 :     
     704            2624 :   vstr_ref_del(ref); ref = NULL;
     705            2624 :   return (HTTPD_POLICY__TRUE);
     706               0 :  path_no_match:
     707               0 :   vstr_ref_del(ref); ref = NULL;
     708               0 :   return (HTTPD_POLICY__FALSE);
     709                 : }
     710                 : 
     711                 : HTTPD_POLICY__EI int httpd_policy_path_req2lim(unsigned int type)
     712          177384 : {
     713          177384 :   unsigned int lim = HTTPD_POLICY_PATH_LIM_NONE;
     714                 :   
     715          177384 :   switch (type)
     716                 :   {
     717           95944 :     case HTTPD_POLICY_REQ_PATH_BEG: lim = HTTPD_POLICY_PATH_LIM_PATH_BEG; break;
     718           38808 :     case HTTPD_POLICY_REQ_PATH_END: lim = HTTPD_POLICY_PATH_LIM_PATH_END; break;
     719           42152 :     case HTTPD_POLICY_REQ_PATH_EQ:  lim = HTTPD_POLICY_PATH_LIM_PATH_EQ;  break;
     720                 :       
     721              32 :     case HTTPD_POLICY_REQ_NAME_BEG: lim = HTTPD_POLICY_PATH_LIM_NAME_BEG; break;
     722              32 :     case HTTPD_POLICY_REQ_NAME_END: lim = HTTPD_POLICY_PATH_LIM_NAME_END; break;
     723              32 :     case HTTPD_POLICY_REQ_NAME_EQ:  lim = HTTPD_POLICY_PATH_LIM_NAME_EQ;  break;
     724                 :       
     725              32 :     case HTTPD_POLICY_REQ_BWEN_BEG: lim = HTTPD_POLICY_PATH_LIM_BWEN_BEG; break;
     726              32 :     case HTTPD_POLICY_REQ_BWEN_END: lim = HTTPD_POLICY_PATH_LIM_BWEN_END; break;
     727              32 :     case HTTPD_POLICY_REQ_BWEN_EQ:  lim = HTTPD_POLICY_PATH_LIM_BWEN_EQ;  break;
     728                 :       
     729              32 :     case HTTPD_POLICY_REQ_BWES_BEG: lim = HTTPD_POLICY_PATH_LIM_BWES_BEG; break;
     730              32 :     case HTTPD_POLICY_REQ_BWES_END: lim = HTTPD_POLICY_PATH_LIM_BWES_END; break;
     731              32 :     case HTTPD_POLICY_REQ_BWES_EQ:  lim = HTTPD_POLICY_PATH_LIM_BWES_EQ;  break;
     732                 :       
     733              32 :     case HTTPD_POLICY_REQ_EXTN_BEG: lim = HTTPD_POLICY_PATH_LIM_EXTN_BEG; break;
     734              32 :     case HTTPD_POLICY_REQ_EXTN_END: lim = HTTPD_POLICY_PATH_LIM_EXTN_END; break;
     735              32 :     case HTTPD_POLICY_REQ_EXTN_EQ:  lim = HTTPD_POLICY_PATH_LIM_EXTN_EQ;  break;
     736                 :       
     737              32 :     case HTTPD_POLICY_REQ_EXTS_BEG: lim = HTTPD_POLICY_PATH_LIM_EXTS_BEG; break;
     738              32 :     case HTTPD_POLICY_REQ_EXTS_END: lim = HTTPD_POLICY_PATH_LIM_EXTS_END; break;
     739              32 :     case HTTPD_POLICY_REQ_EXTS_EQ:  lim = HTTPD_POLICY_PATH_LIM_EXTS_EQ;  break;
     740                 :       
     741                 :     default:
     742               0 :       HTTPD_POLICY__ASSERT(HTTPD_POLICY__FALSE);
     743                 :   }
     744                 : 
     745          177384 :   return (lim);
     746                 : }
     747                 : 
     748                 : HTTPD_POLICY__EI int httpd_policy_ipv4_make(struct Con *con,
     749                 :                                             Httpd_req_data *req,
     750                 :                                             Conf_parse *conf, Conf_token *token,
     751                 :                                             unsigned int type,
     752                 :                                             struct sockaddr *sa, int *matches)
     753             350 : {
     754             175 :   HTTPD_POLICY__ASSERT(con);
     755             175 :   HTTPD_POLICY__ASSERT(EVNT_ACPT_EXISTS(con->evnt));
     756             175 :   HTTPD_POLICY__ASSERT((sa == CON_CEVNT_SA(con)) || (sa == CON_SEVNT_SA(con)));
     757                 :   
     758             350 :   if (sa == CON_CEVNT_SA(con))
     759                 :   {
     760               4 :     if (req)
     761               4 :       req->vary_star = HTTPD_POLICY__TRUE;
     762                 :     else
     763               0 :       con->vary_star = HTTPD_POLICY__TRUE;
     764                 :   }
     765                 : 
     766             350 :   return (opt_policy_ipv4_make(conf, token, type, sa, matches));
     767                 : }
     768                 : 
     769                 : HTTPD_POLICY__EI int httpd_policy_ipv4_cidr_eq(struct Con *con,
     770                 :                                                Httpd_req_data *req,
     771                 :                                                Opt_policy_ipv4 *ipv4,
     772                 :                                                struct sockaddr *sa)
     773           40486 : {
     774           20243 :   HTTPD_POLICY__ASSERT(con);
     775           20243 :   HTTPD_POLICY__ASSERT((sa == CON_CEVNT_SA(con)) || (sa == CON_SEVNT_SA(con)));
     776                 :   
     777           40486 :   if (sa == EVNT_SA(con->evnt))
     778                 :   {
     779             828 :     if (req)
     780             828 :       req->vary_star = HTTPD_POLICY__TRUE;
     781                 :     else
     782               0 :       con->vary_star = HTTPD_POLICY__TRUE;
     783                 :   }
     784                 : 
     785           40486 :   return (opt_policy_ipv4_cidr_eq(ipv4, sa));
     786                 : }
     787                 : 
     788                 : 
     789                 : #endif
     790                 : 
     791                 : #endif

Generated by: LTP GCOV extension version 1.4