## modules/wk/which_keytypes.c

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

## FUNCTIONS

This source file includes following functions.

1. perform_regex_test
2. isasnum
3. isnichandle
4. isdomname
5. isname_a
6. isname_b
7. isname_ab
8. isnetname
9. wk_is_name
10. wk_is_nic_hdl
11. wk_is_email
12. wk_is_mntner
13. wk_is_key_cert
14. wk_is_ipaddress
15. wk_is_iprange
16. wk_is_ipprefix
17. wk_is_ip6prefix
18. wk_is_netname
19. wk_is_net6name
20. wk_is_autnum
21. wk_is_asrange
22. wk_is_assetname
23. wk_is_routesetname
24. wk_is_domain
25. wk_is_hostname
26. wk_is_limerick
27. wk_is_peeringset
28. wk_is_rtrset
29. wk_is_filterset
30. WK_to_string
31. WK_new

       1 /***************************************
       2   $Revision: 1.15 $
       3
       4   Example code: Determine which keys to look for.
       5
       6   This is based on the C code that was reversed engineered from existing Perl
       7   code.  (~ottrey/which_table/which_table.c)
       8
       9   ******************/ /******************
      10   Copyright (c) 1999                              RIPE NCC
      11
      12   All Rights Reserved
      13
      14   Permission to use, copy, modify, and distribute this software and its
      15   documentation for any purpose and without fee is hereby granted,
      16   provided that the above copyright notice appear in all copies and that
      17   both that copyright notice and this permission notice appear in
      18   supporting documentation, and that the name of the author not be
      19   used in advertising or publicity pertaining to distribution of the
      20   software without specific, written prior permission.
      21
      22   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      23   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      24   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      25   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      26   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      27   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      28   ***************************************/
      29 #include <stdio.h>
      30 #include <stdlib.h>
      31 #include <strings.h>
      32 #include <libgen.h>
      33 #include <glib.h>
      34
      35 #include "isnic.h"
      36 #include "bitmask.h"
      37 #include "memwrap.h"
      38
      39 #define  WK_IMPL
      40 #include "which_keytypes.h"
      41
      42
      43
      44 #define DOMAINNAME "^[ ]*[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*[ ]*$"
      45 /* add a constraint: there must be at least one character in the domain name
      46    because the TLD must not be composed of digits only */
      47 #define DOMAINALPHA  "[a-zA-Z]"
      48
      49 #define LEN_MIN 0
      50 #define LEN_MAX 32
      51
      52 #define NETLEN 16
      53 #define NETQUADS 4
      54 #define NETQUAD_MIN 0
      55 #define NETQUAD_MAX 255
      56
      57 #define ASNUM_MIN 1
      58 #define ASNUM_MAX 65535
      59 #define ASNUM_NUMOFFSET 2   /* XXX - (This is really kludgy!) Offset to the number bit of ASNUM */
      60
      61 #define VALIDIP6PREFIX "^[0-9A-F:]*:[0-9A-F:/]*$"     /* at least one colon */
      62 /* "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"*/
      63
      64 #define NET "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
      65
      66 #define ASNUM "^AS[1-9]+[0-9]*$"
      67
      68 #define ASRANGE "^AS[0-9]+[ ]*([-][ ]*AS[0-9]+){0,1}$"   /* [ ]*(-[ ]*AS[0-9]+)?   */
      69
      70 #define NETNAME "^[A-Z][A-Z0-9-]*$"
      71
      72 #define MAINTAINER "^[A-Z][A-Z0-9-]*$"
      73
      74 #define LIMERICK "^LIM-[A-Z0-9-]+$"
      75
      76 #define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
      77
      78 #define ROUTESETNAME "^RS-[A-Z0-9-_]*$"
      79
      80 #define ASSETNAME "^AS-[A-Z0-9-_]*$"
      81
      82 #define AUTONICPREFIXREGULAR "^AUTO-"
      83
      84 #define IPRANGE "^[0-9]{1,3}(\\.[0-9]{1,3}){0,3}[ ]*-[ ]*[0-9]{1,3}(\\.[0-9]{1,3}){0,3}$"
      85
      86 #define IPADDRESS "^[0-9.]+$"
      87
      88 #define IPPREFIX "^[0-9.]+/[0-9]+$"
      89
      90 #define PEERINGSET "^PRNG-"
      91
      92 #define FILTERSET  "^FLTR-"
      93
      94 #define RTRSET     "^RTRS-"
      95
      96 /*
      97   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
      98   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
      99   Does \w include [ ;:,?/}{()+*#] ?
     100 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
     101 */
     102 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
     103
     104 #define VALIDIP4PREFIX
     105
     106 #define EMAIL "^[.a-zA-Z0-9--]*@[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*$"
     107
     108 static int perform_regex_test(const char *pattern, char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     109   int match;
     110
     111   char *re;
     112
     113   re = regcmp(pattern, (char*)0);
     114   if (regex(re, string) == NULL) {
     115     match = 0;
     116   }
     117   else {
     118     match = 1;
     119   }
     120
     121   free(re); /* not a wrapper, because we have not allocated it */
     122
     123   return match;
     124 } /* perform_regex_test() */
     125
     126 static int isasnum(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     127   int result='-';
     128   int as_value;
     129
     130   /* First check if the string matches an ASNUM */
     131   result = perform_regex_test(ASNUM, string);
     132
     133   /* Then check if the value is between ASNUM_MIN and ASNUM_MAX */
     134   if (result == 1) {
     135     as_value = atoi(string+ASNUM_NUMOFFSET);
     136     if ((as_value < ASNUM_MIN) || (as_value > ASNUM_MAX)) {
     137       /* an invalid value */
     138       result=0;
     139     }
     140   }
     141
     142   return result;
     143 }
     144
     145 /*******************************************************
     146     # the problem is as follows:
     147     #
     148     # we can never find out which NIC handles are possible on the
     149     # globe since we don't know that they exist
     150     #
     151     # we want to solve this with once with DNS :
     152     #
     153     # RIPE.registries.int     CNAME whois.ripe.net
     154     # InterNIC.registries.int CNAME whois.internic.net
     155     # and so on...
     156
     157     #
     158     # 1) it first does a basic syntax check
     159     #
     160     #    notes:
     161     #
     162     #    - catches InterNIC handles
     163     #    - catches the JP|JP-JP APNIC exceptions
     164     #    - limits the number of initials to three with a good reason:
     165     #      we have a much better chance to find syntax errors like:
     166     #      RIPE-DK13 and other problems like this
     167     #
     168     # 2) checks for valid suffixes
     169     #    - all 'source:' attribute values from sites that we mirror
     170     #      are allowed
     171     #    - country codes are allowed for APNIC compatibility
     172     #    - APNIC AP|CC-AU exceptions are handled correctly
     173     #    - -ORG organization InterNIC handles
     174     #    - -ARIN ARIN handles
     175     #    - -ORG-ARIN ARIN handles
     176 ********************************************************/
     177 static int isnichandle(char *nichdl) {
         /* [<][>][^][v][top][bottom][index][help] */
     178
     179   char *regexp, *match;
     180   char ret[1024];
     181   char *suffix;
     182
     183   int i;
     184
     185 /* set ret to the empty string */
     186   ret[0]='\0';
     187
     188 /*
     189   # Japanese NIC handles
     190   #
     191   # leading zeros in the number part *are* allowed
     192   #
     193   # e.g. AB021JP AB199JP-JP
     194   #
     195 */
     196   regexp = regcmp("[A-Z]{2}[0-9]{3}JP(-JP){0,1}",(char *)0);
     197   match =  regex(regexp,nichdl);
     198   free(regexp); /* not a wrapper, because we have not allocated it */
     199   if (match) return 1;
     200
     201 /*
     202   # Standard NIC handles
     203   #
     204   # leading zeros in the number part are *not* allowed
     205   #
     206   # InterNIC - TBQ, IP4
     207   # RIPE format - AB1-RIPE
     208   # APNIC use two letter country code suffix
     209   # Austraila have used -1-AU, -2-AU, -CC-AU suffix.
     210   # Internic used -ORG suffix
     211   # ARIN use -ARIN suffix
     212   # ARIN also use -ORG-ARIN suffix
     213   #
     214 */
     215   regexp = regcmp("^[A-Z]{2,4}([1-9][0-9]{0,5}){0,1}((-[^ ]+){0,1})$0$",(char *)0);
     216   match =  regex(regexp,nichdl,ret);
     217
     218   free(regexp); /* not a wrapper, because we have not allocated it */
     219
     220   if (match == NULL) {
     221     return 0;
     222   } else {
     223     if (ret[0] == '\0') {
     224       return 1;
     225     } else {
     226 /*   strip leading '-' */
     227       suffix = ret+1;
     228 /* suffix of local sources */
     229       for (i=0;i<=NUM_NICPOSTFIX;i++) {
     230         if ( !strcmp(suffix,nicpostfix[i]) ) {
     231           return 1;
     232         }
     233       }
     234 /* country codes */
     235       for (i=0;i<NUM_COUNTRIES;i++) {
     236         if ( !strcmp(suffix,countries[i]) ) {
     237           return 1;
     238         }
     239       }
     240 /* special suffix */
     241       for (i=0;i<NUM_SPECIAL;i++) {
     242         if ( !strcmp(suffix,special[i]) ) {
     243           return 1;
     244         }
     245       }
     246     }
     247   }
     248   return 0;
     249 } /* isnichandle() */
     250
     251 static int isdomname(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     252     return (    perform_regex_test(DOMAINNAME, string)
     253              && perform_regex_test(DOMAINALPHA, string));
     254 }
     255
     256 /*
     257  I split the isname up into isname_a & isname_b.  And created isname_ab to join them together.
     258   - So I can test it properly.  -ottrey
     259  */
     260 static int isname_a(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     261     return perform_regex_test(AUTONICPREFIXREGULAR, string);
     262 }
     263
     264 static int isname_b(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     265     return perform_regex_test(NAME_B, string);
     266 }
     267
     268 static int isname_ab(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     269     return (isname_a(string) || isname_b(string));
     270 }
     271
     272 static int isnetname(char *string) {
         /* [<][>][^][v][top][bottom][index][help] */
     273     return perform_regex_test(NETNAME, string);
     274 } /* wk_is_netname() */
     275
     276 static int wk_is_name(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     277     /* Everything matches to name */
     278     return 1;
     279 } /* wk_is_name() */
     280
     281 static int wk_is_nic_hdl(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     282     return isnichandle(key);
     283 } /* wk_is_nic_hdl() */
     284
     285 static int wk_is_email(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     286     return perform_regex_test(EMAIL, key);
     287 } /* wk_is_email() */
     288
     289 static int wk_is_mntner(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     290     return perform_regex_test(MAINTAINER, key);
     291 } /* wk_is_mntner() */
     292
     293 static int wk_is_key_cert(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     294     return perform_regex_test(KEYCERT, key);
     295 } /* wk_is_key_cert() */
     296
     297 static int wk_is_ipaddress(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     298     return perform_regex_test(IPADDRESS, key);
     299 } /* wk_is_key_cert() */
     300
     301 static int wk_is_iprange(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     302     return perform_regex_test(IPRANGE, key);
     303 } /* wk_is_iprange() */
     304
     305 static int wk_is_ipprefix(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     306     return perform_regex_test(IPPREFIX, key);
     307 } /* wk_is_iprange() */
     308
     309 static int wk_is_ip6prefix(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     310     return perform_regex_test(VALIDIP6PREFIX, key);
     311 } /* wk_is_ip6prefix() */
     312
     313 static int wk_is_netname(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     314     return isnetname(key);
     315 } /* wk_is_netname() */
     316
     317 /* XXX Note: This function uses the same call as wk_is_netname(). */
     318 static int wk_is_net6name(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     319     return isnetname(key);
     320 } /* wk_is_netname() */
     321
     322 static int wk_is_autnum(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     323     return isasnum(key);
     324 } /* wk_is_autnum() */
     325
     326 static int wk_is_asrange(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     327     return perform_regex_test(ASRANGE, key);
     328 } /* wk_is_autnum() */
     329
     330 static int wk_is_assetname(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     331     return perform_regex_test(ASSETNAME, key);
     332 } /* wk_is_assetname() */
     333
     334 static int wk_is_routesetname(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     335     return perform_regex_test(ROUTESETNAME, key);
     336 } /* wk_is_routesetname() */
     337
     338 static int wk_is_domain(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     339     return isdomname(key);
     340 } /* wk_is_domname() */
     341
     342 static int wk_is_hostname(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     343   /* XXX Why is there a hostname & a domainname? */
     344   /* Answer - hostname can be a domainname or an IP */
     345     return (isdomname(key) || wk_is_iprange(key));
     346 } /* wk_is_hostname() */
     347
     348 static int wk_is_limerick(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     349     return perform_regex_test(LIMERICK, key);
     350 } /* wk_is_limerick() */
     351
     352 static int wk_is_peeringset(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     353     return perform_regex_test(PEERINGSET, key);
     354 } /* wk_is_peeringset() */
     355
     356 static int wk_is_rtrset(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     357     return perform_regex_test(RTRSET, key);
     358 } /* wk_is_rtrset() */
     359
     360 static int wk_is_filterset(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     361     return perform_regex_test(FILTERSET, key);
     362 } /* wk_is_filterset() */
     363
     364 /* WK_to_string() */
     365 /*++++++++++++++++++++++++++++++++++++++
     366   Convert the which keytypes bitmap into a string.
     367
     368   mask_t wk The which keytypes mask to be converted.
     369
     370   More:
     371   +html+ <PRE>
     372   Authors:
     373         ottrey
     374   +html+ </PRE><DL COMPACT>
     375   +html+ <DT>Online References:
     376   +html+ <DD><UL>
     377   +html+ </UL></DL>
     378
     379   ++++++++++++++++++++++++++++++++++++++*/
     380 char *WK_to_string(mask_t wk) {
         /* [<][>][^][v][top][bottom][index][help] */
     381
     382   return MA_to_string(wk, Keytypes);
     383
     384 } /* WK_to_string() */
     385
     386 /* WK_new() */
     387 /*++++++++++++++++++++++++++++++++++++++
     388   Create a new which keytypes bitmap.
     389
     390   char *key The key to be examined.
     391
     392   More:
     393   +html+ <PRE>
     394   Authors:
     395         ottrey
     396   +html+ </PRE><DL COMPACT>
     397   +html+ <DT>Online References:
     398   +html+ <DD><UL>
     399   +html+ </UL></DL>
     400
     401   ++++++++++++++++++++++++++++++++++++++*/
     402 mask_t WK_new(char *key) {
         /* [<][>][^][v][top][bottom][index][help] */
     403   mask_t wk;
     404
     405   wk = MA_new(MA_END);
     406
     407   MA_set(&wk, WK_NAME,         wk_is_name(key));
     408   MA_set(&wk, WK_NIC_HDL,      wk_is_nic_hdl(key));
     409   MA_set(&wk, WK_EMAIL,        wk_is_email(key));
     410   MA_set(&wk, WK_MNTNER,       wk_is_mntner(key));
     411   MA_set(&wk, WK_KEY_CERT,     wk_is_key_cert(key));
     412   MA_set(&wk, WK_IPADDRESS,    wk_is_ipaddress(key));
     413   MA_set(&wk, WK_IPRANGE,      wk_is_iprange(key));
     414   MA_set(&wk, WK_IPPREFIX,     wk_is_ipprefix(key));
     415   MA_set(&wk, WK_IP6PREFIX,    wk_is_ip6prefix(key));
     416   MA_set(&wk, WK_NETNAME,      wk_is_netname(key));
     417   MA_set(&wk, WK_NET6NAME,     wk_is_net6name(key));
     418   MA_set(&wk, WK_AUTNUM,       wk_is_autnum(key));
     419   MA_set(&wk, WK_ASSETNAME,    wk_is_assetname(key));
     420   MA_set(&wk, WK_ROUTESETNAME, wk_is_routesetname(key));
     421   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
     422   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
     423   MA_set(&wk, WK_LIMERICK,     wk_is_limerick(key));
     424   MA_set(&wk, WK_ASRANGE,      wk_is_asrange(key));
     425   MA_set(&wk, WK_PEERINGSET,   wk_is_peeringset(key));
     426   MA_set(&wk, WK_FILTERSET,    wk_is_filterset(key));
     427   MA_set(&wk, WK_RTRSET,       wk_is_rtrset(key));
     428
     429   return wk;
     430
     431 } /* WK_new() */

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