From 4d845207a09d6a7ac70a1ec0728284d4f717abfe Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 10 Dec 2010 20:48:36 +0100 Subject: [PATCH] add keygen script --- misc/infrastructure/keygen/.htaccess | 15 ++ misc/infrastructure/keygen/config.pl | 20 +++ misc/infrastructure/keygen/response.d0ir | 211 +++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 misc/infrastructure/keygen/.htaccess create mode 100644 misc/infrastructure/keygen/config.pl create mode 100755 misc/infrastructure/keygen/response.d0ir diff --git a/misc/infrastructure/keygen/.htaccess b/misc/infrastructure/keygen/.htaccess new file mode 100644 index 00000000..aeafa217 --- /dev/null +++ b/misc/infrastructure/keygen/.htaccess @@ -0,0 +1,15 @@ +Options +ExecCGI +DirectoryIndex response.d0ir + + SetHandler cgi-script + +# allow,deny: accept = A && !D +# deny,allow: accept = !(D && !A) == A || !D + + Order allow,deny + deny from all + + + Order allow,deny + deny from all + diff --git a/misc/infrastructure/keygen/config.pl b/misc/infrastructure/keygen/config.pl new file mode 100644 index 00000000..28f9a79f --- /dev/null +++ b/misc/infrastructure/keygen/config.pl @@ -0,0 +1,20 @@ +%ca = ( + 0 => + { + name => "Xonotic official", + check => sub + { + my ($inc) = @_; + return 0 if ($inc >= 0) && check_dnsbl([qr/.*:.*:.*/], [], ['torexit.dan.me.uk', 'aspews.ext.sorbs.net']); + return 0 if ($inc >= 0) && check_banlist('http://rm.endoftheinternet.org/~xonotic/bans/?action=list&servers=*'); + return 0 if check_sql('dbi:mysql:dbname=xonotic_ca', 'xonotic_ca', '************', 'ip', $inc); + 1; + } + }, + 15 => + { + name => "Xonotic testing", + check => sub { 1; } + } +); +$default_ca = 15; diff --git a/misc/infrastructure/keygen/response.d0ir b/misc/infrastructure/keygen/response.d0ir new file mode 100755 index 00000000..29fd5d42 --- /dev/null +++ b/misc/infrastructure/keygen/response.d0ir @@ -0,0 +1,211 @@ +#!/usr/bin/perl + +use strict; +use CGI; +use LWP::Simple; +use MIME::Base64; +use File::Temp; +use DBI; +my $cgi = CGI->new(); + +sub error($) +{ + my ($err) = @_; + print "Content-type: text/plain\n\nd0er $err"; + exit 0; +} + +sub check_dnsbl($$@) +{ + my ($goodpatterns, $badpatterns, $list) = @_; + + my $name = $ENV{REMOTE_HOST} . "."; + my $addr = $ENV{REMOTE_ADDR}; + + # check goodpatterns + for(@$goodpatterns) + { + return 0 + if $name =~ /^(??{$_})$/ || $addr =~ /^(??{$_})$/; + } + # check badpatterns + for(@$badpatterns) + { + return -1 + if $name =~ /^(??{$_})$/ || $addr =~ /^(??{$_})$/; + } + + # is he tor? + my $h = gethostbyname $addr; + return -1 + if not defined $h; + + my $blprefix = join '.', reverse unpack 'C4', $h; + my $i = 0; + for(@$list) + { + ++$i; + my $hn = "$blprefix.$_."; + my $h2 = gethostbyname $hn; + next + if not defined $h2; + return -1; + } + + return 0; +} + +# create table ip ( id INT AUTO_INCREMENT PRIMARY KEY, ip VARCHAR(64), t DATETIME, error BOOLEAN, INDEX(ip), INDEX(t), INDEX(error) ); +our $__CACHED_DBH__; + +sub check_sql($$$$$) +{ + my ($dsn, $u, $p, $tbl, $inc) = @_; + my $ip = $ENV{REMOTE_ADDR}; + my $DBH = ($__CACHED_DBH__ ? $__CACHED_DBH__ : ($__CACHED_DBH__ = DBI->connect($dsn, $u, $p, { RaiseError => 1, AutoCommit => 0 }))) + or die "DBI/DBD: $!"; + $DBH->do("set character set utf8"); + $DBH->do("set names utf8"); + if($inc < 0) + { + $DBH->do("update $tbl set error=true where ip=?", undef, $ip); + $DBH->commit(); + $DBH->disconnect(); + return 0; + } + elsif($inc == 0) + { + my $status = $DBH->selectrow_arrayref("select count(*) from $tbl where ip=? and error=false and t>date_sub(now(), interval 7 day)", undef, $ip) + or die "DBI/DBD: $!"; + $DBH->disconnect(); + return $status->[0] ? -1 : 0; + } + else + { + my $status = $DBH->selectall_arrayref("select error, t>date_sub(now(), interval 7 day) from $tbl where ip=?", undef, $ip) + or die "DBI/DBD: $!"; + if(@$status) + { + if($status->[0][0] || !$status->[0][1]) # error, or after interval + { + $DBH->do("update $tbl set error=false, t=now() where ip=?", undef, $ip); + $DBH->commit(); + $DBH->disconnect(); + return 0; + } + else # too soon + { + $DBH->disconnect(); + return -1; + } + } + else + { + $DBH->do("insert into $tbl(ip, error, t) values(?, false, now())", undef, $ip); + $DBH->commit(); + $DBH->disconnect(); + return 0; + } + } +} + +sub check_banlist($) +{ + my ($s) = @_; + my $ip = $ENV{REMOTE_ADDR}; + my @s = split /\n/, get $s; + for(0..@s/4-1) + { + my $i = $s[4*$_]; + return 1 if "$ip." =~ /^\Q$i\E\./; + } + return 0; +} + +our %ca = (); +our $default_ca = 0; + +do 'config.pl'; + +if((my $key = $cgi->param('key'))) +{ + local $| = 1; + undef local $/; + + my $ca = $cgi->param('ca'); + $ca = $default_ca if not defined $ca; + error "Invalid CA" if not defined $ca{$ca}; + error "Not allowed" if not $ca{$ca}->{check}->(1); + my $tempfh = undef; + eval + { + $tempfh = File::Temp->new(); + binmode $tempfh; + my $fh = $cgi->upload('key'); + if($fh) + { + binmode $fh; + print $tempfh $_ for <$fh>; + } + else + { + $key =~ s/ /+/g; + $key = decode_base64($key); + print $tempfh $key; + } + seek $tempfh, 0, 0; + + $ENV{REQUESTFILE} = $tempfh->filename; + $ENV{RESPONSEFILE} = $tempfh->filename; + $ENV{SECRET} = "key_$ca.d0sk"; + open my $errfh, '-|', './xonotic-keygen -P "$SECRET" -j "$REQUESTFILE" -o "$RESPONSEFILE" 2>&1' + or die "cannot start xonotic-keygen"; + my $err = <$errfh>; + close $errfh + or die "xonotic-keygen failed: $err"; + 1; + } + or do + { + $ca{$ca}->{check}->(-1); + die "$@"; + }; + + print "Content-type: application/octet-stream\n\n"; + binmode STDOUT; + print for <$tempfh>; +} +else +{ + print < + + + Xonotic keygen + + +

Xonotic keygen

+
+ To generate and sign a key IN GAME, follow these steps on the console: +
    +
  1. crypto_keygen $default_ca http://rm.endoftheinternet.org/~xonotic/keygen/?ca=$default_ca&key=
  2. +
+ To generate and sign a key MANUALLY, follow these steps on a UNIX command line: +
    +
  1. ./xonotic-keygen -p key_$default_ca.d0pk -o key_$default_ca.d0si
  2. +
  3. ./xonotic-keygen -p key_$default_ca.d0pk -I key_$default_ca.d0si -o request.d0iq -O camouflage.d0ic +
  4. Upload the request.d0iq file:
  5. +
  6. Save the response.d0ir file you are getting
  7. +
  8. ./xonotic-keygen -p key_$default_ca.d0pk -I key_$default_ca.d0si -c camouflage.d0ic -J response.d0ir -o key_$default_ca.d0si
  9. +
  10. Delete request.d0iq, camouflage.d0ic, response.d0ir
  11. +
+ Your key_$default_ca.d0si key is now signed. +
+ To use another CA, please enter its number here before using this page: + + + +EOF +} -- 2.39.2