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