1    | /***************************************
2    |   $Revision: 1.18 $
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                              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 <libgen.h>
34   | #include <glib.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   | 
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   | /*****************************************************************/
99   | 
100  | static int perform_regex_test(const char *pattern, char *string)
101  | {
102  | 
103  |   int match = 0;
104  | 
105  |   /* These are not used, since REG_NOSUB is specified in regcomp() */
106  |   size_t nmatch = 0;
107  |   regmatch_t pmatch[1];
108  |   regex_t re;
109  |   int err;
110  | 
111  |   if( (err = regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB)) != 0) 
112  |     {
113  |       char erbuf[2048];      
114  |       regerror(err,&re,erbuf,sizeof(erbuf));
115  |       die;
116  |     }
117  |   if (regexec(&re, string, nmatch, pmatch, 0))
118  |     match = 0;
119  |   else
120  |     match = 1;
121  | 
122  |   regfree(&re);
123  | 
124  |   return(match);
125  | 
126  | } 
127  | 
128  | /*
129  |  I split the isname up into isname_a & isname_b.  And created isname_ab to join them together.
130  |   - So I can test it properly.  -ottrey
131  |  */
132  | #if 0
133  | static int isname_a(char *string) {
134  |     return perform_regex_test(AUTONICPREFIXREGULAR, string);
135  | }
136  | 
137  | static int isname_b(char *string) {
138  |     return perform_regex_test(NAME_B, string);
139  | }
140  | 
141  | static int isname_ab(char *string) {
142  |     return (isname_a(string) || isname_b(string));
143  | }
144  | #endif 
145  | 
146  | static int wk_is_name(char *key) {
147  |     /* Everything matches to name */
148  |     return 1;
149  | } /* wk_is_name() */
150  | 
151  | /***************************************************************/
152  | 
153  | static int isdomname(char *string) {
154  |     return (    perform_regex_test(DOMAINNAME, string)
155  | 	     && perform_regex_test(DOMAINALPHA, string));
156  | }
157  | 
158  | static int wk_is_domain(char *key) {
159  |     return isdomname(key);
160  | } /* wk_is_domname() */
161  | 
162  | static int wk_is_iprange(char *key) {
163  |   return perform_regex_test(IPRANGE, key);
164  | } /* wk_is_iprange() */
165  | 
166  | static int wk_is_hostname(char *key) {
167  |   /* XXX Why is there a hostname & a domainname? */
168  |   /* Answer - hostname can be a domainname or an IP */
169  |     return (isdomname(key) || wk_is_iprange(key));
170  | } /* wk_is_hostname() */
171  | 
172  | /* WK_to_string() */
173  | /*++++++++++++++++++++++++++++++++++++++
174  |   Convert the which keytypes bitmap into a string.
175  | 
176  |   mask_t wk The which keytypes mask to be converted.
177  | 
178  |   More:
179  |   +html+ <PRE>
180  |   Authors:
181  |         ottrey
182  |   +html+ </PRE><DL COMPACT>
183  |   +html+ <DT>Online References:
184  |   +html+ <DD><UL>
185  |   +html+ </UL></DL>
186  | 
187  |   ++++++++++++++++++++++++++++++++++++++*/
188  | char *WK_to_string(mask_t wk) {
189  | 
190  |   return MA_to_string(wk, Keytypes);
191  | 
192  | } /* WK_to_string() */
193  | 
194  | /* WK_new() */
195  | /*++++++++++++++++++++++++++++++++++++++
196  |   Create a new which keytypes bitmap.
197  | 
198  |   char *key The key to be examined.
199  | 
200  |   More:
201  |   +html+ <PRE>
202  |   Authors:
203  |         ottrey
204  |   +html+ </PRE><DL COMPACT>
205  |   +html+ <DT>Online References:
206  |   +html+ <DD><UL>
207  |   +html+ </UL></DL>
208  | 
209  |   ++++++++++++++++++++++++++++++++++++++*/
210  | mask_t WK_new(char *key) {
211  |   mask_t wk; 
212  | 
213  |   wk = MA_new(MA_END);
214  | 
215  |   MA_set(&wk, WK_NAME,         wk_is_name(key));
216  |   MA_set(&wk, WK_NIC_HDL,      perform_regex_test(NICHANDLE, key));
217  |   MA_set(&wk, WK_EMAIL,        perform_regex_test(EMAIL, key));
218  |   MA_set(&wk, WK_MNTNER,       perform_regex_test(MAINTAINER, key));
219  |   MA_set(&wk, WK_KEY_CERT,     perform_regex_test(KEYCERT, key));
220  |   MA_set(&wk, WK_IPADDRESS,    perform_regex_test(IPADDRESS, key));
221  |   MA_set(&wk, WK_IPRANGE,      wk_is_iprange(key));
222  |   MA_set(&wk, WK_IPPREFIX,     perform_regex_test(IPPREFIX, key));
223  |   MA_set(&wk, WK_IP6PREFIX,    perform_regex_test(VALIDIP6PREFIX, key));
224  |   MA_set(&wk, WK_NETNAME,      perform_regex_test(NETNAME, key));
225  |   MA_set(&wk, WK_NET6NAME,     perform_regex_test(NETNAME, key));
226  |   MA_set(&wk, WK_AUTNUM,       perform_regex_test(ASNUM, key));
227  |   MA_set(&wk, WK_ASSETNAME,    perform_regex_test(ASSETNAME, key));
228  |   MA_set(&wk, WK_ROUTESETNAME, perform_regex_test(ROUTESETNAME, key));
229  |   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
230  |   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
231  |   MA_set(&wk, WK_LIMERICK,     perform_regex_test(LIMERICK, key));
232  |   MA_set(&wk, WK_ASRANGE,      perform_regex_test(ASRANGE, key));
233  |   MA_set(&wk, WK_PEERINGSET,   perform_regex_test(PEERINGSET, key));
234  |   MA_set(&wk, WK_FILTERSET,    perform_regex_test(FILTERSET, key));
235  |   MA_set(&wk, WK_RTRSET,       perform_regex_test(RTRSET, key));
236  |   
237  |   return wk;
238  | 
239  | } /* WK_new() */