1    | /***************************************
2    |   $Revision: 1.16 $
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 VALIDIP6PREFIX "^[0-9A-F:]*:[0-9A-F:/]*$"     /* at least one colon */
50   | /* "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"*/
51   | 
52   | #define NET "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
53   | 
54   | #define ASNUM "^AS[1-9]+[0-9]{0,4}$"
55   | 
56   | #define ASRANGE "^AS[0-9]{1,5}[ ]*([-][ ]*AS[0-9]{1,5}){0,1}$"   /* [ ]*(-[ ]*AS[0-9]+)?   */
57   | 
58   | #define NETNAME "^[A-Z][A-Z0-9-]*$"
59   | 
60   | #define MAINTAINER "^[A-Z][A-Z0-9-]*$"
61   | 
62   | #define LIMERICK "^LIM-[A-Z0-9-]+$"
63   | 
64   | #define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
65   | 
66   | #define ROUTESETNAME "^RS-[A-Z0-9-_]*$"
67   | 
68   | #define ASSETNAME "^AS-[A-Z0-9-_]*$"
69   | 
70   | #define AUTONICPREFIXREGULAR "^AUTO-"
71   | 
72   | #define IPRANGE "^[0-9]{1,3}(\\.[0-9]{1,3}){0,3}[ ]*-[ ]*[0-9]{1,3}(\\.[0-9]{1,3}){0,3}$"
73   | 
74   | #define IPADDRESS "^[0-9.]+$"
75   | 
76   | #define IPPREFIX "^[0-9.]+/[0-9]+$"
77   | 
78   | #define PEERINGSET "^PRNG-"
79   | 
80   | #define FILTERSET  "^FLTR-"
81   | 
82   | #define RTRSET     "^RTRS-"
83   | 
84   | #define NICHANDLE "^[A-Z0-9-]+$"
85   | 
86   | /*
87   |   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
88   |   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
89   |   Does \w include [ ;:,?/}{()+*#] ?
90   | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
91   | */
92   | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
93   | 
94   | #define VALIDIP4PREFIX
95   | 
96   | #define EMAIL "^[.a-zA-Z0-9--]*@[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*$"
97   | 
98   | static int perform_regex_test(const char *pattern, char *string) {
99   |   int match;
100  | 
101  |   char *re;
102  | 
103  |   re = regcmp(pattern, (char*)0);
104  |   if (regex(re, string) == NULL) {
105  |     match = 0;
106  |   }
107  |   else {
108  |     match = 1;
109  |   }
110  | 
111  |   free(re); /* not a wrapper, because we have not allocated it */
112  | 
113  |   return match;
114  | } /* perform_regex_test() */
115  | 
116  | 
117  | static int isdomname(char *string) {
118  |     return (    perform_regex_test(DOMAINNAME, string)
119  | 	     && perform_regex_test(DOMAINALPHA, string));
120  | }
121  | 
122  | /*
123  |  I split the isname up into isname_a & isname_b.  And created isname_ab to join them together.
124  |   - So I can test it properly.  -ottrey
125  |  */
126  | static int isname_a(char *string) {
127  |     return perform_regex_test(AUTONICPREFIXREGULAR, string);
128  | }
129  | 
130  | static int isname_b(char *string) {
131  |     return perform_regex_test(NAME_B, string);
132  | }
133  | 
134  | static int isname_ab(char *string) {
135  |     return (isname_a(string) || isname_b(string));
136  | }
137  | 
138  | static int wk_is_name(char *key) {
139  |     /* Everything matches to name */
140  |     return 1;
141  | } /* wk_is_name() */
142  | 
143  | static int wk_is_domain(char *key) {
144  |     return isdomname(key);
145  | } /* wk_is_domname() */
146  | 
147  | static int wk_is_iprange(char *key) {
148  |   return perform_regex_test(IPRANGE, key);
149  | } /* wk_is_iprange() */
150  | 
151  | static int wk_is_hostname(char *key) {
152  |   /* XXX Why is there a hostname & a domainname? */
153  |   /* Answer - hostname can be a domainname or an IP */
154  |     return (isdomname(key) || wk_is_iprange(key));
155  | } /* wk_is_hostname() */
156  | 
157  | /* WK_to_string() */
158  | /*++++++++++++++++++++++++++++++++++++++
159  |   Convert the which keytypes bitmap into a string.
160  | 
161  |   mask_t wk The which keytypes mask to be converted.
162  | 
163  |   More:
164  |   +html+ <PRE>
165  |   Authors:
166  |         ottrey
167  |   +html+ </PRE><DL COMPACT>
168  |   +html+ <DT>Online References:
169  |   +html+ <DD><UL>
170  |   +html+ </UL></DL>
171  | 
172  |   ++++++++++++++++++++++++++++++++++++++*/
173  | char *WK_to_string(mask_t wk) {
174  | 
175  |   return MA_to_string(wk, Keytypes);
176  | 
177  | } /* WK_to_string() */
178  | 
179  | /* WK_new() */
180  | /*++++++++++++++++++++++++++++++++++++++
181  |   Create a new which keytypes bitmap.
182  | 
183  |   char *key The key to be examined.
184  | 
185  |   More:
186  |   +html+ <PRE>
187  |   Authors:
188  |         ottrey
189  |   +html+ </PRE><DL COMPACT>
190  |   +html+ <DT>Online References:
191  |   +html+ <DD><UL>
192  |   +html+ </UL></DL>
193  | 
194  |   ++++++++++++++++++++++++++++++++++++++*/
195  | mask_t WK_new(char *key) {
196  |   mask_t wk; 
197  | 
198  |   wk = MA_new(MA_END);
199  | 
200  |   MA_set(&wk, WK_NAME,         wk_is_name(key));
201  |   MA_set(&wk, WK_NIC_HDL,      perform_regex_test(NICHANDLE, key));
202  |   MA_set(&wk, WK_EMAIL,        perform_regex_test(EMAIL, key));
203  |   MA_set(&wk, WK_MNTNER,       perform_regex_test(MAINTAINER, key));
204  |   MA_set(&wk, WK_KEY_CERT,     perform_regex_test(KEYCERT, key));
205  |   MA_set(&wk, WK_IPADDRESS,    perform_regex_test(IPADDRESS, key));
206  |   MA_set(&wk, WK_IPRANGE,      wk_is_iprange(key));
207  |   MA_set(&wk, WK_IPPREFIX,     perform_regex_test(IPPREFIX, key));
208  |   MA_set(&wk, WK_IP6PREFIX,    perform_regex_test(VALIDIP6PREFIX, key));
209  |   MA_set(&wk, WK_NETNAME,      perform_regex_test(NETNAME, key));
210  |   MA_set(&wk, WK_NET6NAME,     perform_regex_test(NETNAME, key));
211  |   MA_set(&wk, WK_AUTNUM,       perform_regex_test(ASNUM, key));
212  |   MA_set(&wk, WK_ASSETNAME,    perform_regex_test(ASSETNAME, key));
213  |   MA_set(&wk, WK_ROUTESETNAME, perform_regex_test(ROUTESETNAME, key));
214  |   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
215  |   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
216  |   MA_set(&wk, WK_LIMERICK,     perform_regex_test(LIMERICK, key));
217  |   MA_set(&wk, WK_ASRANGE,      perform_regex_test(ASRANGE, key));
218  |   MA_set(&wk, WK_PEERINGSET,   perform_regex_test(PEERINGSET, key));
219  |   MA_set(&wk, WK_FILTERSET,    perform_regex_test(FILTERSET, key));
220  |   MA_set(&wk, WK_RTRSET,       perform_regex_test(RTRSET, key));
221  |   
222  |   return wk;
223  | 
224  | } /* WK_new() */