Move .gitignore to lib/ in preparation for moving lib to the root.
[libradsec.git] / radius / common.pl
1 ######################################################################
2 # Copyright (c) 2011, Network RADIUS SARL
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are met:
7 #     * Redistributions of source code must retain the above copyright
8 #       notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above copyright
10 #       notice, this list of conditions and the following disclaimer in the
11 #       documentation and/or other materials provided with the distribution.
12 #     * Neither the name of the <organization> nor the
13 #       names of its contributors may be used to endorse or promote products
14 #       derived from this software without specific prior written permission.
15
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 # DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ######################################################################
27 our %attributes;
28 our %vendor;
29 our %vendorpec;
30 our $begin_vendor = 0;
31
32 $vendorpec{'0'} = "IETF";
33
34 sub do_file()
35 {
36     my $filename = shift;
37     my $fh;
38
39     $dir = $filename;
40     $dir =~ s:/[^/]+?$::;
41     $lineno = 0;
42
43     open $fh, "<$filename" or die "Failed to open $filename: $!\n";
44
45     while (<$fh>) {
46         $lineno++;
47         next if (/^\s*#/);
48         next if (/^\s*$/);
49         s/#.*//;
50         s/\s+$//;
51
52         next if ($_ eq "");
53
54         #
55         #  Remember the vendor
56         #
57         if (/^VENDOR\s+([\w-]+)\s+(\w+)(.*)/) {
58             my $me = $1;
59
60             $vendor{$me}{'pec'} = $2;
61             $vendorpec{$2} = $me;
62
63             $vendor{$me}{'type'} = 1;
64             $vendor{$me}{'length'} = 1;
65
66             if ($3) {
67                 $format=$3;
68                 $format =~ s/^\s+//;
69
70                 if ($format !~ /^format=(\d+),(\d+)$/) {
71                     die "Unknown format $format\n";
72                 }
73                 $vendor{$me}{'type'} = $1;
74                 $vendor{$me}{'length'} = $2;
75             }
76             next;
77         }
78
79         #
80         #  Remember if we did begin-vendor.
81         #
82         if (/^BEGIN-VENDOR\s+([\w-]+)/) {
83             if (!defined $vendor{$1}) {
84                 die "Unknown vendor $1\n";
85             }
86             $begin_vendor = $vendor{$1}{'pec'};
87             next;
88         }
89
90         #
91         #  Remember if we did this.
92         #
93         if (/^END-VENDOR/) {
94             $begin_vendor = 0;
95             next;
96         }
97
98         #
99         #  Get attribute.
100         #
101         if (/^ATTRIBUTE\s+([\w-\/.]+)\s+(\w+)\s+(\w+)(.*)/) {
102             $name=$1;
103             $value = $2;
104             $type = $3;
105             $stuff = $4;
106
107             $value =~ tr/[A-F]/[a-f]/; # normal form for hex
108             $value =~ tr/X/x/;
109
110             if ($value =~ /^0x/) {
111                 $index = hex $value;
112             } else {
113                 $index = $value;
114             }
115
116             next if (($begin_vendor == 0) && ($index > 255));
117
118             $index += ($begin_vendor << 16);
119
120             $attributes{$index}{'name'} = $name;
121             $attributes{$index}{'value'} = $value;
122             if ($begin_vendor ne "") {
123                 $attributes{$index}{'vendor'} = $begin_vendor;
124             }
125
126             $type =~ tr/a-z/A-Z/;
127             $attributes{$index}{'type'} = "RS_TYPE_$type";
128
129             $stuff =~ s/^\s*//;
130
131             if ($stuff) {
132                 foreach $text (split /,/, $stuff) {
133                     if ($text eq "encrypt=1") {
134                         $attributes{$index}{'flags'}{'encrypt'} = "FLAG_ENCRYPT_USER_PASSWORD";
135                     } elsif ($text eq "encrypt=2") {
136                         $attributes{$index}{'flags'}{'encrypt'} = "FLAG_ENCRYPT_TUNNEL_PASSWORD";
137
138                         } elsif ($text eq "encrypt=3") {
139                         $attributes{$index}{'flags'}{'encrypt'} = "FLAG_ENCRYPT_ASCEND_SECRET";
140
141                     } elsif ($text eq "has_tag") {
142                         $attributes{$index}{'flags'}{'has_tag'} = "1";
143
144                     } elsif ($text =~ /\[(\d+)\]/) {
145                         $attributes{$index}{'flags'}{'length'} = $1;
146                         
147                     } else {
148                         die "$filename: $lineno - Unknown flag $text\n";
149                     }
150                 }
151             }
152
153             if ($type eq "BYTE") {
154                 $attributes{$index}{'flags'}{'length'} = "1";
155                 
156             } elsif ($type eq "SHORT") {
157                 $attributes{$index}{'flags'}{'length'} = "2";
158                 
159             } elsif ($type eq "INTEGER") {
160                 $attributes{$index}{'flags'}{'length'} = "4";
161                 
162             } elsif ($type eq "IPADDR") {
163                 $attributes{$index}{'flags'}{'length'} = "4";
164                 
165             } elsif ($type eq "DATE") {
166                 $attributes{$index}{'flags'}{'length'} = "4";
167                 
168             } elsif ($type eq "IFID") {
169                 $attributes{$index}{'flags'}{'length'} = "8";
170                 
171             } elsif ($type eq "IPV6ADDR") {
172                 
173                 $attributes{$index}{'flags'}{'length'} = "16";
174             }
175
176             $name2val{$name} = $index;
177             next;
178         }
179
180         #
181         #  Values.
182         #
183         if (/^VALUE\s+([\d\w-\/.]+)\s+([\w-\/,.+]+)\s+(\w+)(.*)/) {
184             next;
185
186             $attr = $1;
187             $name = $2;
188             $value = $3;
189             $stuff = $d;
190
191             $value =~ tr/[A-F]/[a-f]/; # normal form for hex
192             $value =~ tr/X/x/;
193
194             if ($value =~ /^0x/) {
195                 $index = hex $value;
196             } else {
197                 $index = $value;
198             }
199
200             if (!defined $name2val{$attr}) {
201                 print "# FIXME: FORWARD REF?\nVALUE $attr $name $value$stuff\n";
202                 next;
203             }
204
205             $values{$name2val{$attr}}{$index} = "$attr $name $value$stuff";
206             next;
207         }
208
209         if (/^\$INCLUDE\s+(.*)$/) {
210             do_file("$dir/$1");
211             next;
212         }
213
214         die "unknown text in line $lineno of $filename: $_\n";
215     }
216
217     close $fh;
218 }
219
220 1;