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() */