modules/wk/which_keytypes.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. wk_regex_init
  2. wk_is_name
  3. wk_is_domain
  4. wk_is_hostname
  5. WK_to_string
  6. WK_new

   1 /***************************************
   2   $Revision: 1.24 $
   3 
   4   which_keytypes:  Determine which keys to look for.
   5   
   6   This is based on the existing Perl code. 
   7 
   8   Authors: ottrey, marek
   9 
  10   ******************/ /******************
  11   Copyright (c) 1999,2000,2001                    RIPE NCC
  12  
  13   All Rights Reserved
  14   
  15   Permission to use, copy, modify, and distribute this software and its
  16   documentation for any purpose and without fee is hereby granted,
  17   provided that the above copyright notice appear in all copies and that
  18   both that copyright notice and this permission notice appear in
  19   supporting documentation, and that the name of the author not be
  20   used in advertising or publicity pertaining to distribution of the
  21   software without specific, written prior permission.
  22   
  23   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  24   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  25   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  26   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  27   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  28   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  29   ***************************************/
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <strings.h>
  33 #include <glib.h>
  34 #include <pthread.h>
  35 
  36 #include "bitmask.h"
  37 #include "memwrap.h"
  38 
  39 #define  WK_IMPL
  40 #include "which_keytypes.h"
  41 #include <regex.h>
  42 
  43 #define DOMAINNAME "^[ ]*[a-zA-Z0-9-]*(\\.[a-zA-Z0-9-]+)*[ ]*$"
  44 /* add a constraint: there must be at least one character in the domain name
  45    because the TLD must not be composed of digits only */
  46 #define DOMAINALPHA  "[a-zA-Z]"
  47 
  48 #define VALIDIP6PREFIX "^[0-9A-F:]*:[0-9A-F:/]*$"     /* at least one colon */
  49 /* "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"*/
  50 
  51 /* AS numbers, prepared for 32-bit AS numbers */
  52 #define ASNUM "^AS[1-9][0-9]{0,9}$"
  53 
  54 /* AS numbers, prepared for 32-bit AS numbers */
  55 #define ASRANGE "^AS[1-9][0-9]{0,9}[ ]*([-][ ]*AS[1-9][0-9]{0,9}){0,1}$"   /* [ ]*(-[ ]*AS[0-9]+)?   */
  56 
  57 #define NETNAME "^[A-Z][A-Z0-9_-]*$"
  58 
  59 #define MAINTAINER "^[A-Z][A-Z0-9_-]*$"
  60 
  61 #define LIMERICK "^LIM-[A-Z0-9_-]+$"
  62 
  63 #define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
  64 
  65 /* made less restrictive to make consistent with other sets ... shane */
  66 /* made to match what we're actually looking for - shane */
  67 /*#define ROUTESETNAME "^RS-[A-Z0-9_:-]*$"*/
  68 #define ROUTESETNAME "(^|:)RS-[A-Z0-9_-]*[A-Z0-9](:|$)"
  69 
  70 /* made less restrictive to make consistent with other sets ... shane */
  71 /* made to match what we're actually looking for - shane */
  72 /*#define ASSETNAME "^AS-[A-Z0-9_:-]*$"*/
  73 #define ASSETNAME "(^|:)AS-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  74 
  75 #define AUTONICPREFIXREGULAR "^AUTO-"
  76 
  77 #define IPRANGE "^[0-9]{1,3}(\\.[0-9]{1,3}){0,3}[ ]*-[ ]*[0-9]{1,3}(\\.[0-9]{1,3}){0,3}$"
  78 
  79 #define IPADDRESS "^[0-9.]+$"
  80 
  81 #define IPPREFIX "^[0-9.]+/[0-9]+$"
  82 
  83 /*#define PEERINGSET "^PRNG-"*/
  84 #define PEERINGSET "(^|:)PRNG-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  85 
  86 /*#define FILTERSET  "^FLTR-"*/
  87 #define FILTERSET "(^|:)FLTR-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  88 
  89 /*#define RTRSET     "^RTRS-"*/
  90 #define RTRSET "(^|:)RTRS-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  91 
  92 #define NICHANDLE "^[A-Z0-9-]+$"
  93 
  94 /*
  95   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
  96   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
  97   Does \w include [ ;:,?/}{()+*#] ?
  98 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
  99 */
 100 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
 101 
 102 #define EMAIL "@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"
 103 
 104 /* structure for simple keys, with a single regular expression to match */
 105 /* NOTE: the WK_NAME, WK_DOMAIN, and WK_HOSTNAME are not handled here   */
 106 struct {
 107     int key_type;               /* identifier for key, e.g. WK_RTRSET */
 108     char *pattern;              /* string for regular expression */
 109     regex_t regex;              /* regular expression */
 110 } wk_regex_list[] = {
 111     { WK_NIC_HDL,       NICHANDLE },
 112     { WK_EMAIL,         EMAIL },
 113     { WK_MNTNER,        MAINTAINER },
 114     { WK_KEY_CERT,      KEYCERT },
 115     { WK_IPRANGE,       IPRANGE },
 116     { WK_IPADDRESS,     IPADDRESS },
 117     { WK_IPPREFIX,      IPPREFIX },
 118     { WK_IP6PREFIX,     VALIDIP6PREFIX },
 119     { WK_NETNAME,       NETNAME },
 120     { WK_NET6NAME,      NETNAME },
 121     { WK_AUTNUM,        ASNUM },
 122     { WK_ASSETNAME,     ASSETNAME },
 123     { WK_ROUTESETNAME,  ROUTESETNAME },
 124     { WK_LIMERICK,      LIMERICK },
 125     { WK_ASRANGE,       ASRANGE },
 126     { WK_PEERINGSET,    PEERINGSET },
 127     { WK_FILTERSET,     FILTERSET },
 128     { WK_RTRSET,        RTRSET }
 129 };
 130 #define WK_REGEX_LIST_LEN  (sizeof(wk_regex_list)/sizeof(wk_regex_list[0]))
 131 
 132 /* regular expressions used by wk_is_name() */
 133 static regex_t ipaddress;
 134 static regex_t ipprefix;
 135 static regex_t validip6prefix;
 136 
 137 /* regular expression used by isdomname() */
 138 static regex_t domainname;
 139 static regex_t domainalpha;
 140 
 141 /* initialize regular expressions */
 142 static void 
 143 wk_regex_init ()
     /* [<][>][^][v][top][bottom][index][help] */
 144 {
 145     int i;
 146     int errcode;
 147 
 148     /* initialize our table */
 149     for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 150         errcode = regcomp(&wk_regex_list[i].regex, 
 151                           wk_regex_list[i].pattern, 
 152                           REG_EXTENDED|REG_NOSUB);
 153         dieif(errcode != 0);
 154     }
 155 
 156     /* add some special cases used by our other functions */
 157     errcode = regcomp(&ipaddress, IPADDRESS, REG_EXTENDED|REG_NOSUB);
 158     dieif(errcode != 0);
 159     errcode = regcomp(&ipprefix, IPPREFIX, REG_EXTENDED|REG_NOSUB);
 160     dieif(errcode != 0);
 161     errcode = regcomp(&validip6prefix, VALIDIP6PREFIX, REG_EXTENDED|REG_NOSUB);
 162     dieif(errcode != 0);
 163     errcode = regcomp(&domainname, DOMAINNAME, REG_EXTENDED|REG_NOSUB);
 164     dieif(errcode != 0);
 165     errcode = regcomp(&domainalpha, DOMAINALPHA, REG_EXTENDED|REG_NOSUB);
 166     dieif(errcode != 0);
 167 }
 168 
 169 
 170 /* see if the key looks like it could be a name */
 171 static unsigned int 
 172 wk_is_name (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 173 {
 174     /* if it's an address, it cannot be a name */
 175     if (regexec(&ipaddress, key, 0, NULL, 0) == 0) { 
 176         return 0;
 177     }
 178     if (regexec(&ipprefix, key, 0, NULL, 0) == 0) { 
 179         return 0;
 180     }
 181     if (regexec(&validip6prefix, key, 0, NULL, 0) == 0) { 
 182         return 0;
 183     }
 184 
 185     /* Everything apart from addresses matches to name */
 186     return 1;
 187 } /* wk_is_name() */
 188 
 189 /* check for domain name */
 190 static unsigned int 
 191 wk_is_domain (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 192 {
 193     /* if it matches the general domain name search, and contains an */
 194     /* alphabetic character, consider it a possible domain name */
 195     if (regexec(&domainname, key, 0, NULL, 0) == 0) {
 196         if (regexec(&domainalpha, key, 0, NULL, 0) == 0) {
 197             return 1;
 198         }
 199     }
 200     return 0;
 201 } 
 202 
 203 /* check for a host name (could be a domain, or an IP) */
 204 static unsigned int 
 205 wk_is_hostname (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 206 {
 207     /* Fix - should check for IPADDRESS, not IPRANGE.  - Shane */
 208     return (wk_is_domain(key) || (regexec(&ipaddress, key, 0, NULL, 0) == 0));
 209 } /* wk_is_hostname() */
 210 
 211 /* WK_to_string() */
 212 /*++++++++++++++++++++++++++++++++++++++
 213   Convert the which keytypes bitmap into a string.
 214 
 215   mask_t wk The which keytypes mask to be converted.
 216 
 217   More:
 218   +html+ <PRE>
 219   Authors:
 220         ottrey
 221   +html+ </PRE><DL COMPACT>
 222   +html+ <DT>Online References:
 223   +html+ <DD><UL>
 224   +html+ </UL></DL>
 225 
 226   ++++++++++++++++++++++++++++++++++++++*/
 227 char *
 228 WK_to_string (mask_t wk) 
     /* [<][>][^][v][top][bottom][index][help] */
 229 {
 230 
 231   return MA_to_string(wk, Keytypes);
 232 
 233 } /* WK_to_string() */
 234 
 235 /* WK_new() */
 236 /*++++++++++++++++++++++++++++++++++++++
 237   Create a new which keytypes bitmap.
 238 
 239   This checks the string to see which keys it looks like.  This helps 
 240   us decide what SQL tables (or radix trees) we need to query for a
 241   match.
 242 
 243   char *key The key to be examined.
 244 
 245   More:
 246   +html+ <PRE>
 247   Authors:
 248         ottrey
 249         shane
 250   +html+ </PRE><DL COMPACT>
 251   +html+ <DT>Online References:
 252   +html+ <DD><UL>
 253   +html+ </UL></DL>
 254 
 255   ++++++++++++++++++++++++++++++++++++++*/
 256 mask_t 
 257 WK_new (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 258 {
 259   static pthread_once_t once_control = { PTHREAD_ONCE_INIT };
 260 
 261   mask_t wk; 
 262   int i;
 263 
 264   /* initialize our regular expressions on the first call */
 265   pthread_once(&once_control, wk_regex_init);
 266 
 267   /* empty bitmask */
 268   wk = MA_new(MA_END);
 269 
 270   /* search regular expressions in the list */
 271   for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 272       if (regexec(&wk_regex_list[i].regex, key, 0, NULL, 0) == 0) { 
 273           MA_set(&wk, wk_regex_list[i].key_type, 1);
 274       }
 275   }
 276 
 277   /* check our more complicated key patterns */
 278   MA_set(&wk, WK_NAME,         wk_is_name(key));
 279   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
 280   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
 281   
 282   /* return resulting bitmask */
 283   return wk;
 284 
 285 } /* WK_new() */

/* [<][>][^][v][top][bottom][index][help] */