~ubuntu-branches/ubuntu/intrepid/asn1c/intrepid

« back to all changes in this revision

Viewing changes to asn1c/webcgi/asn1c.cgi

  • Committer: Bazaar Package Importer
  • Author(s): W. Borgert
  • Date: 2005-05-28 12:36:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050528123642-3h6kstws5u0xcovl
Tags: upstream-0.9.14
ImportĀ upstreamĀ versionĀ 0.9.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
#
 
3
# $Id: asn1c.cgi,v 1.20 2005/04/28 02:55:35 vlm Exp $
 
4
#
 
5
 
 
6
############################################################################
 
7
# The following preferences may be modified to match the local environment #
 
8
############################################################################
 
9
 
 
10
# Directory with the users data.
 
11
$TMPDIR = '/tmp/asn1c-cgi-jail/';
 
12
$SUIDHelper = './asn1c-suid-helper';
 
13
$SkeletonsDir = '/usr/local/share/asn1c';       # Will be needed only once
 
14
$CompilerLocation = '/usr/local/bin/asn1c';     # asn1c binary location
 
15
$HelpDBFile = $TMPDIR . '/var/db/Help-DB';      # Help requests database
 
16
$HashProgramPath = 'md5';                       # Program to hash the input
 
17
$DM = 0750;                                     # Directory mode for all mkdirs
 
18
$MaxHistoryItems = 5;                           # Number of items in History
 
19
$DynamicHistory = 'yes';                        # Full/Short history
 
20
$safeFilenameRE = '[a-zA-Z0-9_]+[.a-zA-Z0-9_-]{0,200}';  # Safe filename regex
 
21
$safeTimeRE = '[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}';
 
22
$ASN1C_Page = 'http://lionet.info/asn1c';
 
23
$HelpEmail = 'asn1c@lionet.info';
 
24
$defaultUserEmail = 'your@email-for-reply';
 
25
$DataERR = 65;                                  # EX_DATAERR from <sysexits.h>
 
26
 
 
27
$warn = '<CENTER><FONT SIZE=+1><B>';
 
28
$unwarn = '</B></FONT></CENTER>';
 
29
 
 
30
$OpEnvFailed = 'Failed to create the operations\' environment:';
 
31
$RandFailed = 'No source of randomness';
 
32
$SandBoxInitFailed = 'User playground initialization failed';
 
33
 
 
34
$myName = $ENV{SCRIPT_NAME};    # URL of this particular script (without args)
 
35
 
 
36
$homePath = "<FONT FACE=Courier SIZE=-1>"
 
37
        . "<A HREF=http://lionet.info>Home</A>"
 
38
        . " &gt;&gt; <A HREF=$ASN1C_Page>asn1c</A>"
 
39
        . " &gt;&gt; <A HREF=$ASN1C_Page/asn1c.cgi>Free Online ASN.1 Compiler</A>"
 
40
        . "</FONT><P>";
 
41
 
 
42
###################################################
 
43
# The code below rarely requires any modification #
 
44
###################################################
 
45
 
 
46
use CGI qw/param cookie header upload escapeHTML/;
 
47
 
 
48
$|=1;   # Enable AutoFlush (for older versions of Perl)
 
49
 
 
50
my %binaryDecoders = (
 
51
        x509 => { order => 1,
 
52
                type => 'X.509 Certificate',
 
53
                typeExt => 'X.509 Certificate',
 
54
                exe => 'x509dump',
 
55
                cmdopts => '-x',
 
56
                msg => ''
 
57
                },
 
58
 
 
59
        tap0311 => { order => 2,
 
60
                type => TAP3,
 
61
                typeExt => 'GSM TAP3-11 data',
 
62
                exe => 'tap3dump-11',
 
63
                cmdopts => '-x',
 
64
                msg => ''
 
65
                },
 
66
 
 
67
        tap0310 => { order => 3,
 
68
                type => TAP3,
 
69
                typeExt => 'GSM TAP3-10 data',
 
70
                exe => 'tap3dump-10',
 
71
                cmdopts => '-x',
 
72
                msg => ''
 
73
                },
 
74
 
 
75
        tap0309 => { order => 4,
 
76
                type => TAP3,
 
77
                typeExt => 'GSM TAP3-09 data',
 
78
                exe => 'tap3dump-09',
 
79
                cmdopts => '-x',
 
80
                msg => ''
 
81
                },
 
82
 
 
83
        mheg5 => { order => 5,
 
84
                type => 'MHEG-5',
 
85
                typeExt => 'ISO MHEG-5 data',
 
86
                exe => 'mheg5dump',
 
87
                cmdopts => '-x',
 
88
                msg => ''
 
89
                },
 
90
 
 
91
        ber => { order => 6,
 
92
                type => BER,
 
93
                typeExt => 'BER encoded data',
 
94
                exe => 'unber',
 
95
                cmdopts => '',
 
96
                msg => "<!-- Use 'enber' to convert it back into BER -->\n"
 
97
                }
 
98
);
 
99
 
 
100
my $redirect = '';      # No redirection by default
 
101
my $redirect_bottom = '';       # No redirection text by default
 
102
my $content = '';       # Default content is empty
 
103
 
 
104
sub IssueRedirect() {
 
105
        $redirect = "<META HTTP-EQUIV=\"Refresh\" "
 
106
                . "CONTENT=\"5; URL=$myName\">";
 
107
        $redirect_bottom = "<P><CENTER>This page will <A HREF=$myName>disappear</A> in 5 seconds.</CENTER>"
 
108
}
 
109
 
 
110
# If something goes wrong, this function is invoked to display the error message
 
111
sub bark($@) {
 
112
        local $_ = join("<BR>\n", @_);
 
113
        $content = $warn . $_ . $unwarn;
 
114
        goto PRINTOUT;
 
115
}
 
116
 
 
117
# Make the directory name containing session files for the given Session ID
 
118
sub makeSessionDirName($$) {
 
119
        my $pfx = shift;        # Prefix is the name of the top-level directory
 
120
        my $sid = shift;        # Session identifier (md5)
 
121
        $pfx . '/sessions/' . $sid . '/';
 
122
}
 
123
 
 
124
# Create ISO 8601 time string: "YYYY-MM-DDThh:mm:ss"
 
125
my $cachedTime;
 
126
sub isoTime() {
 
127
        return $cachedTime if $cachedTime;
 
128
        my @tm = localtime(time);
 
129
 
 
130
        $tm[5] += 1900;
 
131
        $tm[4] += 1;
 
132
 
 
133
        # Insert leading zeros
 
134
        for(my $i = 0; $i < 5; $i++) {
 
135
                $tm[$i] =~ s/^(.)$/0$1/;
 
136
        }
 
137
 
 
138
        $cachedTime = "$tm[5]-$tm[4]-$tm[3]T$tm[2]:$tm[1]:$tm[0]";
 
139
}
 
140
 
 
141
# Create the necessary environment for chrooting into.
 
142
sub prepareChrootEnvironment() {
 
143
        return 1 if(-d $TMPDIR);        # Envuronment already exists
 
144
        mkdir $TMPDIR, $DM, or bark($OpEnvFailed, $!);  # Global directory
 
145
        mkdir $TMPDIR . 'sessions', $DM or bark($OpEnvFailed, $!); # sessions
 
146
        mkdir $TMPDIR . 'bin', $DM or bark($OpEnvFailed, $!);   # asn1c location
 
147
        mkdir $TMPDIR . 'skeletons', $DM or bark($OpEnvFailed, $!); # asn1c data
 
148
        mkdir $TMPDIR . 'var', $DM or bark($OpEnvFailed, $!);
 
149
        mkdir $TMPDIR . 'var/db', $DM or bark($OpEnvFailed, $!);
 
150
        if(-d '/lib') {
 
151
                # Merge in dynamic libc
 
152
                mkdir $TMPDIR . 'lib', $DM or bark($OpEnvFailed, $!);
 
153
                system("cd $TMPDIR/lib && "
 
154
                        . "for i in"
 
155
                                . " /lib/ld-linux.*"    # Linux ELF loader
 
156
                                . " /lib/libc.*"        # Standard C library
 
157
                                . " /lib/libm.*"        # Math library
 
158
                        . '; do ln $i; done');
 
159
        } elsif(-d '/usr/lib') {
 
160
                # There's no /lib on MacOS
 
161
                mkdir $TMPDIR . 'usr', $DM or bark($OpEnvFailed, $!);
 
162
                mkdir $TMPDIR . 'usr/lib', $DM or bark($OpEnvFailed, $!);
 
163
                mkdir $TMPDIR . 'usr/lib/system', $DM or bark($OpEnvFailed, $!);
 
164
                system("cd $TMPDIR/usr/lib && "
 
165
                        . "for i in"
 
166
                                . " /usr/lib/libc.*"
 
167
                                . " /usr/lib/libSystem.*"
 
168
                                . " /usr/lib/system/libmath*"
 
169
                                . " /usr/lib/dy*"
 
170
                        . '; do ln $i; done');
 
171
        }
 
172
        if(-d '/usr/libexec') {
 
173
                # FreeBSD ELF loader
 
174
                mkdir $TMPDIR . 'usr', $DM;
 
175
                mkdir $TMPDIR . 'usr/libexec',$DM or bark($OpEnvFailed, $!);
 
176
                system("cd $TMPDIR/usr/libexec && "
 
177
                        . 'for i in /usr/libexec/ld-elf.*; do ln $i; done');
 
178
        }
 
179
        system("cp $CompilerLocation $TMPDIR/bin 2>/dev/null") == 0
 
180
                or bark($OpEnvFailed, $!);
 
181
        system("cp -r $SkeletonsDir/* $TMPDIR/skeletons >/dev/null 2>&1") == 0
 
182
                        or bark($OpEnvFailed, $!);
 
183
        return 1;
 
184
}
 
185
 
 
186
sub makeArchive($$) {
 
187
        my $TMPDIR = shift;
 
188
        my $sandbox = shift;
 
189
        my $archName = $sandbox . '/+Archive.tgz';
 
190
 
 
191
        if(! -f $archName) {
 
192
                system("cd $sandbox && "
 
193
                        . "for i in ./*.[ch]; do if [ -L \$i ]; then"
 
194
                        . " cp $TMPDIR/skeletons/\$i \$i.-;"
 
195
                        . " mv \$i.- \$i;"
 
196
                        . " fi done && tar --dereference --ignore-failed-read --owner nobody --group nobody -zcf +tmp." . $$ . " *.[ch] Makefile* +Compiler.Log *.asn *.asn1"
 
197
                        . " && rm -f ./*.[ch] ./Makefile*"
 
198
                        . " && mv ./+tmp." . $$ . " $archName"
 
199
                        . " || rm -f ./+tmp." . $$);
 
200
                undef unless -f $archName;
 
201
        }
 
202
 
 
203
        $archName;
 
204
}
 
205
 
 
206
my $EnvironmentSetOK = prepareChrootEnvironment();
 
207
 
 
208
#
 
209
# Record user's email.
 
210
#
 
211
$userEmail = cookie('userEmail');
 
212
$userEmail = $defaultUserEmail unless defined($userEmail);
 
213
$tmpEmail = param('email');
 
214
if(defined($tmpEmail)) {
 
215
        unless($tmpEmail =~ /^\s*([a-z0-9._+-]+@[a-z0-9.+-]+)\s*$/i) {
 
216
                bark("Invalid email address: "
 
217
                        . "<B><FONT COLOR=darkred>$tmpEmail</FONT></B>");
 
218
        }
 
219
        my $previousEmail = $userEmail;
 
220
        $userEmail = $1;
 
221
        if($userEmail eq $defaultUserEmail) {
 
222
                IssueRedirect();
 
223
                bark("Please enter <FONT COLOR=red>your own</FONT> "
 
224
                        . "valid email address, "
 
225
                        . "instead of default \"<FONT COLOR=darkred>$defaultUserEmail</FONT>\"");
 
226
        }
 
227
        if($userEmail ne $previousEmail) {
 
228
                # Refresh cookie contents.
 
229
                my $ck = cookie(-name=>'userEmail',
 
230
                        -value=>$userEmail,
 
231
                        -path=>'/', -expires=>'+1d');
 
232
                print "Set-Cookie: " . $ck . "\n";
 
233
        }
 
234
}
 
235
 
 
236
#
 
237
# Check if full history requested.
 
238
#
 
239
$HistoryShow = cookie('HistoryShow');
 
240
$HistoryShow = '' unless $HistoryShow;
 
241
$tmpHSParam = param('history'); # Control cookie setting
 
242
if (defined($tmpHSParam)
 
243
 && $tmpHSParam ne $HistoryShow
 
244
 && $tmpHSParam =~ /^(full|short)$/) {
 
245
        $HistoryShow = $tmpHSParam;
 
246
        my $ck = cookie(-name=>'HistoryShow',
 
247
                -value=>$HistoryShow,
 
248
                -path=>'/', -expires=>'+1h');
 
249
        print "Set-Cookie: " . $ck . "\n";
 
250
}
 
251
 
 
252
#
 
253
# Prepare the session and create the session directory.
 
254
# If session exists, perfom arguments checking and execute historic views.
 
255
#
 
256
$session = cookie('SessionID');
 
257
unless($session) {
 
258
        $session = '';
 
259
        open(R, '/dev/urandom')
 
260
                or open(R, '/dev/random')
 
261
                        or bark($RandFailed);
 
262
        read(R, $session, 16) == 16 or bark("Not enough randomness");
 
263
        if($ENV{HTTP_USER_AGENT}) {
 
264
                $session .= $ENV{HTTP_USER_AGENT};      # Add randomness
 
265
        }
 
266
        my $pid = open(R, "-|");
 
267
        if($pid == 0) { # Child
 
268
                open(W, "| $HashProgramPath") or die;
 
269
                print W $session;
 
270
                exit(0);
 
271
        }
 
272
        $session = <R>;
 
273
        $session =~ s/[^a-f0-9]//ig;
 
274
        bark("md5 program is rotten here") if(length($session) != 32);
 
275
        $sessionDir = makeSessionDirName($TMPDIR, $session);
 
276
        mkdir($sessionDir, $DM) or bark($SandBoxInitFailed);
 
277
        my $ck = cookie(-name=>'SessionID', -value=>$session,
 
278
                        -path=>'/', -expires=>'+1y');
 
279
        print "Set-Cookie: " . $ck . "\n";
 
280
} else {
 
281
        $session =~ s/[^a-f0-9]//ig;
 
282
        bark("Nope, try again") if(length($session) != 32);     # cool hacker?
 
283
 
 
284
        # Make sure the session directory exists
 
285
        $sessionDir = makeSessionDirName($TMPDIR, $session);
 
286
        mkdir($sessionDir, $DM) or bark($SandBoxInitFailed)
 
287
                unless(-d $sessionDir);
 
288
 
 
289
        my $t = param('time');
 
290
        my $file = param('file');
 
291
        my $fetch = param('fetch');
 
292
        my $show = param('show');
 
293
        my $remove = param('remove');
 
294
 
 
295
        unless(defined($t) && defined($file)
 
296
                && $t =~ /^${safeTimeRE}$/
 
297
                && $file =~ /^${safeFilenameRE}$/
 
298
                && ($fetch eq '' or $fetch =~ /^${safeFilenameRE}$/)
 
299
        ) {
 
300
                $file = '';
 
301
                $fetch = '';
 
302
                $show = '';
 
303
                $remove = '';
 
304
        }
 
305
        if($fetch ne '' or $show =~ /^(log|unber|tgz)$/ or $remove ne '') {
 
306
                my $sandbox = $sessionDir . '/' . $t . '--' . $file;
 
307
                my $targetFile = '';
 
308
 
 
309
                if($show eq 'tgz') {
 
310
                        my $tarball = makeArchive($TMPDIR, $sandbox);
 
311
                        defined $tarball
 
312
                                or bark("Cannot create archive [$sandbox]");
 
313
 
 
314
                        printf("Content-Type: application/x-tar\n");
 
315
                        printf("Content-Encoding: gzip\n\n");
 
316
                        exec("cat $tarball");
 
317
                        exit(0);
 
318
                } elsif($show eq 'unber') {
 
319
                        $targetFile = $sandbox . '/+UNBER';
 
320
                } elsif($show eq 'log') {
 
321
                        $targetFile = $sandbox . '/+Compiler.Log';
 
322
                } elsif($remove ne '') {
 
323
                        print "Status: 303 See Other\n";
 
324
                        print "Location: $myName\n";
 
325
                        print "\n";
 
326
                        rename($sandbox,
 
327
                                $sessionDir . '/' . $t . '-R--' . $file);
 
328
                        exit(0);
 
329
                } else {
 
330
                        $targetFile = $sandbox . '/' . $fetch;
 
331
                }
 
332
                if($targetFile ne '') {
 
333
                        open(I, '< ' . $targetFile)
 
334
                                or bark("Invalid or outdated request $!");
 
335
                        printf "Content-Type: text/plain\n\n";
 
336
                        print while <I>;
 
337
                        exit(0);
 
338
                }
 
339
        }
 
340
}
 
341
 
 
342
#
 
343
# Check if transaction help is requested.
 
344
#
 
345
$transHelp = param('transHelp');
 
346
if(defined($transHelp)
 
347
&& $transHelp =~ /^([0-9]+)--($safeTimeRE)--($safeFilenameRE)$/) {
 
348
        open(S, "| sendmail -it")
 
349
                or bark("Cannot perform help request, "
 
350
                        . "please email to the address below");
 
351
        print S "From: $userEmail\n";
 
352
        print S "To: $HelpEmail\n";
 
353
        print S "Subject: asn1c help requested for $3 ($1) by $userEmail\n";
 
354
        print S "\n";
 
355
        print S "\n-- \n";
 
356
        print S "User $userEmail requested help with\n";
 
357
        print S "$session/$2--$3 ($1)\n";
 
358
        close(S);
 
359
 
 
360
        open(S, '>> ' . $sessionDir . '/' . $2 . '--' . $3 . '/+HelpReq')
 
361
                or bark("Cannot perform help request, "
 
362
                        . "please email to the address below");
 
363
        print S "$userEmail\n";
 
364
        close(S);
 
365
 
 
366
        open(S, '>> ' . $HelpDBFile);   # Susceptible to race condition.
 
367
        print S "$session/$2--$1--$3\n";
 
368
        close(S);
 
369
 
 
370
        $content = '<CENTER>Transaction '
 
371
                . "$1 ($3) is marked for manual processing.<BR>"
 
372
                . "Results will be mailed to "
 
373
                . "<FONT COLOR=darkgreen>$userEmail</FONT> shortly."
 
374
                . "</CONTENT>";
 
375
        IssueRedirect();
 
376
        goto PRINTOUT;
 
377
}
 
378
 
 
379
open(LOG, ">> $sessionDir/+logfile") or bark("Sandbox error: $!");
 
380
print LOG isoTime() . "\tIP=$ENV{REMOTE_ADDR}";
 
381
print LOG "\tEMAIL=$userEmail" if($userEmail ne $defaultUserEmail);
 
382
 
 
383
@gotSafeNames = ();
 
384
@gotNames = param('file');
 
385
if($#gotNames != -1 && $gotNames[0] ne "") {
 
386
        $gotFile = param('file');
 
387
        @gotFiles = upload('file');
 
388
} else {
 
389
        @gotNames = ();
 
390
        @gotFiles = ();
 
391
        $gotFile = undef;
 
392
}
 
393
 
 
394
my $asnText = param('text');
 
395
 
 
396
if($#gotNames == -1) {
 
397
        push(@gotNames, 'module.asn1') if $asnText;
 
398
}
 
399
 
 
400
# Make safe filenames
 
401
foreach my $fname (@gotNames) {
 
402
        local $_ = $fname;
 
403
        s/.*\///g;      # Strip directory components
 
404
        s/.*\\//g;      # Strip directory components (DOS version)
 
405
        s/^[.-]/_/g;    # Don't allow filenames starting with a dot or a dash
 
406
        s/[^._a-zA-Z0-9-]/_/g;
 
407
        if(!length($_)) {
 
408
                print LOG "\n";
 
409
                bark("Too strange filename: \"$fname\"");
 
410
        }
 
411
        $_ .= '.asn1' unless(/asn[1]{0,1}$/i);
 
412
        @gotSafeNames = (@gotSafeNames, $_);
 
413
        print LOG "\t" . $_;
 
414
}
 
415
 
 
416
#
 
417
# Save the files and start compilation process.
 
418
#
 
419
if($#gotSafeNames >= 0) {
 
420
        $transactionDir = isoTime() . '--' . join("-", @gotSafeNames);
 
421
        print LOG "\tDST=$transactionDir";
 
422
 
 
423
        my $sandbox = $sessionDir . '/' . $transactionDir;
 
424
        mkdir($sandbox, $DM) or bark($SandBoxInitFailed);
 
425
 
 
426
        open(O, '> ' . $sandbox . '/+Names');
 
427
        print O join("\n", @gotNames);
 
428
        open(O, '> ' . $sandbox . '/+safeNames');
 
429
        print O join("\n", @gotSafeNames);
 
430
        for(my $i = 0; $i <= $#gotSafeNames; $i++) {
 
431
                my $name = $gotSafeNames[$i];
 
432
                open(O, '> ' . $sandbox . '/'. $name);
 
433
                if($#gotFiles == -1) {
 
434
                        print O $asnText;       # param(text)
 
435
                        unlink $sessionDir . '/lastText';
 
436
                        symlink $transactionDir . '/' . $name,
 
437
                                $sessionDir . '/lastText';
 
438
                } else {
 
439
                        # Save the uploaded data into specified file
 
440
                        print O while <$gotFile>;
 
441
                }
 
442
        }
 
443
        close(O);
 
444
 
 
445
        my $inChDir = makeSessionDirName("/", $session) . $transactionDir;
 
446
        my $options = '';
 
447
        my $optDebugL = param('optDebugL');
 
448
        my $optE = param('optE');
 
449
        my $optEF = param('optEF');
 
450
        my $optNT = param('optNT');
 
451
        my $optCN = param('optCN');
 
452
        $options .= " -Wdebug-lexer"
 
453
                if(defined($optDebugL) && $optDebugL eq "on");
 
454
        $options .= " -E" if(defined($optE) && $optE eq "on");
 
455
        $options .= " -EF" if(defined($optEF) && $optEF eq "on");
 
456
        $options .= " -fnative-types" if(defined($optNT) && $optNT eq "on");
 
457
        $options .= " -fcompound-names" if(defined($optCN) && $optNT eq "on");
 
458
        my $CompileASN = "$TMPDIR/bin/asn1c -v | sed -e 's/^/-- /'"
 
459
                        . " > $sandbox/+Compiler.Log 2>&1"
 
460
                . "; $SUIDHelper $TMPDIR $inChDir asn1c $options @gotSafeNames "
 
461
                        . " >> $sandbox/+Compiler.Log 2>&1"
 
462
                . "; ec=\$?; echo \$ec > $sandbox/+ExitCode"
 
463
                . "; exit \$ec";
 
464
 
 
465
        my $fType = param('fileType');
 
466
        $fType = 'auto' unless $fType;
 
467
 
 
468
        # Compile as ASN.1 text
 
469
        if($fType eq 'auto' || $fType eq 'asn1') {
 
470
                my $ec = system($CompileASN);
 
471
                bark("Failed to initiate compilation process: $!")
 
472
                        if(!-r $sandbox . '/+ExitCode');
 
473
                if($ec != (256 * $DataERR)) {
 
474
                        makeArchive($TMPDIR, $sandbox) unless $ec;
 
475
                        goto REGET;     # Issue a clean GET request.
 
476
                }
 
477
        }
 
478
 
 
479
        # Unrecognized ASN.1 module format.
 
480
        # Try out several BER decoders.
 
481
        foreach my $t (sort { $binaryDecoders{$a} cmp $binaryDecoders{$b} }
 
482
                        keys %binaryDecoders) {
 
483
                next unless ($fType eq 'auto' or $fType eq $t);
 
484
                my %dec = %{$binaryDecoders{$t}};
 
485
                my $ec = system("$SUIDHelper $TMPDIR $inChDir $dec{exe} $dec{cmdopts} @gotSafeNames > $TMPDIR/$inChDir/+UNBER.tmp 2>&1");
 
486
                next if ($ec != 0 and $t ne $fType
 
487
                        and (-s "$TMPDIR/$inChDir/+UNBER.tmp" < 1000));
 
488
                last unless open(U, "> $TMPDIR/$inChDir/+UNBER");
 
489
                my $fnames = escapeHTML(join(", ", @gotNames));
 
490
                print U "<!-- $dec{type} structure of $fnames; "
 
491
                        . "decoded by '$dec{exe}' "
 
492
                        . "(c) Lev Walkin <vlm\@lionet.info> -->\n"
 
493
                        . $dec{msg};
 
494
                open(T, "< $TMPDIR/$inChDir/+UNBER.tmp");
 
495
                print U while <T>;
 
496
                close(U);
 
497
                close(T);
 
498
                open(U, "> $TMPDIR/$inChDir/+UNBER.TYPE");
 
499
                print U $dec{typeExt};
 
500
                close(U);
 
501
                if($ec) {
 
502
                        # Indicate unclean exit.
 
503
                        open(U, "> $TMPDIR/$inChDir/+UNBER.EXIT");
 
504
                        print U $ec;
 
505
                        close(U);
 
506
                }
 
507
                last;
 
508
        }
 
509
        unlink("$TMPDIR/$inChDir/+UNBER.tmp");
 
510
 
 
511
REGET:
 
512
 
 
513
        if($ENV{REQUEST_METHOD} ne 'GET') {
 
514
                print "Status: 303 See Other\n";
 
515
                print "Location: $myName\n";
 
516
        }
 
517
}
 
518
 
 
519
my $rtt = '';
 
520
if(-f $sessionDir . '/lastText') {
 
521
        if(param('resetText')) {
 
522
                unlink $sessionDir . '/lastText';
 
523
        } else {
 
524
                $rtt = "<BR>&nbsp;&nbsp;[<A HREF=$myName?resetText=ok>refill with sample ASN.1 module text</A>]";
 
525
        }
 
526
}
 
527
 
 
528
$form =
 
529
  "<FORM METHOD=POST ACTION=$myName ENCTYPE=\"multipart/form-data\">"
 
530
. "<TABLE BORDER=0><TR><TD>&nbsp;</TD><TD COLSPAN=2>"
 
531
. "Pick the ASN.1 module or binary encoded data file:\n"
 
532
. "</TD></TR><TD VALIGN=top><FONT COLOR=green>&rArr;</FONT></TD><TD>"
 
533
. "<SELECT NAME=fileType>"
 
534
. "<OPTION VALUE=auto>Autodetect type of file ..."
 
535
. "<OPTION VALUE=asn1>ASN.1 module text..."
 
536
. "<OPTION VALUE=ber>BER/DER/CER data ..."
 
537
. "<OPTION VALUE=tap0311>GSM TAP3-11 data ..."
 
538
. "<OPTION VALUE=tap0310>GSM TAP3-10 data ..."
 
539
. "<OPTION VALUE=tap0309>GSM TAP3-09 data ..."
 
540
. "<OPTION VALUE=mheg5>ISO MHEG-5 data ..."
 
541
. "<OPTION VALUE=x509>X.509 in DER (not PEM!)..."
 
542
. "</SELECT>"
 
543
. "</TD><TD ALIGN=right>"
 
544
. "<INPUT TYPE=file NAME=file SIZE=13>"
 
545
. "</TD></TR><TR><TD>&nbsp;</TD><TD COLSPAN=2>"
 
546
. "Or paste the ASN.1 text into the following area:$rtt\n"
 
547
. "</TD></TR><TD VALIGN=top><FONT COLOR=green>&rArr;</FONT></TD><TD COLSPAN=2>"
 
548
. "<TEXTAREA NAME=text ROWS=16 COLS=60>\n"
 
549
;
 
550
if(open(T, '< ' . $sessionDir . '/lastText')) {
 
551
        $form .= escapeHTML($_) while <T>;
 
552
        close(T);
 
553
} else {
 
554
        $form .= ""
 
555
        . "/*\n"
 
556
        . " * This ASN.1 specification is given for illustrative purposes.\n"
 
557
        . " * Your own ASN.1 module must be properly formed too!\n"
 
558
        . " * (Make sure it has BEGIN/END statements, etc.)\n"
 
559
        . " */\n"
 
560
        . "TestModule DEFINITIONS ::= \n"
 
561
        . "BEGIN\n"
 
562
        . "\n"
 
563
        . "  TestType ::= SEQUENCE {\n"
 
564
        . "      num [PRIVATE 1] INTEGER,\n"
 
565
        . "      str UTF8String (SIZE(1..20)) OPTIONAL\n"
 
566
        . "  }\n"
 
567
        . "\n"
 
568
        . "END\n"
 
569
        ;
 
570
}
 
571
 
 
572
$form .= "</TEXTAREA>\n"
 
573
. "</TD></TR><TD COLSPAN=3 ID=extrasmall"
 
574
. " STYLE=\"border-left: dashed 1px rgb(200, 200, 200);\">\n"
 
575
. "These options may be used to control the compiler's behavior:<BR>\n"
 
576
. "<INPUT TYPE=checkbox NAME=optDebugL> Debug lexer (<I>-Wdebug-lexer</I>)<BR>\n"
 
577
. "<INPUT TYPE=checkbox NAME=optE> Just parse and dump (do not verify) (<I>-E</I>)<BR>\n"
 
578
. "<INPUT TYPE=checkbox NAME=optEF> Parse, verify validity, and dump (<I>-E -F</I>)<BR>\n"
 
579
. "<INPUT TYPE=checkbox NAME=optNT CHECKED=on> Use native machine types (e.g. <b>double</b> instead of <b>REAL_t</b>) (<I>-fnative-types</I>)<BR>\n"
 
580
. "<INPUT TYPE=checkbox NAME=optCN> Prevent name clashes in compiled output (<I>-fcompound-names</I>)<BR>\n"
 
581
. "<I>... the command line ASN.1 compiler, <A HREF=$ASN1C_Page>asn1c</A>, supports many other parameters</I>."
 
582
. "</FONT>"
 
583
. "</TD></TR><TD VALIGN=top><FONT COLOR=green>&rArr;</FONT></TD><TD COLSPAN=2>"
 
584
. "<INPUT TYPE=submit VALUE=\"Proceed with ASN.1 compilation\">"
 
585
. " (<A HREF=$ASN1C_Page>What is ASN.1?</A>)"
 
586
. "</FORM></TD></TR></TABLE>";
 
587
 
 
588
#
 
589
# Gather previous transactions to generate the history page.
 
590
# The history page contains a list of several last ASN.1 files
 
591
# which were uploaded for compilation into the system
 
592
# by this particular browser (cookie-tracked).
 
593
#
 
594
opendir(SD, $sessionDir) or bark("Cannot open sandbox: $!");
 
595
my @transactions = sort { $b cmp $a }
 
596
                (grep {/^${safeTimeRE}(-R)?--${safeFilenameRE}?$/}
 
597
                        readdir(SD));
 
598
my $CountHistoryItems = 0;
 
599
my $CountGlobalItems = 0;
 
600
my $CountShownItems = 0;
 
601
my $fullresp = param("fullresp");
 
602
foreach my $trans (sort { $b cmp $a } @transactions) {
 
603
        $CountGlobalItems++;
 
604
        next unless($trans =~ /^($safeTimeRE)--($safeFilenameRE)$/);
 
605
        $CountHistoryItems++;
 
606
        next if($CountHistoryItems > $MaxHistoryItems
 
607
                && $HistoryShow ne 'full');
 
608
        $CountShownItems++;
 
609
 
 
610
        my ($t, $f) = ($1, $2);
 
611
        my $origTime = $t;
 
612
        $t =~ s/T/ /;   # "1999-01-02T13:53:12" => "1999-01-02 13:53:12"
 
613
 
 
614
        # Global transaction number
 
615
        my $tNum = 2 + $#transactions - $CountGlobalItems;
 
616
 
 
617
        # Open the list of file names under which these files are known
 
618
        # at the remote system.
 
619
        open(I, '< ' . $sessionDir . '/' . $trans . '/+Names');
 
620
        my @Names = <I>;
 
621
 
 
622
        # Open the list of "safe" file names under which these files
 
623
        # are known to our file system.
 
624
        open(I, '< ' . $sessionDir . '/' . $trans . '/+safeNames');
 
625
        my @safeNames = <I>;
 
626
 
 
627
        # Create a list of real file names whith appropriate links to the
 
628
        # "safe" file names for subsequent file fetching.
 
629
        my @markedNames = ();
 
630
        for(my $i = 0; $i <= $#Names; $i++) {
 
631
                local $_ = "<A HREF=\"$myName?time="
 
632
                        . escapeHTML($origTime)
 
633
                        . "&file=$f"
 
634
                        . "&fetch=$safeNames[$i]\" ID=modrefs>"
 
635
                        . escapeHTML($Names[$i])
 
636
                        . "</A>";
 
637
                @markedNames = (@markedNames, $_);
 
638
        }
 
639
 
 
640
        my $ec = '';
 
641
        open(I, '< ' . $sessionDir . '/' . $trans . '/+ExitCode')
 
642
                and chop($ec = <I>);
 
643
 
 
644
        my $resCode = "log";
 
645
        my $resText = "Show compiler log";
 
646
 
 
647
        if($ec eq "0") {
 
648
                $results = "<FONT COLOR=darkgreen><B>"
 
649
                        . "Compiled OK</B></FONT><BR>\n";
 
650
        } elsif(open(U, $sessionDir . '/' . $trans . '/+UNBER.TYPE')) {
 
651
                my $type = <U>; close(U);
 
652
                my $msg;
 
653
                if($ec eq '') {
 
654
                        $msg = 'Treating input as ' . $type;
 
655
                } else {
 
656
                        $msg = 'This looks like ' . $type;
 
657
                }
 
658
                $results = "<FONT COLOR=darkgreen><B>$msg</B></FONT><BR>\n";
 
659
                if(-f $sessionDir . '/' . $trans . '/+UNBER.EXIT') {
 
660
                        $results = "<FONT COLOR=darkred SIZE=-1>"
 
661
                                . "<NOBR>$type:</NOBR> "
 
662
                                . "Broken encoding</FONT><BR>\n";
 
663
                        $ec = 'broken-input';
 
664
                        $resText = "Show $type decoding attempt";
 
665
                } else {
 
666
                        $ec = 0;
 
667
                        $resText = "Show $type contents";
 
668
                }
 
669
                $resCode = "unber";
 
670
        } else {
 
671
                my $why = $ec;
 
672
                $why = "<NOBR>Broken input file</NOBR>" if $ec == $DataERR;
 
673
                $results = "<FONT COLOR=darkred SIZE=-1>"
 
674
                        . "<NOBR>ASN.1 compiler error:</NOBR> "
 
675
                        . "$why</FONT><BR>\n";
 
676
        }
 
677
 
 
678
        $allowFetchResults = $ec eq "0"
 
679
                && (-f $sessionDir . '/' . $trans . '/+Archive.tgz'
 
680
                || -f $sessionDir . '/' . $trans . '/Makefile.am.sample');
 
681
 
 
682
        $results .= "<NOBR>"
 
683
                . ($allowFetchResults ? '1. ' : '')
 
684
                . "<A HREF=\"$myName/$f-$tNum.$resCode?time="
 
685
                . escapeHTML($origTime)
 
686
                . "&file=$f"
 
687
                . "&show=$resCode\">"
 
688
                . "$resText</A>"
 
689
                . ($ec ? ' &larr;' : '')
 
690
                . "</NOBR>";
 
691
        $results .= "<BR>\n<NOBR>"
 
692
                . "2. <A HREF=\"$myName/$f-$tNum.tgz?time="
 
693
                . escapeHTML($origTime)
 
694
                . "&file=$f"
 
695
                . "&show=tgz\">"
 
696
                . "Fetch compiled C sources (.tgz)</A> &larr;</NOBR>"
 
697
                if $allowFetchResults;
 
698
        if($ec ne "0") {
 
699
                my ($eml, @resp);
 
700
                open(H, '< ' . $sessionDir . '/' . $trans . '/+HelpResp')
 
701
                        and @resp = <H>;
 
702
                open(H, '< ' . $sessionDir . '/' . $trans . '/+HelpReq')
 
703
                        and chomp($eml = <H>);
 
704
                if($#resp >= 0) {
 
705
                        shift(@resp) while($resp[0] =~ /^$/);
 
706
                        if($fullresp eq $tNum) {
 
707
                                my $r = join("<BR>", @resp);
 
708
                                $r =~ s/ /&nbsp;/g;
 
709
                                $results .= "<P><B>Analysis:</B>";
 
710
                                $results .= "<BR>(<A HREF=\"$myName\">Hide full explanation</A>)";
 
711
                                $results .= "<BLOCKQUOTE>";
 
712
                                $results .= $r;
 
713
                                $results .= "</BLOCKQUOTE>";
 
714
                                $results .= "(<A HREF=\"$myName\">Hide full explanation</A>)";
 
715
                        } else {
 
716
                                $results .= "<P><B>Analysis:</B> $resp[0]<BR>";
 
717
                                $results .= "(<A HREF=\"$myName?fullresp=$tNum\">Show full explanation</A>)";
 
718
                        }
 
719
                } elsif($eml) {
 
720
                        $results .= "<P><FONT COLOR=darkred Family=Serif><B>"
 
721
                                . "Status: manual help requested<BR>"
 
722
                                . " by <FONT COLOR=black>$eml</FONT>,<BR>"
 
723
                                . "expect results in a few hours.<B></FONT>";
 
724
                } else {
 
725
                        $results .= '<P>'
 
726
                        . "To get free help, leave a return address:<BR>"
 
727
                        . "<INPUT TYPE=text NAME=email VALUE=\"$userEmail\"><BR>"
 
728
                        . "<INPUT TYPE=hidden NAME=transHelp VALUE=\"$tNum--$trans\">"
 
729
                        . '<INPUT TYPE=Submit VALUE="Help me fix it!">'
 
730
                        ;
 
731
                        $atLeastOneError = 1;
 
732
                }
 
733
        }
 
734
 
 
735
        $trColor = ' BGCOLOR=#f8f8f8';
 
736
        $trColor = ' BGCOLOR=#d0ffe0' if $CountHistoryItems == 1;
 
737
 
 
738
        $history .= "<TR $trColor>"
 
739
                . "<TH ALIGN=center ID=num>$tNum"
 
740
                . "<BR><FONT FACE=serif>[<A ID=modrefs "
 
741
                        . "HREF=\"$myName?time="
 
742
                        . escapeHTML($origTime)
 
743
                        . "&file=$f&remove=$tNum\""
 
744
                        . ">&times;</A>]</FONT>"
 
745
                . "</TH>"
 
746
                . "<TD ALIGN=center>"
 
747
                . join(", ", @markedNames)
 
748
                . "</TD></TD>"
 
749
                . "<FORM METHOD=POST ACTION=$myName><TD ID=extrasmall>"
 
750
                        . $results
 
751
                        . "</TD></FORM>"
 
752
                . "</TR>"
 
753
                ;
 
754
}
 
755
 
 
756
if($DynamicHistory eq 'yes') {
 
757
        # [Un-]limit number of history items
 
758
        $HistoryItemsHidden = $CountHistoryItems - $CountShownItems;
 
759
        if($HistoryItemsHidden > 0) {
 
760
                # Propose to expand the list.
 
761
                my $item = 'item';
 
762
                $HistoryItemsHidden == 1 or $item = 'items';
 
763
                $history .= "<TR BGCOLOR=white><TD COLSPAN=3 ALIGN=center>"
 
764
                        . "<A HREF=\"$myName?history=full\">"
 
765
                        . "Show full history</A> "
 
766
                        . "($HistoryItemsHidden hidden $item)"
 
767
                        . "</TD></TR>\n";
 
768
        } elsif($HistoryShow eq "full" && $#transactions >= $MaxHistoryItems) {
 
769
                # Propose to shorten the list.
 
770
                my $item = 'item';
 
771
                $MaxHistoryItems == 1 or $item = 'items';
 
772
                $history .= "<TR BGCOLOR=white><TD COLSPAN=3 ALIGN=center>"
 
773
                        . "<A HREF=\"$myName?history=short\">"
 
774
                        . "Short history</A> ($MaxHistoryItems $item)"
 
775
                        . "</TD></TR>\n";
 
776
        }
 
777
}
 
778
 
 
779
if($history) {
 
780
        $history = "<H3>History</H3>"
 
781
        . "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 BGCOLOR=#404040 WIDTH=100%><TR><TD>"
 
782
        . "<TABLE BORDER=0 CELLPADDING=5 CELLSPACING=1 WIDTH=100%>\n"
 
783
        . "<TR BGCOLOR=#e0f0d0>"
 
784
        . "<TH WIDTH=1%>N</TH><TH>Files processed</TH><TH>Result</TH>\n"
 
785
        . "</TR>\n"
 
786
        . $history . "</TABLE></TD></TR></TABLE><BR>\n";
 
787
 
 
788
        if($atLeastOneError) {
 
789
                $history .= "<FONT COLOR=#404040>"
 
790
                        . "<FONT COLOR=darkred><B>Bottom line:</B> ASN.1 compiler was unable to process some of the input.</FONT><BR>"
 
791
                        . "This is typically caused by syntax errors in the input files.\n"
 
792
                        . "Such errors are normally fixed by removing or adding a couple of characters in the ASN.1 module.<BR>\n"
 
793
                        . "<BR><B><FONT COLOR=darkred>&rArr; Please consider clicking on the appropriate &quot;<I>Help me fix it!</I>&quot; button above.</FONT></B><BR>\n"
 
794
                        . "An email will be sent to a live person who will fix the ASN.1 module for you. (The typical turn-around time is less than 24 hours.)\n"
 
795
                        . "<BR>This is <B>free</B>, and highly advisable.\n"
 
796
                        . "<BR>Your request will help us make a better compiler!\n"
 
797
                        . "<BR>Thank you."
 
798
                        . "</FONT>";
 
799
        }
 
800
}
 
801
 
 
802
unless($history) {
 
803
        $history = "<FONT SIZE=+2 COLOR=#a0a0a0>"
 
804
                . "[compiled results will appear here]</FONT>";
 
805
        $histValign = 'center';
 
806
} else {
 
807
        $histValign = 'top';
 
808
}
 
809
 
 
810
$content .=
 
811
  "<TABLE WIDTH=100% BORDER=0 CELLSPACING=5 CELLPADDING=5><TR><TD ID=inputbox VALIGN=top ROWSPAN=2 WIDTH=40%>\n"
 
812
. "<H3 ALIGN=center>ASN.1 Input</H3>\n"
 
813
. "$form"
 
814
. "</TD><TD WIDTH=60% HEIGHT=50% ALIGN=center VALIGN=$histValign>$history \n"
 
815
. "</TD></TR><TR><TD HEIGHT=50% VALIGN=bottom>"
 
816
        . "<B>Privacy Note:</B> this page is tailored "
 
817
        . "to your browser. "
 
818
        . "<I>Other users will see their own (different) data.</I> "
 
819
        . "(<A HREF=asn1c-privacy.html>Read more...</A>)"
 
820
. "</TD></TR></TABLE>";
 
821
 
 
822
$ua = $ENV{HTTP_USER_AGENT};
 
823
$ua =~ s/\\/\\\\/;
 
824
$ua =~ s/"/\\"/;
 
825
print LOG "\tUA=\"$ua\"";
 
826
print LOG "\n"; # Finalize logging record
 
827
 
 
828
PRINTOUT:
 
829
 
 
830
print header(-expires=>'-1y');
 
831
 
 
832
# If environment has never been set up completely, remove it.
 
833
if($EnvironmentSetOK != 1 && $TMPDIR ne "/") {
 
834
        system("rm -rf $TMPDIR/ >/dev/null 2>&1");
 
835
}
 
836
 
 
837
print<<EOM;
 
838
<HTML>
 
839
<HEAD>
 
840
<TITLE>Free Online ASN.1 Compiler</TITLE>
 
841
<META NAME="Description" CONTENT="Free Online ASN.1 Compiler">
 
842
$redirect
 
843
<STYLE TYPE="text/css">
 
844
        TH {
 
845
                font-size: 11pt;
 
846
                color: #404040;
 
847
                font-family: monospace;
 
848
        }
 
849
        TH#num {
 
850
                font-size: 8pt;
 
851
                font-family: sans-serif;
 
852
        }
 
853
        TD {
 
854
                font-size: 10pt;
 
855
                font-family: sans-serif;
 
856
        }
 
857
        TD#inputbox {
 
858
                border-right: dashed 1px rgb(200, 200, 200);
 
859
        }
 
860
        TD#extrasmall {
 
861
                font-size: 8pt;
 
862
                font-family: sans-serif;
 
863
        }
 
864
        A#modrefs {
 
865
                color: #606060;
 
866
                text-decoration: none;
 
867
        }
 
868
        A:hover#modrefs {
 
869
                text-decoration: underline;
 
870
        }
 
871
        A:visited#modrefs {
 
872
                color: #b06060;
 
873
        }
 
874
</STYLE>
 
875
</HEAD>
 
876
<BODY BGCOLOR=white>
 
877
 
 
878
$homePath
 
879
 
 
880
$content
 
881
 
 
882
$redirect_bottom
 
883
 
 
884
<HR WIDTH=70%>
 
885
<CENTER><ADDRESS><FONT SIZE=-1 FACE=Courier COLOR=#404040>
 
886
<A HREF=$ASN1C_Page>The ASN.1 Compiler</A>
 
887
        Copyright &copy; 2003, 2004, 2005
 
888
Lev Walkin &lt;<A HREF=mailto:vlm&#64;lionet.info?Subject=asn1c>vlm&#64;lionet.info</A>&gt;
 
889
</FONT></ADDRESS></CENTER>
 
890
</BODY>
 
891
</HTML>
 
892
EOM