~n3npq/lsb/distribution-checker

« back to all changes in this revision

Viewing changes to webui/public_html/cert_integration.pl

  • Committer: biga
  • Date: 2009-04-24 14:16:44 UTC
  • Revision ID: biga@spidey.linux-foundation.org-20090424141644-7evzd6mjocix7e68
init

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w 
 
2
 
 
3
# LSB Test Execution Framework
 
4
# Module for Integration with Certification System (cert_integration.pl)
 
5
#
 
6
# Copyright (C) 2007-2009 The Linux Foundation. All rights reserved.
 
7
#
 
8
# This program has been developed by ISP RAS for LF.
 
9
# The ptyshell tool is originally written by Jiri Dluhos <jdluhos@suse.cz>
 
10
# Copyright (C) 2005-2007 SuSE Linux Products GmbH
 
11
#
 
12
# This program is free software; you can redistribute it and/or
 
13
# modify it under the terms of the GNU General Public License
 
14
# version 2 as published by the Free Software Foundation.
 
15
#
 
16
# This program is distributed in the hope that it will be useful,
 
17
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
# GNU General Public License for more details.
 
20
#
 
21
# You should have received a copy of the GNU General Public License
 
22
# along with this program; if not, write to the Free Software
 
23
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
24
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 
25
 
 
26
use strict;
 
27
use Templates;
 
28
use Socket;
 
29
 
 
30
autoflush_on();
 
31
 
 
32
my $boundary = '432432548930278320';
 
33
 
 
34
my $client_name = 'DTK Manager';
 
35
 
 
36
my %subst;  # compiled patternes
 
37
 
 
38
sub uri_escape {
 
39
    my ($text) = @_;
 
40
    return unless defined $text;
 
41
    
 
42
        $text =~ s/([^A-Za-z0-9\-_.!~*\'()])/sprintf("%%%02X", $1)/ge;
 
43
    return $text;
 
44
}
 
45
 
 
46
sub multipart_file
 
47
{
 
48
    my ($file_location, $filename, $field_name, $save_as) = @_;
 
49
 
 
50
    my $content_type = 'application/octet-stream';
 
51
    
 
52
    unless (open FILE, $file_location.$filename) {
 
53
        print "Can't open ".$file_location.$filename."\n";
 
54
        print_footer();
 
55
        exit(1);
 
56
    }
 
57
 
 
58
    my $body_text = '';
 
59
    
 
60
    $body_text .= "\r\n";
 
61
    $body_text .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$save_as\"\r\n";
 
62
    $body_text .= "Content-Type: $content_type\r\n";
 
63
    #$body_text .= "Content-Transfer-Encoding: binary\r\n";
 
64
    $body_text .= "\r\n";
 
65
 
 
66
    # File content
 
67
    my $content_part;
 
68
    while ( read (FILE, $content_part, 1024*1024) ) {
 
69
        $body_text .= $content_part;
 
70
    }
 
71
    close FILE;
 
72
 
 
73
    $body_text .= "\r\n";
 
74
    $body_text .= "--$boundary";
 
75
    
 
76
    return $body_text;
 
77
}
 
78
 
 
79
sub multipart_text
 
80
{
 
81
    my ($name, $value) = @_;
 
82
    
 
83
    # Submit button data
 
84
    my $body_text = '';
 
85
    
 
86
    $body_text .= "\r\n";
 
87
    $body_text .= "Content-Disposition: form-data; name=\"$name\"\r\n";
 
88
    $body_text .= "\r\n";
 
89
    $body_text .= "$value\r\n";
 
90
    $body_text .= "--$boundary";
 
91
    
 
92
    return $body_text;
 
93
}
 
94
 
 
95
sub multipart_body
 
96
{
 
97
    my ($filename, $directory, $save_as, $_POST) = @_;
 
98
 
 
99
    my $body_text = '';
 
100
    
 
101
    # Body start 
 
102
    $body_text .= "--$boundary";
 
103
 
 
104
    $body_text .= multipart_file($directory, $filename, 'attachment', $save_as);
 
105
    $body_text .= multipart_text('submit', 'Hidden');
 
106
    foreach my $key ( keys %$_POST ) {
 
107
        next if $key =~ /^secure_key/;
 
108
        next if $key eq "filename";
 
109
        next if $key eq "directory";
 
110
        next if $key eq "save_as";
 
111
        next if $key eq "pc_id";
 
112
        next if $key eq "back_url";
 
113
        next if $key eq "back_host";
 
114
        $body_text .= multipart_text( $key, $_POST->{$key});
 
115
    }
 
116
 
 
117
    # Body End
 
118
    $body_text .= "--\r\n";
 
119
    
 
120
    return $body_text;
 
121
}
 
122
 
 
123
sub upload
 
124
{
 
125
    print "HTTP/1.0 200 OK" . CRLF;
 
126
    print "Content-type: text/html" . CRLF . CRLF;
 
127
 
 
128
    print_header("Test Results", "results");
 
129
    
 
130
    if ( !exists($_POST{'filename'} )
 
131
      || !exists($_POST{'directory'})
 
132
      || !exists($_POST{'secure_key_name'})
 
133
      || !exists($_POST{'secure_key_val'})
 
134
    ) {
 
135
        print "Not enough parameters";
 
136
        print_footer();
 
137
        exit;
 
138
    }
 
139
    
 
140
    my $filename = $_POST{'filename'};
 
141
    my $directory = $_POST{'directory'};    
 
142
    
 
143
    my $save_as = $filename;
 
144
    if ( exists($_POST{'save_as'}) ) {
 
145
        $save_as = $_POST{'save_as'};
 
146
    }
 
147
    
 
148
    # Default
 
149
    my $cert_url = $cert_sys_base.'upload.php?inadvance';
 
150
    $cert_url .= '&pcid='.$_POST{'pc_id'} if exists $_POST{'pc_id'};
 
151
    
 
152
    # Override
 
153
    $cert_url = $_POST{'back_url'} if exists $_POST{'back_url'};
 
154
    
 
155
    $cert_sys_host = $_POST{'back_host'} if exists $_POST{'back_host'};
 
156
    
 
157
    # prepare the data
 
158
    my $body_text = &multipart_body( $filename, $directory, $save_as, \%_POST );
 
159
 
 
160
    my $content_length = length($body_text);
 
161
 
 
162
    # Bake cookies
 
163
    my %cookies = (
 
164
            $_POST{'secure_key_name'} => $_POST{'secure_key_val'},
 
165
            'integration' => $client_name,
 
166
        );
 
167
    my @cookie_pairs = ();
 
168
    foreach my $key ( keys %cookies ) {
 
169
        my $cookie_pair = $key.'='.uri_escape($cookies{$key});
 
170
        push @cookie_pairs, $cookie_pair;
 
171
    }
 
172
    my $cookie_line = join('; ', @cookie_pairs);
 
173
    
 
174
    # Header settings
 
175
    my $host = $cert_sys_host;
 
176
    my $port = 80;
 
177
    my $pagename = $cert_url;
 
178
    my $header_content_type = "multipart/form-data";
 
179
    
 
180
    # Compile the header
 
181
    my $header = '';
 
182
    $header .= "POST $pagename HTTP/1.1" . CRLF;
 
183
    $header .= "Host: $host" . CRLF;
 
184
    $header .= "Content-Type: $header_content_type; boundary=$boundary" . CRLF;
 
185
    $header .= "Content-Length: $content_length" . CRLF;
 
186
    $header .= "Cookie: $cookie_line" . CRLF if ( $cookie_line );
 
187
    $header .= "Connection: Close" . CRLF;
 
188
    $header .= CRLF;
 
189
    
 
190
    #print "<pre>$header</pre>";
 
191
    
 
192
    # Entire message
 
193
    my $message = $header.$body_text;
 
194
 
 
195
    # start connecting
 
196
    socket ( SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp') );
 
197
 
 
198
    my $iaddr = inet_aton($host);
 
199
    my $paddr = sockaddr_in($port, $iaddr);
 
200
 
 
201
    my $result = connect(SOCK, $paddr);
 
202
    
 
203
    if ( ! $result ) {
 
204
    # Connection failed
 
205
        print '<p style="color:red">Error: Failed to connect to the Certification System'
 
206
                .' at '.$cert_sys_host.':80.</p>';
 
207
        print_footer();
 
208
    } else {
 
209
        print <<DATA;
 
210
<h1>Uploading test results</h1>
 
211
<p style="color:green;font-weight:bold">
 
212
 Please, wait while uploading the data to the Certification System...
 
213
</p>
 
214
<p>
 
215
 Time elapsed: 
 
216
  <span id="timer" style="font-family: monospace; color: blue;">00:00</span>
 
217
</p>
 
218
<br />
 
219
<table><tr><td><div style="width: 300px; height: 12px; border: 1px solid #004000;">
 
220
 <img src="images/progress.png" alt="progress: 0/0" 
 
221
   width="0" height="12" id="progress_bar" style="display: none;" />
 
222
</div>
 
223
</td><td>
 
224
<span id="progress_text" style="padding-left:30pt"></span>
 
225
</td></tr>
 
226
</table>
 
227
<br />
 
228
<p><span id="msg"><br/></span></p>
 
229
 
 
230
<script language="javascript" type="text/javascript">
 
231
// <![CDATA[
 
232
var elapsed_time = 0;
 
233
var timer;
 
234
function update_timer() {
 
235
    if ( !timer )  return;
 
236
        ++elapsed_time;
 
237
        var elem = document.getElementById("timer");
 
238
        if (elem) {
 
239
                var m = Math.floor(elapsed_time / 60);
 
240
                var s = elapsed_time - m * 60;
 
241
                var tmp = "";
 
242
                tmp += (m < 10) ? "0" + m : m;
 
243
                tmp += ":";
 
244
                tmp += (s < 10) ? "0" + s : s;
 
245
                elem.innerHTML = tmp;
 
246
                timer = setTimeout("update_timer()", 1000);
 
247
        }
 
248
}
 
249
 
 
250
function set_progress(done, total) {
 
251
        var elem = document.getElementById("progress_bar");
 
252
        if (elem) {
 
253
                elem.style.display = ((done == 0) ? 'none' : '');
 
254
                if (done > total)
 
255
                        done = total;
 
256
        elem.alt = "progress: " + done + "/" + total;
 
257
                elem.width = Math.round(done * 300 / total);
 
258
        }
 
259
        var etxt = document.getElementById("progress_text");
 
260
        if (etxt) {
 
261
                if (done > total)
 
262
                        done = total;
 
263
                etxt.innerHTML = "Uploaded: " + Math.floor(done/1024) + " of " + Math.floor(total/1024) +" Kbytes.";
 
264
        } 
 
265
}
 
266
 
 
267
function stopTimer() {
 
268
    clearTimeout(timer); 
 
269
    timer = 0;
 
270
}
 
271
 
 
272
timer = setTimeout("update_timer()", 1000);
 
273
// ]]>
 
274
</script>
 
275
DATA
 
276
            print_footer(1);     # do not finish with </body></html> now!
 
277
    }
 
278
 
 
279
    # No bufferization!
 
280
    select SOCK; $| = 1;
 
281
    select STDOUT; $| = 1;
 
282
 
 
283
    # connected, let's post the data
 
284
 
 
285
    my $total_bytes = length($message);
 
286
    my $sent_bytes = 0;
 
287
    my $chunk_size = 1024*50;
 
288
    
 
289
    # Sending...
 
290
    $message =~ //; # reset search iterator
 
291
    for ( my $sent_bytes = 0; $sent_bytes < $total_bytes; ) { 
 
292
    # reading chunks of $chunk_size bytes
 
293
        my $chunk = substr($message, $sent_bytes, $chunk_size);
 
294
 
 
295
        print SOCK $chunk;
 
296
        
 
297
        $sent_bytes += (length($chunk) or last);
 
298
        
 
299
        # Progress bar increase
 
300
        print_javascript_progress ( $sent_bytes, $total_bytes );
 
301
        
 
302
        # DBG: sleep a bit
 
303
        #select(undef, undef, undef, 0.2);
 
304
    }
 
305
 
 
306
    ##### Data has been sent. Read the response. #####
 
307
    
 
308
    my $back_url = '';
 
309
    
 
310
    # TODO: F: Check the response code
 
311
    
 
312
    # Reading the response: looking for the "Location:" header field
 
313
    my $resp_header = ''; # For debugging
 
314
    my $output = '';
 
315
    my $mode = 0;
 
316
    while (<SOCK>) {
 
317
        $resp_header .= $_ if $mode==0;
 
318
        $output .= $_ if $mode==1;
 
319
        
 
320
        # TODO: /^HTTP1.\d\s+(\d+)/ - code should be 302
 
321
        
 
322
        if ( /^Location:\s+(.*)$/ && $mode==0 ) {
 
323
            $back_url = $1;
 
324
            $back_url =~ s/\s+$//; # Trim trailing \r\n; 'chomp' doesn't work here!
 
325
        }
 
326
        
 
327
        if ( /^\s*$/ && $mode==0 ) {
 
328
        # End of header is marked by empty line.
 
329
            #last; # Do not read the rest of the response.
 
330
            $mode = 1;
 
331
        }
 
332
    }
 
333
    # close the connection
 
334
    close(SOCK);
 
335
 
 
336
    if ( $output && $output !~ /^\s*0\s*$/ ) { print $output; }
 
337
    
 
338
    if ( $back_url =~ m!^https?://! ) {
 
339
        # OK. Do nothing.
 
340
    }
 
341
    elsif ( $back_url =~ m!^/! ) {
 
342
        $back_url = 'http://'.$cert_sys_host.$back_url;
 
343
    }
 
344
    elsif ( $back_url =~ /^\w/ ) {
 
345
        $cert_url =~ s{/[^/]+$}{/$back_url};
 
346
        $back_url = 'http://'.$cert_sys_host.$cert_url;
 
347
    }
 
348
    elsif ( $back_url =~ /^\?/ ) {
 
349
        $cert_url =~ s{\?.+$}{$back_url};
 
350
        $back_url = 'http://'.$cert_sys_host.$cert_url;
 
351
    }
 
352
    elsif ( exists($_POST{'back_url_error'}) ) { 
 
353
        $back_url = 'http://'.$cert_sys_host.$_POST{'back_url_error'};
 
354
    }
 
355
    else {
 
356
        $back_url = '';
 
357
    }
 
358
 
 
359
    # Stop the timer on the page, print message.
 
360
    
 
361
    print <<OUT;
 
362
<script language="javascript" type="text/javascript">
 
363
// <![CDATA[
 
364
    stopTimer();
 
365
    var elem = document.getElementById("msg");
 
366
    if ( elem ) {
 
367
        elem.innerHTML = "<span style='color:green;font-weight:bold'>... done!</span>";
 
368
        elem.innerHTML += " &nbsp; ";
 
369
OUT
 
370
    if ( $back_url ne '' ) {
 
371
        print <<OUT;
 
372
        elem.innerHTML += "Press [<a href='$back_url'>Continue</a>]";
 
373
OUT
 
374
        }
 
375
    print <<OUT;
 
376
    }
 
377
// ]]>
 
378
</script>
 
379
OUT
 
380
    
 
381
    # Footer has already been printed, but without "</body></html>".
 
382
    print "</body>\n</html>\n";
 
383
    exit;
 
384
}
 
385
 
 
386
sub print_javascript_redirect
 
387
{
 
388
    my $back_url = shift;
 
389
    
 
390
    #print $back_url or
 
391
    print <<OUT;
 
392
<script language="javascript" type="text/javascript">
 
393
// <![CDATA[
 
394
    stopTimer();
 
395
    location.replace("$back_url");
 
396
// ]]>
 
397
</script>
 
398
OUT
 
399
}
 
400
 
 
401
sub print_javascript_progress
 
402
{
 
403
    my $sent_bytes = shift;
 
404
    my $total_bytes = shift;
 
405
    
 
406
    print <<OUT;
 
407
<script language="javascript" type="text/javascript">
 
408
// <![CDATA[
 
409
    set_progress($sent_bytes, $total_bytes);
 
410
// ]]>
 
411
</script>
 
412
OUT
 
413
 
 
414
}
 
415
 
 
416
sub get_test_info {
 
417
    my $subdir = shift;
 
418
    
 
419
    my $dir = $CONFIG{"RESULTS_DIR"}.'/'.$subdir;
 
420
    
 
421
    my $result;
 
422
    
 
423
    if ( open(FILE, $dir."/host_info/host_platform")) {
 
424
        $result->{'prod_arch'} = <FILE>;
 
425
        chomp $result->{'prod_arch'};
 
426
        $result->{'prod_arch'} =~ s/amd64/x86_64/;
 
427
    }
 
428
 
 
429
    if ( open(FILE, $dir."/host_info/host_os")) {
 
430
        my $distr = <FILE>;
 
431
        chomp $distr;
 
432
        
 
433
        if ( $distr =~ s/\(([^\)]+)\)// ) {
 
434
            if ( $1 ne $result->{'prod_arch'} ) {
 
435
                $result->{'prod_comment'} = $1;
 
436
            }
 
437
        }
 
438
        
 
439
        if ( $distr =~ s/\b(release)? *([0-9][0-9\.\-\w]*)\b// ) {
 
440
            $result->{'prod_version'} = $2;
 
441
        }
 
442
        
 
443
        $distr =~ s/\s+$//; # Trim
 
444
        $distr =~ s/^\s+//; # Trim
 
445
        
 
446
        $result->{'prod_name'} = $distr;
 
447
    }
 
448
    
 
449
    if ( open(FILE, $dir."/host_info/lsb_release_all")) {
 
450
        while ( <FILE> ) {
 
451
            chomp;
 
452
            if ( /^Release:\s+(.*)$/ ) {
 
453
                $result->{'prod_version'} = $1;
 
454
            }
 
455
            if ( /^Codename:\s+(.*)$/ ) {
 
456
                next if ($1 eq 'n/a');
 
457
                $result->{'prod_comment'} = $1;
 
458
            }
 
459
        }
 
460
    }
 
461
    
 
462
    if ( open(FILE, $dir."/host_info/lsb_version")) {
 
463
        $result->{'lsb_version'} = <FILE>;
 
464
        chomp $result->{'lsb_version'};
 
465
    }
 
466
    
 
467
    return $result;
 
468
}
 
469
 
 
470
sub start()
 
471
{
 
472
    print "HTTP/1.0 200 OK" . CRLF;
 
473
    print "Content-type: text/html" . CRLF . CRLF;
 
474
 
 
475
    print_header("Test Results", "results");
 
476
 
 
477
    my $file = $_GET{'file'};
 
478
    $file = $_POST{'file'} if (!$file);
 
479
 
 
480
    my $cert = $_GET{'cert'}; # Is this a good certification test result.
 
481
    $cert = $_POST{'cert'} if (!$cert);
 
482
 
 
483
    if ( index($file, $CONFIG{"RESULTS_DIR"}) != 0 ) {
 
484
        print "Wrong parameter: file (access forbidden)";
 
485
        print_footer();
 
486
        exit;
 
487
    }
 
488
    if ( ! -r $file ) {
 
489
        print "Wrong parameter: file (access denied)";
 
490
        print_footer();
 
491
        exit;
 
492
    }
 
493
    #
 
494
    my $get_credentials_page = "status.php";
 
495
    my $action_url = 'http://'.$cert_sys_host.$cert_sys_base.$get_credentials_page;
 
496
    
 
497
    my $base_url = 'http://'.$SERVER_PARAM{"HOST"};
 
498
    my $this_url = $base_url.'/cert_integration.pl'; 
 
499
    my $back_url = $this_url.'?upload'; # Callback for file uploading
 
500
    my $client_url = $base_url.'/tests_results.pl'; # Return to it on success
 
501
 
 
502
    my $filename = '';
 
503
    my $file_location = '';
 
504
    
 
505
    if ( $file =~ m/^(.*\/)([^\/]*)$/ ) {
 
506
        $filename = $2;
 
507
        $file_location = $1; # with trailing slash.
 
508
    }
 
509
    else {
 
510
        print "Wrong parameter: file (can't split)";
 
511
        print_footer();
 
512
        exit;
 
513
    }
 
514
    
 
515
    my $filesize = -s $file_location.$filename;
 
516
    my $filelink = $base_url.'/get.pl'.$file_location.$filename;
 
517
    
 
518
    my $result;
 
519
    if ( $file_location =~ m/\/([^\/]+)\/+$/ ) {
 
520
        $result = get_test_info($1);
 
521
    }
 
522
    
 
523
    my $prod_kind = "distr";
 
524
    
 
525
    my $prod_name = ($result->{'prod_name'} or '');
 
526
    my $prod_version = ($result->{'prod_version'} or '');
 
527
    my $prod_arch = ($result->{'prod_arch'} or '');
 
528
    my $prod_comment = ($result->{'prod_comment'} or '');
 
529
    my $prod_url = ($result->{'prod_url'} or '');
 
530
    my $lsb_version = ($result->{'lsb_version'} or '');
 
531
 
 
532
    print <<DATA;
 
533
    <h1>Working with the Certification System</h1>
 
534
    <p>To apply for certification you should pass the following steps 
 
535
    in the Certification System.
 
536
    </p>
 
537
    <ul>
 
538
    <li>If you are not logged in you will be suggested
 
539
        to log in or create an account.</li>
 
540
    <li>If you are not a company member you will be suggested to register
 
541
        your company or join an existing one.</li>
 
542
    <li>Then you should register the product or chose a registered one.</li>
 
543
    <li>And after all you should start certification of the product
 
544
        by signing the Trademark License Agreement.</li>
 
545
    </ul>
 
546
    
 
547
    <p>All these steps are required to apply for certification.
 
548
    Once you click on the 'continue' link the Certification System page
 
549
    will be opened. Then follow the instructions.
 
550
    </p>
 
551
    <form method="post" name="dataform" action="$action_url">
 
552
    
 
553
    <input type="hidden" name="prod_kind" value="$prod_kind" />
 
554
    <input type="hidden" name="prod_name" value="$prod_name" />
 
555
    <input type="hidden" name="prod_version" value="$prod_version" />
 
556
    <input type="hidden" name="prod_comment" value="$prod_comment" />
 
557
    <input type="hidden" name="prod_arch" value="$prod_arch" />
 
558
    <input type="hidden" name="prod_url" value="$prod_url" />
 
559
    <input type="hidden" name="lsb_version" value="$lsb_version" />
 
560
    
 
561
    <input type="hidden" name="client" value="$client_name" />
 
562
    <input type="hidden" name="client_url" value="$client_url" />
 
563
    <input type="hidden" name="back_url" value="$back_url" />
 
564
 
 
565
    <input type="hidden" name="filename" value="$filename" />
 
566
    <input type="hidden" name="directory" value="$file_location" />
 
567
    <input type="hidden" name="filesize" value="$filesize" />
 
568
    <input type="hidden" name="filelink" value="$filelink" />
 
569
    <input type="hidden" name="cert" value="$cert" />
 
570
 
 
571
    <input type="hidden" name="integration" value="submit" />
 
572
    </form>
 
573
    <p>[<span class="active" onclick="document.dataform.submit();"
 
574
        >Continue</span>]</p>
 
575
DATA
 
576
 
 
577
    print_footer();
 
578
    exit;
 
579
}
 
580
 
 
581
if ( exists($_GET{'start'}) && $_GET{'start'} ) {
 
582
    &start();
 
583
    exit;
 
584
}
 
585
 
 
586
if ( exists($_POST{'upload'}) && $_POST{'upload'} ) {
 
587
    upload();
 
588
}
 
589
 
 
590
print "HTTP/1.0 200 OK" . CRLF;
 
591
print "Content-type: text/html" . CRLF . CRLF;
 
592
 
 
593
print_header("Test Results", "results");
 
594
    
 
595
print <<DATA;
 
596
<p>This address is used by the <a href="http://$cert_sys_host$cert_sys_base">Certification System</a> to interact with the DTK Manager.</p>
 
597
DATA
 
598
 
 
599
print_footer();
 
600
exit;