modules/wk/which_keytypes.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- perform_regex_test
- isasnum
- isnichandle
- isdomname
- isname_a
- isname_b
- isname_ab
- isnetname
- wk_is_name
- wk_is_nic_hdl
- wk_is_email
- wk_is_mntner
- wk_is_key_cert
- wk_is_ipaddress
- wk_is_iprange
- wk_is_ipprefix
- wk_is_ip6prefix
- wk_is_netname
- wk_is_net6name
- wk_is_autnum
- wk_is_asrange
- wk_is_assetname
- wk_is_routesetname
- wk_is_domain
- wk_is_hostname
- wk_is_limerick
- wk_is_peeringset
- wk_is_rtrset
- wk_is_filterset
- WK_to_string
- 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() */