#!/usr/bin/perl

########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####


# DBI : 0
# IO: 0


use DBI;

use vars qw/$db_address $dbUser $dbPw $bin_openssl $tmpdir/;
use strict;

$db_address = 'DBI:mysql:confixx:localhost;mysql_socket=/var/lib/mysql/mysql.sock';
$dbUser = 'confixx';
$dbPw = '1234';
$bin_openssl = '/usr/bin/openssl';
$tmpdir = '/var/www/confixx/tmp';

my ($user,$selfsigned,$sth,$dbh,$csr,$sql);

if ( $ARGV[0] ne "" ) {
  $user = $ARGV[0];
} else {
  &fehler("mlf||ssl_argv||#1001");
}

$selfsigned = $ARGV[1];


my $keyfile = "$tmpdir/$user.key";
my $csrfile = "$tmpdir/$user.csr";
my $crtfile = "$tmpdir/$user.crt";

$dbh = DBI->connect($db_address, $dbUser, $dbPw)
  or &fehler("mlf||scripts_db_connect||#2001||$DBI::errstr");

$sth = $dbh->prepare("SELECT privatekey, neu, countrycode, state, city, firm, unit, common, email, crt".
										 " FROM cssl WHERE kunde='$user'");

$sth->execute or 
	&fehler("mlf||#2002||ssl_db_fetch||$DBI::errstr");

my ($key, $new, $cc, $state, $city, $firm, $unit, $common, $email, $crt) = $sth->fetchrow_array or 
	&fehler("mlf||ssl_db_getuser||#2003||$user||$DBI::errstr");

$sth->finish;

if((defined $ARGV[1]) && ($ARGV[1] eq "match")){
  &matchKeyCrt( $key,$crt );
}

unless( $cc =~ /^\w\w$/ ) { &fehler("mlf||ssl_val_cc"); }
unless( $state ) { &fehler("mlf||ssl_val_state"); }
unless( $city ) { &fehler("mlf||ssl_val_city"); }
unless( $firm ) { &fehler("mlf||ssl_val_firm"); }
unless( $unit ) { &fehler("mlf||ssl_val_unit"); }
unless( $common ) { &fehler("mlf||ssl_val_common"); }
unless( $email =~ /\S+\@(?:\S+\.)+\S+/) { &fehler("mlf||ssl_val_email"); }

if(($key eq "") || $new){
  $key = &create_key();

} else {
  if ( open(KEY, ">$keyfile") ) {
		print KEY $key;
		close(KEY);
	} else {
		&fehler("mlf||scripts_file_read||#1002||$keyfile");
	}

} 

$csr = &create_csr( $selfsigned );

if ( $key && $csr ) {
	if ( $selfsigned ) {
		$sql = "UPDATE cssl SET crt='$csr', privatekey='$key', neu=0 WHERE kunde='$user'";
	} else {
		$sql = "UPDATE cssl SET csr='$csr', privatekey='$key', neu=0 WHERE kunde='$user'";
	}

	$dbh->do( $sql ) or 
		&fehler("mlf||ssl_db_update||#2004||$DBI::errstr");
}

$dbh->disconnect;

unlink $keyfile;
unlink $csrfile;


## Unterprogramme

sub create_key {

  my ($key);

  my $return = system("$bin_openssl genrsa -rand -des3 -out $keyfile 1024 2>/dev/null");

	unless ( $return == 0 ) {
		&fehler("mlf||ssl_key_create||#1003");
	}

  if ( open(KEY, "<$keyfile") ){
		while(<KEY>){
			$key .= $_;
		}
		close(KEY);
	} else {
		&fehler("mlf||scripts_file_open_read||#1004");
	}

	return $key;
}


sub create_csr{

	my ($selfsigned) = @_;

	my ($csr,$cmd);



	if ( $selfsigned ) {
		$cmd = "$bin_openssl  req -new -x509 -days 365 -key $keyfile -out $csrfile";
	} else {
		$cmd = "$bin_openssl  req -new -key $keyfile -out $csrfile";
	}

	if ( open(INPUT,"| $cmd 1>/dev/null") ) {
		print INPUT <<"SETTINGS";
$cc
$state
$city
$firm
$unit
$common
$email
SETTINGS

		print INPUT "\n\n";

		close INPUT;
	}

  if ( open(CSR, "$csrfile") ) {
		while(<CSR>){
			$csr .= $_;
		}
		close(CSR);	
	} else {
		&fehler("mlf||scripts_file_open_read||#1006||$csrfile");
	}

	return $csr;
}


sub print_file{
  my ($file) =@_;
  open(FILE, $file);
  while (<FILE>){
    print $_;
  }
}


sub fehler {
  my ($msg) = @_;
  if($msg ne ""){
    print "$msg\n";
  }
  exit 1;
}


sub matchKeyCrt {
	my ($key,$crt) = @_;

  $dbh->disconnect;

  my ($md5_key, $md5_crt);

  if ( $crt && $key ) {

		open(KEY, ">$keyfile");
		$key =~ s/\r//g;
		print KEY $key;
		close(KEY);

		open(CRT, ">$crtfile");
		$crt =~ s/\r//g;
		print CRT $crt;
		close(CRT);

		$md5_key = `$bin_openssl rsa -noout -modulus -in $keyfile 2>/dev/null | $bin_openssl md5`;
		$md5_crt = `$bin_openssl x509 -noout -modulus -in $crtfile | $bin_openssl md5`;

		unlink($keyfile); 
		unlink($crtfile); 
		if(($md5_key ne "") && ($md5_key eq $md5_crt) && ($md5_key ne "d41d8cd98f00b204e9800998ecf8427e\n") && ($md5_key ne "68b329da9893e34099c7d8ad5cb9c940\n")){

			exit 0; ## success

		}
  }

	exit 1; ## fail
}
## //Unterprogramme
