commit
e136e7cbbf
@ -0,0 +1,212 @@ |
|||||||
|
$Id: CHANGES,v 1.23 2006/07/25 20:10:54 sm Exp $ |
||||||
|
|
||||||
|
version 0.7.5 - Tue July 25 2006 |
||||||
|
* added swedish translation |
||||||
|
many thanks to Daniel Nylander |
||||||
|
|
||||||
|
version 0.7.4 - Thu June 29 2006 |
||||||
|
* fixed invalid filename encoding with german umlauts in base64 |
||||||
|
thanks to Bruno Blumenthal |
||||||
|
* Fixed display of UTF8 characters in the GUI |
||||||
|
Debian #367829 |
||||||
|
|
||||||
|
version 0.7.3 - Tue May 23 2006 |
||||||
|
* Add environment variable |
||||||
|
Gentoo #78576 |
||||||
|
thanks to dragonheart at gentoo dot org |
||||||
|
* Fixed crash when CA is created with nsCertType |
||||||
|
Debian #354386 |
||||||
|
|
||||||
|
version 0.7.3 - Tue May 23 2006 |
||||||
|
* Enhanced version detection |
||||||
|
thanks to Peter Marschall |
||||||
|
Debian #360766 #360555 |
||||||
|
* Changed command for openssl due to changed openssl behavior |
||||||
|
regarding fingerprints |
||||||
|
thanks to Peter Marschall |
||||||
|
Debian #360768 |
||||||
|
* Added "friendly name" to PKCS#12 export |
||||||
|
Debian #364617 |
||||||
|
* Corrected exit call |
||||||
|
thanks to Peter Marschall |
||||||
|
Debian #360767 |
||||||
|
|
||||||
|
|
||||||
|
version 0.7.2 - Sat Feb 18 2006 |
||||||
|
* Fixed bug, which made keysize always 4096 |
||||||
|
* Implemented correct usage of openssl crl depending on openssl version |
||||||
|
* Added tar file support for export |
||||||
|
|
||||||
|
version 0.7.1 - Sat Oct 22 2005 |
||||||
|
* Fixed possible crashbug, thanks to |
||||||
|
* Choose CA validity as maximal certificate lifetime |
||||||
|
* correctly include/don't include keys in exported certificate files |
||||||
|
thanks to "thus0 at free dot fr" |
||||||
|
* added ripemd160 support, thanks to Wim Lewis |
||||||
|
* added possibility to create pkcs#12 without password |
||||||
|
* fixed broken OU in SubCA, thanks to Charles Lepple |
||||||
|
* fixed bug which made saving options with comboboxes impossible |
||||||
|
thanks to "thus0 at free dot fr" |
||||||
|
* fixed bug inseting the right serial number during import |
||||||
|
thanks to Daniel Kahn Gillmor |
||||||
|
|
||||||
|
version 0.7.0 - Sun Apr 10 2005 |
||||||
|
* migrated to perl-Gtk2 |
||||||
|
* added advanced export options (Debian #293931) |
||||||
|
* added CA history |
||||||
|
* fixed some minor bugs |
||||||
|
|
||||||
|
version 0.6.8 (beta) - Sun Feb 20 2004 |
||||||
|
* added detection for openssl 0.9.8 |
||||||
|
* removed crlDistributionPoint for Root-CA |
||||||
|
* added patch for multiple OUs |
||||||
|
Thanks to Uwe Arndt <arndt@uni-koblenz.de> |
||||||
|
* added patch for multiple subjectAltName extensions (Debian #271183) |
||||||
|
Thanks to Peter Marschall <peter@adpm.de> |
||||||
|
|
||||||
|
version 0.6.7 (beta) - Mon Dec 5 2004 |
||||||
|
* added import functionality |
||||||
|
|
||||||
|
version 0.6.6 (beta) - Fri Aug 13 2004 |
||||||
|
* added czech translation |
||||||
|
Thanks to Robert Wolf <gentoo@slave.umbr.cas.cz> |
||||||
|
|
||||||
|
version 0.6.5 (beta) - Thu Aug 05 2004 |
||||||
|
* added spanish translation |
||||||
|
Thanks to Ramon Pons Vivanco <rpons@rinu.org> |
||||||
|
* force (re)parsing a newly created request |
||||||
|
* force delete of internal structures, when deleting a CA |
||||||
|
|
||||||
|
version 0.6.4 (beta) - Thu Jul 15 2004 |
||||||
|
* fixed bug, showing wrong options for renewal of certificates |
||||||
|
* fixed bug creating requests via rightclick directly after creating a new CA |
||||||
|
(thanks to wbx@openbsd.de) |
||||||
|
* fixed bug which added ugly empty box to cert/req page |
||||||
|
* fixed bug with wrong openssl.conf during startup (server-cert with |
||||||
|
ca-extensions) |
||||||
|
(thanks to bernhard.dawuidow@tronicplanet.de) |
||||||
|
* fixed ca-config dialog during creation of root-ca (drop-downs) |
||||||
|
(thanks to X_KurJ@viessmann.com) |
||||||
|
* revocation reason can be given with openssl 0.9.7 |
||||||
|
* changed default exportdir to users home |
||||||
|
* remeber exportdir from last export |
||||||
|
* added possibility to set the extension extendedKeyUsage |
||||||
|
* added possibility to leave email out of the subject dn (0.9.7) |
||||||
|
|
||||||
|
version 0.6.3 (beta) - Wed Jun 16 2004 |
||||||
|
* fixed bug which made it impossible to create new requests |
||||||
|
|
||||||
|
version 0.6.2 (beta) - Sun Jun 13 2004 |
||||||
|
* added new look for some functions |
||||||
|
* key, request and certificate can be generated in one step |
||||||
|
* code cleanup |
||||||
|
|
||||||
|
version 0.6.1 (beta) - Sat May 22 2004 |
||||||
|
* fixed bug, which made it impossible to create a new Root-CA |
||||||
|
Thanks to Olaf Gellert <og@pre-secure.de> |
||||||
|
|
||||||
|
version 0.6.0 (beta) - Tue May 11 2004 |
||||||
|
* some minor usability improvements |
||||||
|
* added possibility to create SubCAs now |
||||||
|
* added possibility also to use DSA keys |
||||||
|
* added possibility to select the digest during key creation |
||||||
|
* added possibility to export the complete CA-chain of a SubCA |
||||||
|
Thanks a lot to Olaf Gellert <og@pre-secure.de> for ideas and patches. |
||||||
|
|
||||||
|
version 0.5.4 (beta) - Fri Oct 3 2003 |
||||||
|
* added a lot of configuration options |
||||||
|
* correctly import/show details of requests without extensions |
||||||
|
(thanks to James.Leavitt@anywaregroup.com) |
||||||
|
|
||||||
|
version 0.5.3 (beta) - Mon Sep 29 2003 |
||||||
|
* fixed wrong label while creating new CA |
||||||
|
* fixed bug, saving configuration is possible again |
||||||
|
|
||||||
|
version 0.5.2 (beta) - Mon Sep 1 2003 |
||||||
|
* added renewal of certificates |
||||||
|
|
||||||
|
version 0.5.1 (beta) - Tue Aug 26 2003 |
||||||
|
* code cleanup |
||||||
|
* fixed some minor bugs and typos |
||||||
|
* corrected some window sizes and tables |
||||||
|
* added accelerators to the menu |
||||||
|
|
||||||
|
version 0.5.0 (beta) - Sat Aug 16 2003 |
||||||
|
* GUI rewriten with perl-Gtk/Gnome |
||||||
|
|
||||||
|
version 0.4.9 (beta) - Sat Jul 5 2003 |
||||||
|
* added german translation |
||||||
|
|
||||||
|
version 0.4.8 (beta) - Tue Jul 1 2003 |
||||||
|
* convert index.txt if openssl changed from 0.9.6x to 0.9.7x |
||||||
|
|
||||||
|
version 0.4.7 (beta) - Fri Jun 27 2003 |
||||||
|
* added export into zip-file |
||||||
|
thanks to ludwig.nussel@suse.de |
||||||
|
|
||||||
|
version 0.4.6 (beta) - Mon Jun 23 2003 |
||||||
|
* some tiny usability improvements |
||||||
|
thanks to ludwig.nussel@suse.de again |
||||||
|
|
||||||
|
version 0.4.5 (beta) - Thu Jun 19 2003 |
||||||
|
* some usability improvements |
||||||
|
thanks to ludwig.nussel@suse.de |
||||||
|
* some more configuration options |
||||||
|
|
||||||
|
version 0.4.4 (beta) - Fri Oct 4 2002 |
||||||
|
* Fixed bug exporting keys in PEM format |
||||||
|
* Fixed possible empty lines in cert/key/reqlist |
||||||
|
thanks to waldemar.mertke@gmx.de |
||||||
|
|
||||||
|
version 0.4.3 (beta) - Fri Sep 27 2002 |
||||||
|
* Fixed some minor bugs and typos (e.g. concerning openssl 0.9.7) |
||||||
|
thanks to iebgener@yahoo.com and waldemar.mertke@gmx.de |
||||||
|
|
||||||
|
version 0.4.2 (beta) - Sat Aug 24 2002 |
||||||
|
* fixed revocation when serial is > 15 |
||||||
|
thanks to curly@e-card.bg |
||||||
|
* fixed recognition of java-generated requests |
||||||
|
thanks to matthew.lewis@syntegra.com |
||||||
|
* code cleanup |
||||||
|
|
||||||
|
version 0.4.1 (beta) - Wed Aug 21 2002 |
||||||
|
* fixed revocation |
||||||
|
* added some colors |
||||||
|
* thanks to curly@e-card.bg |
||||||
|
|
||||||
|
version 0.4.0 (beta) - Sun Aug 18 2002 |
||||||
|
* works independent of OpenCA modules now |
||||||
|
* some enhancements to functionality (e.g. export of key without |
||||||
|
passwd) |
||||||
|
* some smaller bugfixes in usability |
||||||
|
* new specfile (thanks to oron@actcom.co.il) |
||||||
|
|
||||||
|
version 0.3.4 (beta) - Mon Jun 3 2002 |
||||||
|
* fixed wrong templatedir when creating a new CA |
||||||
|
|
||||||
|
version 0.3.3 (beta) - Sun Jun 2 2002 |
||||||
|
* fixed some minor bugs and typos |
||||||
|
import of requests from ssh-sentinel should work now without problems |
||||||
|
|
||||||
|
version 0.3.2 (beta) - Sat May 11 2002 |
||||||
|
* added parser for x509 extensions when viewing certificate details |
||||||
|
|
||||||
|
version 0.3.1 (beta) - Fri May 3 2002 |
||||||
|
* added option to view complete certificate/request as text |
||||||
|
|
||||||
|
version 0.3.0 (beta) - Thu Apr 18 2002 |
||||||
|
* added possibility to configure openssl |
||||||
|
* fixed some minor bugs |
||||||
|
|
||||||
|
version 0.2.5 (beta) - Sun Apr 7 2002 |
||||||
|
* improved usabilty and errorhandling |
||||||
|
* fixed some minor bugs and typos |
||||||
|
|
||||||
|
version 0.2.4 (beta) - Sun Mar 31 2002 |
||||||
|
* added possibilty to import PKCS#10 requests |
||||||
|
* added function to delete a configured CA |
||||||
|
|
||||||
|
version 0.2.3 (beta) - Tue Mar 26 2002 |
||||||
|
* fixed bug with expiration date defaults to 30 days when creating |
||||||
|
a new CA |
||||||
|
* change status to E in index.txt, if certificate is expired |
@ -0,0 +1,30 @@ |
|||||||
|
1. Unpack the sources (seems like you got it already) |
||||||
|
|
||||||
|
2. Configure the following paths for your setup. These variables |
||||||
|
are located in the file tinyca itself. |
||||||
|
|
||||||
|
@INC (location of the directory lib) |
||||||
|
$init->{'opensslbin'} (location of your openssl binary) |
||||||
|
$init->{'templatedir'} (location of the directory templates) |
||||||
|
$init->{'zipbin'} (location of your zip binary) |
||||||
|
$init->{'tarbin'} (location of your tar binary) |
||||||
|
|
||||||
|
3. If you want to have german/spanish/czech/swedish texts: |
||||||
|
Generate the file tinyca.mo from po/de.po: |
||||||
|
msgfmt po/de.po -o locale/de/LC_MESSAGES/tinyca.mo |
||||||
|
msgfmt po/es.po -o locale/es/LC_MESSAGES/tinyca.mo |
||||||
|
msgfmt po/cs.po -o locale/cs/LC_MESSAGES/tinyca.mo |
||||||
|
msgfmt po/sv.po -o locale/sv/LC_MESSAGES/tinyca.mo |
||||||
|
or even more simple: call make in the directory po/ |
||||||
|
|
||||||
|
If your locale is not set to german/spanish: |
||||||
|
export LC_ALL=de_DE.UTF-8 |
||||||
|
or |
||||||
|
export LC_ALL=es_ES.UTF-8 |
||||||
|
or |
||||||
|
export LC_ALL=cs_CZ.UTF-8 |
||||||
|
or |
||||||
|
export LC_ALL=sv_SE.UTF-8 |
||||||
|
before you call tinyca. |
||||||
|
|
||||||
|
4. Call tinyca2, use it and report bugs :-)) |
@ -0,0 +1,9 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
mkdir -p locale/de/LC_MESSAGES |
||||||
|
mkdir -p locale/es/LC_MESSAGES |
||||||
|
mkdir -p locale/cs/LC_MESSAGES |
||||||
|
|
||||||
|
msgfmt po/de.po -o locale/de/LC_MESSAGES/tinyca2.mo |
||||||
|
msgfmt po/es.po -o locale/es/LC_MESSAGES/tinyca2.mo |
||||||
|
msgfmt po/cs.po -o locale/cs/LC_MESSAGES/tinyca2.mo |
@ -0,0 +1,713 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: CERT.pm,v 1.11 2006/06/28 21:50:41 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
|
||||||
|
package CERT; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $that = shift; |
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
$self->{'OpenSSL'} = shift; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# read certificates in directory into list |
||||||
|
# |
||||||
|
sub read_certlist { |
||||||
|
my ($self, $certdir, $crlfile, $indexfile, $force, $main) = @_; |
||||||
|
|
||||||
|
my($f, $certlist, $crl, $modt, $parsed, $tmp, $t, $c, $p, @files); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$certlist = []; |
||||||
|
|
||||||
|
$modt = (stat($certdir))[9]; |
||||||
|
|
||||||
|
if(defined($self->{'lastread'}) && |
||||||
|
($self->{'lastread'} >= $modt) && |
||||||
|
not defined($force)) { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
return(0); |
||||||
|
} |
||||||
|
|
||||||
|
$crl = $self->{'OpenSSL'}->parsecrl($crlfile, $force); |
||||||
|
|
||||||
|
opendir(DIR, $certdir) || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Can't open Certificate directory: %s"), $certdir); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return(0); |
||||||
|
}; |
||||||
|
|
||||||
|
while($f = readdir(DIR)) { |
||||||
|
next if $f =~ /^\./; |
||||||
|
push(@files, $f); |
||||||
|
$c++; |
||||||
|
} |
||||||
|
|
||||||
|
$main->{'barbox'}->pack_start($main->{'progress'}, 0, 0, 0); |
||||||
|
$main->{'progress'}->show(); |
||||||
|
foreach $f (@files) { |
||||||
|
next if $f =~ /^\./; |
||||||
|
|
||||||
|
$f =~ s/\.pem//; |
||||||
|
|
||||||
|
$tmp = HELPERS::dec_base64($f); |
||||||
|
next if not defined($tmp); |
||||||
|
next if $tmp eq ""; |
||||||
|
|
||||||
|
if(defined($main)) { |
||||||
|
$t = sprintf(_(" Read Certificate: %s"), $tmp); |
||||||
|
GUI::HELPERS::set_status($main, $t); |
||||||
|
$p += 100/$c; |
||||||
|
if($p/100 <= 1) { |
||||||
|
$main->{'progress'}->set_fraction($p/100); |
||||||
|
while(Gtk2->events_pending) { |
||||||
|
Gtk2->main_iteration; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
my $debugf = $certdir."/".$f.".pem"; |
||||||
|
|
||||||
|
$parsed = $self->{'OpenSSL'}->parsecert($crlfile, $indexfile, |
||||||
|
$certdir."/".$f.".pem", $force); |
||||||
|
|
||||||
|
defined($parsed) || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_error(_("Can't read Certificate")); |
||||||
|
}; |
||||||
|
|
||||||
|
$tmp .= "%".$parsed->{'STATUS'}; |
||||||
|
|
||||||
|
push(@{$certlist}, $tmp); |
||||||
|
} |
||||||
|
@{$certlist} = sort(@{$certlist}); |
||||||
|
closedir(DIR); |
||||||
|
|
||||||
|
$self->{'certlist'} = $certlist; |
||||||
|
|
||||||
|
$self->{'lastread'} = time(); |
||||||
|
|
||||||
|
if(defined($main)) { |
||||||
|
$main->{'progress'}->set_fraction(0); |
||||||
|
$main->{'barbox'}->remove($main->{'progress'}); |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
} |
||||||
|
|
||||||
|
return(1); # got new list |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get information for renewing a certifikate |
||||||
|
# |
||||||
|
sub get_renew_cert { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
my ($cert, $status, $t, $ca, $cadir); |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
if((not defined($opts->{'certfile'})) || |
||||||
|
(not defined($opts->{'passwd'})) || |
||||||
|
($opts->{'certfile'} eq '') || |
||||||
|
($opts->{'passwd'} eq '')) { |
||||||
|
|
||||||
|
$cert = $main->{'certbrowser'}->selection_dn(); |
||||||
|
|
||||||
|
if(not defined($cert)) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Certificate first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$ca = $main->{'certbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
$status = $main->{'certbrowser'}->selection_status(); |
||||||
|
|
||||||
|
if($status eq _("VALID")) { |
||||||
|
$t = sprintf( |
||||||
|
_("Can't renew Certifikate with Status: %s\nPlease revoke the Certificate first"), |
||||||
|
$status); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'certname'} = HELPERS::enc_base64($cert); |
||||||
|
$opts->{'reqname'} = $opts->{'certname'}; |
||||||
|
$opts->{'certfile'} = $cadir."/certs/".$opts->{'certname'}.".pem"; |
||||||
|
$opts->{'keyfile'} = $cadir."/keys/".$opts->{'certname'}.".pem"; |
||||||
|
$opts->{'reqfile'} = $cadir."/req/".$opts->{'certname'}.".pem"; |
||||||
|
|
||||||
|
if((not -s $opts->{'certfile'}) || |
||||||
|
(not -s $opts->{'keyfile'}) || |
||||||
|
(not -s $opts->{'reqfile'})) { |
||||||
|
$t = _("Key and Request are necessary for renewal of a Certificate\nRenewal is not possible!"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_req_sign_dialog($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->{'REQ'}->sign_req($main, $opts); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get information for revoking a certifikate |
||||||
|
# |
||||||
|
sub get_revoke_cert { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
my ($cert, $status, $t, $ca, $cadir); |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
if((not defined($opts->{'certfile'})) || |
||||||
|
(not defined($opts->{'passwd'})) || |
||||||
|
($opts->{'certfile'} eq '') || |
||||||
|
($opts->{'passwd'} eq '')) { |
||||||
|
$opts->{'certfile'} = $main->{'certbrowser'}->selection_fname(); |
||||||
|
|
||||||
|
if(not defined($opts->{'certfile'})) { |
||||||
|
$t = _("Please select a Certificate first"); |
||||||
|
GUI::HELPERS::print_info($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$ca = $main->{'certbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
$cert = $main->{'certbrowser'}->selection_dn(); |
||||||
|
$status = $main->{'certbrowser'}->selection_status(); |
||||||
|
|
||||||
|
if($status ne _("VALID")) { |
||||||
|
$t = sprintf(_("Can't revoke Certifikate with Status: %s"), |
||||||
|
$status); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'certname'} = HELPERS::enc_base64($cert); |
||||||
|
$opts->{'cert'} = $cert; |
||||||
|
|
||||||
|
$main->show_cert_revoke_dialog($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$self->revoke_cert($main, $opts); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# now really revoke the certificate |
||||||
|
# |
||||||
|
sub revoke_cert { |
||||||
|
my ($self, $main, $opts) = @_; |
||||||
|
|
||||||
|
my($ca, $cadir, $ret, $t, $ext, $reason); |
||||||
|
|
||||||
|
$ca = $main->{'certbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
if(defined($opts->{'reason'}) && $opts->{'reason'} ne '') { |
||||||
|
$reason = $opts->{'reason'}; |
||||||
|
} else { |
||||||
|
$reason = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->revoke( |
||||||
|
'config' => $main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
'infile' => $cadir."/certs/".$opts->{'certname'}.".pem", |
||||||
|
'pass' => $opts->{'passwd'}, |
||||||
|
'reason' => $reason |
||||||
|
); |
||||||
|
|
||||||
|
if($ret eq 1) { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = _("Wrong CA password given\nRevoking the Certificate failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret eq 2) { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = _("CA Key not found\nRevoking the Certificate failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret) { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = _("Revoking the Certificate failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->newcrl( |
||||||
|
'config' => $main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
'pass' => $opts->{'passwd'}, |
||||||
|
'crldays' => 365, |
||||||
|
'outfile' => $cadir."/crl/crl.pem" |
||||||
|
); |
||||||
|
|
||||||
|
if (not -s $cadir."/crl/crl.pem" || $ret) { |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Generating a new Revocation List failed"), $ext); |
||||||
|
} |
||||||
|
|
||||||
|
$self->{'OpenSSL'}->parsecrl( $cadir."/crl/crl.pem", 1); |
||||||
|
|
||||||
|
$self->reread_cert($main, $opts->{'cert'}); |
||||||
|
|
||||||
|
# force reread of certlist |
||||||
|
$main->{'certbrowser'}->update($cadir."/certs", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get name of certificatefile to delete |
||||||
|
# |
||||||
|
sub get_del_cert { |
||||||
|
my ($self, $main) = @_; |
||||||
|
|
||||||
|
my($certname, $cert, $certfile, $status, $t, $cadir, $ca); |
||||||
|
|
||||||
|
$certfile = $main->{'certbrowser'}->selection_fname(); |
||||||
|
|
||||||
|
if(not defined $certfile) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Certificate first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$ca = $main->{'certbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
$cert = $main->{'certbrowser'}->selection_dn(); |
||||||
|
$status = $main->{'certbrowser'}->selection_status(); |
||||||
|
|
||||||
|
$certname = HELPERS::enc_base64($cert); |
||||||
|
|
||||||
|
if($status eq _("VALID")) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Can't delete VALID certificate!\nPlease revoke the Certificate first.")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_del_confirm($certfile, 'cert'); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# now really delete the certificatefile |
||||||
|
# |
||||||
|
sub del_cert { |
||||||
|
my ($self, $main, $file) = @_; |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
unlink($file); |
||||||
|
|
||||||
|
my $cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$main->{'certbrowser'}->update($cadir."/certs", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get informations for exporting a certificate |
||||||
|
# |
||||||
|
sub get_export_cert { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
my($ca, $t, $cn, $email, $cadir); |
||||||
|
|
||||||
|
if(not defined($opts)) { |
||||||
|
$cn = $main->{'certbrowser'}->selection_cn(); |
||||||
|
$email = $main->{'certbrowser'}->selection_email(); |
||||||
|
|
||||||
|
if(not defined $cn) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Certificate first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$ca = $main->{'certbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'certbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$opts->{'status'} = $main->{'certbrowser'}->selection_status(); |
||||||
|
$opts->{'cert'} = $main->{'certbrowser'}->selection_dn(); |
||||||
|
|
||||||
|
$opts->{'certname'} = HELPERS::enc_base64($opts->{'cert'}); |
||||||
|
$opts->{'certfile'} = $cadir."/certs/".$opts->{'certname'}.".pem"; |
||||||
|
$opts->{'keyfile'} = $cadir."/keys/".$opts->{'certname'}.".pem"; |
||||||
|
$opts->{'cafile'} = $cadir."/cacert.pem"; |
||||||
|
|
||||||
|
if (-f $cadir."/cachain.pem") { |
||||||
|
$opts->{'cafile'} = $cadir."/cachain.pem"; |
||||||
|
} |
||||||
|
|
||||||
|
if($opts->{'status'} ne _("VALID")) { |
||||||
|
$t = _("Certificate seems not to be VALID"); |
||||||
|
$t .= "\n"; |
||||||
|
$t .= _("Export is not possible"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'parsed'} = $self->parse_cert($main, $opts->{'certname'}); |
||||||
|
|
||||||
|
if((defined($email)) && $email ne '' && $email ne ' ') { |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/$email-cert.pem"; |
||||||
|
}elsif((defined($cn)) && $cn ne '' && $cn ne ' ') { |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/$cn-cert.pem"; |
||||||
|
}else{ |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/cert.pem"; |
||||||
|
} |
||||||
|
$opts->{'format'} = 'PEM'; |
||||||
|
$opts->{'include'} = 0; |
||||||
|
$opts->{'incfp'} = 0; |
||||||
|
$opts->{'nopass'} = 0; |
||||||
|
$opts->{'friendlyname'} = ''; |
||||||
|
|
||||||
|
$main->show_export_dialog($opts, 'cert'); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'outfile'})) || ($opts->{'outfile'} eq '')) { |
||||||
|
$main->show_export_dialog($opts, 'cert'); |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Please give at least the output file")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if($opts->{'format'} eq 'P12') { |
||||||
|
if(not -s $opts->{'keyfile'}) { |
||||||
|
$t = _("Key is necessary for export as PKCS#12"); |
||||||
|
$t .= "\n"; |
||||||
|
$t .= _("Export is not possible!"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'p12passwd'})) && |
||||||
|
(not $opts->{'nopass'})) { |
||||||
|
$opts->{'includeca'} = 1; |
||||||
|
$main->show_p12_export_dialog($opts, 'cert'); |
||||||
|
return; |
||||||
|
} |
||||||
|
} elsif(($opts->{'format'} eq 'ZIP') || ($opts->{'format'} eq 'TAR')) { |
||||||
|
if(not -s $opts->{'keyfile'}) { |
||||||
|
$t = sprintf( |
||||||
|
_("Key is necessary for export as %s"), $opts->{'format'}); |
||||||
|
$t .= "\n"; |
||||||
|
$t .= _("Export is not possible!"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$self->export_cert($main, $opts); #FIXME no need for two functions |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
# |
||||||
|
# now really export the certificate |
||||||
|
# |
||||||
|
sub export_cert { |
||||||
|
my ($self, $main, $opts) = @_; |
||||||
|
|
||||||
|
my($ca, $t, $out, $ret, $ext); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
|
||||||
|
if($opts->{'format'} eq 'PEM') { |
||||||
|
if($opts->{'incfp'}) { |
||||||
|
$out = ''; |
||||||
|
$out .= "Fingerprint (MD5): $opts->{'parsed'}->{'FINGERPRINTMD5'}\n"; |
||||||
|
$out .= "Fingerprint (SHA1): $opts->{'parsed'}->{'FINGERPRINTSHA1'}\n\n"; |
||||||
|
} else { |
||||||
|
$out = ''; |
||||||
|
} |
||||||
|
|
||||||
|
$out .= $opts->{'parsed'}->{'PEM'}; |
||||||
|
|
||||||
|
if($opts->{'include'}) { |
||||||
|
open(IN, "<$opts->{'keyfile'}") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Can't open Certificate file: %s: %s"), |
||||||
|
$opts->{'keyfile'}, $!); |
||||||
|
return; |
||||||
|
}; |
||||||
|
$out .= "\n"; |
||||||
|
$out .= $_ while(<IN>); |
||||||
|
close(IN); |
||||||
|
} |
||||||
|
} elsif ($opts->{'format'} eq 'DER') { |
||||||
|
$out = $opts->{'parsed'}->{'DER'}; |
||||||
|
} elsif ($opts->{'format'} eq 'TXT') { |
||||||
|
$out = $opts->{'parsed'}->{'TEXT'}; |
||||||
|
} elsif ($opts->{'format'} eq 'P12') { |
||||||
|
unlink($opts->{'outfile'}); |
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->genp12( |
||||||
|
certfile => $opts->{'certfile'}, |
||||||
|
keyfile => $opts->{'keyfile'}, |
||||||
|
cafile => $opts->{'cafile'}, |
||||||
|
outfile => $opts->{'outfile'}, |
||||||
|
passwd => $opts->{'passwd'}, |
||||||
|
p12passwd => $opts->{'p12passwd'}, |
||||||
|
includeca => $opts->{'includeca'}, |
||||||
|
nopass => $opts->{'nopass'}, |
||||||
|
friendly => $opts->{'friendlyname'} |
||||||
|
); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
if($ret eq 1) { |
||||||
|
$t = "Wrong password given\nDecrypting Key failed\nGenerating PKCS#12 failed"; |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
return; |
||||||
|
} elsif($ret || (not -s $opts->{'outfile'})) { |
||||||
|
$t = _("Generating PKCS#12 failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
|
||||||
|
$t = sprintf(_("Certificate and Key successfully exported to %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t, $ext); |
||||||
|
return; |
||||||
|
|
||||||
|
} elsif (($opts->{'format'} eq "ZIP") || ($opts->{'format'} eq "TAR")) { |
||||||
|
|
||||||
|
my $tmpcert = "$main->{'tmpdir'}/cert.pem"; |
||||||
|
my $tmpkey = "$main->{'tmpdir'}/key.pem"; |
||||||
|
my $tmpcacert = "$main->{'tmpdir'}/cacert.pem"; |
||||||
|
|
||||||
|
open(OUT, ">$tmpcert") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Can't create temporary file: %s: %s"), |
||||||
|
$tmpcert, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT $opts->{'parsed'}->{'PEM'}; |
||||||
|
close OUT; |
||||||
|
|
||||||
|
# store key in temporary location |
||||||
|
{ |
||||||
|
open(IN, "<$opts->{'keyfile'}") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Can't read Key file: %s: %s"), $tmpcert, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
my @key = <IN>; |
||||||
|
close IN; |
||||||
|
|
||||||
|
open(OUT, ">$tmpkey") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Can't create temporary file: %s: %s"), |
||||||
|
$tmpcert, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT @key; |
||||||
|
close OUT; |
||||||
|
} |
||||||
|
|
||||||
|
# store cacert in temporary location |
||||||
|
{ |
||||||
|
open(IN, "<$opts->{'cafile'}") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Can't read CA certificate")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
my @cacert = <IN>; |
||||||
|
close IN; |
||||||
|
|
||||||
|
open(OUT, ">$tmpcacert") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Can't create temporary file")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT @cacert; |
||||||
|
close OUT; |
||||||
|
} |
||||||
|
|
||||||
|
unlink($opts->{'outfile'}); |
||||||
|
if($opts->{'format'} eq "ZIP") { |
||||||
|
system($main->{'init'}->{'zipbin'}, '-j', $opts->{'outfile'}, |
||||||
|
$tmpcacert, $tmpkey, $tmpcert); |
||||||
|
my $ret = $? >> 8; |
||||||
|
} elsif ($opts->{'format'} eq "TAR") { |
||||||
|
system($main->{'init'}->{'tarbin'}, 'cfv', $opts->{'outfile'}, |
||||||
|
$tmpcacert, $tmpkey, $tmpcert); |
||||||
|
} |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
if(not -s $opts->{'outfile'} || $ret) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
sprintf(_("Generating %s file failed"), $opts->{'format'}) |
||||||
|
); |
||||||
|
} else { |
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
|
||||||
|
$t = sprintf( |
||||||
|
_("Certificate and Key successfully exported to %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t); |
||||||
|
unlink($tmpcacert); |
||||||
|
unlink($tmpcert); |
||||||
|
unlink($tmpkey); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
$t = sprintf(_("Invalid Format for export_cert(): %s"), |
||||||
|
$opts->{'format'}); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
open(OUT, ">$opts->{'outfile'}") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't open output file: %s: %s"), |
||||||
|
$opts->{'outfile'}, $!); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
print OUT $out; |
||||||
|
close OUT; |
||||||
|
|
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
|
||||||
|
$t = sprintf(_("Certificate successfully exported to: %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub reread_cert { |
||||||
|
my ($self, $main, $name) = @_; |
||||||
|
|
||||||
|
my ($parsed, $tmp); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$name = HELPERS::enc_base64($name); |
||||||
|
|
||||||
|
$parsed = $self->parse_cert($main, $name, 1); |
||||||
|
|
||||||
|
# print STDERR "DEBUG: status $parsed->{'STATUS'}\n"; |
||||||
|
|
||||||
|
foreach(@{$self->{'certlist'}}) { |
||||||
|
if(/^$name%/) { |
||||||
|
; #delete |
||||||
|
} else { |
||||||
|
push(@{$tmp}, $_); |
||||||
|
} |
||||||
|
} |
||||||
|
push(@{$tmp}, $name."%".$parsed->{'STATUS'}); |
||||||
|
@{$tmp} = sort(@{$tmp}); |
||||||
|
|
||||||
|
delete($self->{'certlist'}); |
||||||
|
$self->{'certlist'} = $tmp; |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub parse_cert { |
||||||
|
my ($self, $main, $name, $force) = @_; |
||||||
|
|
||||||
|
my($ca, $certfile, $x509, $parsed); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
|
||||||
|
if($name eq 'CA') { |
||||||
|
$certfile = $main->{'CA'}->{$ca}->{'dir'}."/cacert.pem"; |
||||||
|
} else { |
||||||
|
$certfile = $main->{'CA'}->{$ca}->{'dir'}."/certs/".$name.".pem"; |
||||||
|
} |
||||||
|
|
||||||
|
$parsed = $self->{'OpenSSL'}->parsecert( |
||||||
|
$main->{'CA'}->{$ca}->{'dir'}."/crl/crl.pem", |
||||||
|
$main->{'CA'}->{$ca}->{'dir'}."/index.txt", |
||||||
|
$certfile, |
||||||
|
$force |
||||||
|
); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return($parsed); |
||||||
|
} |
||||||
|
|
||||||
|
1 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,173 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: CALLBACK.pm,v 1.6 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package GUI::CALLBACK; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
# |
||||||
|
# fill given var-reference with text from entry |
||||||
|
# |
||||||
|
sub entry_to_var { |
||||||
|
my ($widget, $entry, $var, $box, $words) = @_; |
||||||
|
|
||||||
|
if(defined($words)) { |
||||||
|
$$var = $words->{$entry->get_text()}; |
||||||
|
}else{ |
||||||
|
$$var = $entry->get_text(); |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($box)) { |
||||||
|
$box->{'button_ok'}->set_sensitive(1); |
||||||
|
$box->{'button_apply'}->set_sensitive(1); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# fill given var-reference with text from entry subjectAltName |
||||||
|
# and set senitivity of togglebuttons |
||||||
|
# |
||||||
|
sub entry_to_var_san { |
||||||
|
my ($widget, $entry, $var, $box, $words, $radio1, $radio2, $radio3, $radio4) = @_; |
||||||
|
|
||||||
|
if(defined($words)) { |
||||||
|
if(my $tmp = $words->{$entry->get_text()}) { |
||||||
|
$$var = $tmp; |
||||||
|
} else { |
||||||
|
$$var = $entry->get_text(); |
||||||
|
} |
||||||
|
#print STDERR "DEBUG: var: $$var\n"; |
||||||
|
if($$var eq 'user') { |
||||||
|
#print STDERR "set sensitive(1)\n"; |
||||||
|
$radio1->set_sensitive(1) if(defined($radio1)); |
||||||
|
$radio2->set_sensitive(1) if(defined($radio2)); |
||||||
|
$radio3->set_sensitive(1) if(defined($radio3)); |
||||||
|
$radio4->set_sensitive(1) if(defined($radio4)); |
||||||
|
}else{ |
||||||
|
#print STDERR "DEBUG: set sensitive(0)\n"; |
||||||
|
#print STDERR "DEBUG: r1 $radio1 r2 $radio2 r3 $radio3 r4 $radio4\n"; |
||||||
|
$radio1->set_sensitive(0) if(defined($radio1)); |
||||||
|
$radio2->set_sensitive(0) if(defined($radio2)); |
||||||
|
$radio3->set_sensitive(0) if(defined($radio3)); |
||||||
|
$radio4->set_sensitive(0) if(defined($radio4)); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
$$var = $entry->get_text(); |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($box)) { |
||||||
|
$box->{'button_ok'}->set_sensitive(1); |
||||||
|
$box->{'button_apply'}->set_sensitive(1); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# fill given var-reference with text from entry subjectAltName |
||||||
|
# and set senitivity of togglebuttons |
||||||
|
# |
||||||
|
sub entry_to_var_key { |
||||||
|
my ($widget, $entry, $var, $box, $words, $radio1, $radio2, $radio3) = @_; |
||||||
|
|
||||||
|
if(defined($words)) { |
||||||
|
if(my $tmp = $words->{$entry->get_text()}) { |
||||||
|
$$var = $tmp; |
||||||
|
} else { |
||||||
|
$$var = $entry->get_text(); |
||||||
|
} |
||||||
|
if(($$var ne '') && ($$var ne 'none')) { |
||||||
|
$radio1->set_sensitive(1) if(defined($radio1)); |
||||||
|
$radio2->set_sensitive(1) if(defined($radio2)); |
||||||
|
$radio3->set_sensitive(1) if(defined($radio3)); |
||||||
|
}else{ |
||||||
|
$radio1->set_sensitive(0) if(defined($radio1)); |
||||||
|
$radio2->set_sensitive(0) if(defined($radio2)); |
||||||
|
$radio3->set_sensitive(0) if(defined($radio3)); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
$$var = $entry->get_text(); |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($box)) { |
||||||
|
$box->{'button_ok'}->set_sensitive(1); |
||||||
|
$box->{'button_apply'}->set_sensitive(1); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# fill given var-reference with value from togglebutton |
||||||
|
# |
||||||
|
sub toggle_to_var { |
||||||
|
my ($button, $var, $value, $outfileref, $formatref, $fileentry, $pass1, |
||||||
|
$pass2) = @_; |
||||||
|
|
||||||
|
$$var = $value; |
||||||
|
|
||||||
|
if(defined($outfileref) && defined($formatref)) { |
||||||
|
if($$outfileref =~ s/\.(pem|der|txt|p12|zip|tar)$//i) { |
||||||
|
$$outfileref .= "." . lc $$formatref; |
||||||
|
# something seem broken, need tmp var |
||||||
|
my $tmp = $$outfileref; |
||||||
|
$fileentry->set_text($tmp); |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($pass1) && defined($pass2)) { |
||||||
|
if($$formatref eq "PEM") { |
||||||
|
$pass1->set_sensitive(1); |
||||||
|
$pass2->set_sensitive(1); |
||||||
|
} elsif ($$formatref eq "DER") { |
||||||
|
$pass1->set_sensitive(0); |
||||||
|
$pass2->set_sensitive(0); |
||||||
|
} elsif ($$formatref eq "P12") { |
||||||
|
$pass1->set_sensitive(0); |
||||||
|
$pass2->set_sensitive(0); |
||||||
|
} elsif ($$formatref eq "ZIP") { |
||||||
|
$pass1->set_sensitive(0); |
||||||
|
$pass2->set_sensitive(0); |
||||||
|
} elsif ($$formatref eq "TAR") { |
||||||
|
$pass1->set_sensitive(0); |
||||||
|
$pass2->set_sensitive(0); |
||||||
|
} |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# fill given var-reference with value from togglebutton |
||||||
|
# |
||||||
|
sub toggle_to_var_pref { |
||||||
|
my ($button, $var, $value, $box) = @_; |
||||||
|
|
||||||
|
$$var = $value; |
||||||
|
|
||||||
|
if(defined($box) && defined($box->{'nb'}->get_current_page())) { |
||||||
|
$box->{'button_ok'}->set_sensitive(1); |
||||||
|
$box->{'button_apply'}->set_sensitive(1); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
1 |
||||||
|
|
@ -0,0 +1,479 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: HELPERS.pm,v 1.6 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package GUI::HELPERS; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
# |
||||||
|
# Error message box, kills application |
||||||
|
# |
||||||
|
sub print_error { |
||||||
|
my ($t, $ext) = @_; |
||||||
|
|
||||||
|
my ($box, $button, $dbutton, $expander, $text, $scrolled, $buffer); |
||||||
|
|
||||||
|
$button = Gtk2::Button->new_from_stock('gtk-ok'); |
||||||
|
$button->signal_connect('clicked', sub { HELPERS::exit_clean(1) }); |
||||||
|
$button->can_default(1); |
||||||
|
|
||||||
|
$box = Gtk2::MessageDialog->new( |
||||||
|
undef, [qw/destroy-with-parent modal/], 'error', 'none', $t); |
||||||
|
$box->set_default_size(600, 0); |
||||||
|
$box->set_resizable(1); |
||||||
|
|
||||||
|
if(defined($ext)) { |
||||||
|
$buffer = Gtk2::TextBuffer->new(); |
||||||
|
$buffer->set_text($ext); |
||||||
|
|
||||||
|
$text = Gtk2::TextView->new_with_buffer($buffer); |
||||||
|
$text->set_editable(0); |
||||||
|
$text->set_wrap_mode('word'); |
||||||
|
|
||||||
|
$scrolled = Gtk2::ScrolledWindow->new(undef, undef); |
||||||
|
$scrolled->set_policy('never', 'automatic'); |
||||||
|
$scrolled->set_shadow_type('etched-in'); |
||||||
|
$scrolled->add($text); |
||||||
|
|
||||||
|
$expander = Gtk2::Expander->new(_("Command Details")); |
||||||
|
$expander->add($scrolled); |
||||||
|
$box->vbox->add($expander); |
||||||
|
} |
||||||
|
|
||||||
|
$box->add_action_widget($button, 0); |
||||||
|
|
||||||
|
$box->show_all(); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# Warning message box |
||||||
|
# |
||||||
|
sub print_warning { |
||||||
|
my ($t, $ext) = @_; |
||||||
|
|
||||||
|
my ($box, $button, $dbutton, $expander, $text, $scrolled, $buffer); |
||||||
|
|
||||||
|
$button = Gtk2::Button->new_from_stock('gtk-ok'); |
||||||
|
$button->signal_connect('clicked', sub { $box->destroy() }); |
||||||
|
$button->can_default(1); |
||||||
|
|
||||||
|
$box = Gtk2::MessageDialog->new( |
||||||
|
undef, [qw/destroy-with-parent modal/], 'warning', 'none', $t); |
||||||
|
$box->set_default_size(600, 0); |
||||||
|
$box->set_resizable(1); |
||||||
|
|
||||||
|
if(defined($ext)) { |
||||||
|
$buffer = Gtk2::TextBuffer->new(); |
||||||
|
$buffer->set_text($ext); |
||||||
|
|
||||||
|
$text = Gtk2::TextView->new_with_buffer($buffer); |
||||||
|
$text->set_editable(0); |
||||||
|
$text->set_wrap_mode('word'); |
||||||
|
|
||||||
|
$scrolled = Gtk2::ScrolledWindow->new(undef, undef); |
||||||
|
$scrolled->set_policy('never', 'automatic'); |
||||||
|
$scrolled->set_shadow_type('etched-in'); |
||||||
|
$scrolled->add($text); |
||||||
|
|
||||||
|
$expander = Gtk2::Expander->new(_("Command Details")); |
||||||
|
$expander->add($scrolled); |
||||||
|
$box->vbox->add($expander); |
||||||
|
} |
||||||
|
$box->add_action_widget($button, 0); |
||||||
|
|
||||||
|
$box->show_all(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# Info message box |
||||||
|
# |
||||||
|
sub print_info { |
||||||
|
my ($t, $ext) = @_; |
||||||
|
|
||||||
|
my ($box, $button, $dbutton, $buffer, $text, $scrolled, $expander); |
||||||
|
|
||||||
|
$button = Gtk2::Button->new_from_stock('gtk-ok'); |
||||||
|
$button->signal_connect('clicked', sub { $box->destroy() }); |
||||||
|
$button->can_default(1); |
||||||
|
|
||||||
|
$box = Gtk2::MessageDialog->new( |
||||||
|
undef, [qw/destroy-with-parent modal/], 'info', 'none', $t); |
||||||
|
$box->set_default_size(600, 0); |
||||||
|
$box->set_resizable(1); |
||||||
|
|
||||||
|
if(defined($ext)) { |
||||||
|
$buffer = Gtk2::TextBuffer->new(); |
||||||
|
$buffer->set_text($ext); |
||||||
|
|
||||||
|
$text = Gtk2::TextView->new_with_buffer($buffer); |
||||||
|
$text->set_editable(0); |
||||||
|
$text->set_wrap_mode('word'); |
||||||
|
|
||||||
|
$scrolled = Gtk2::ScrolledWindow->new(undef, undef); |
||||||
|
$scrolled->set_policy('never', 'automatic'); |
||||||
|
$scrolled->set_shadow_type('etched-in'); |
||||||
|
$scrolled->add($text); |
||||||
|
|
||||||
|
$expander = Gtk2::Expander->new(_("Command Details")); |
||||||
|
$expander->add($scrolled); |
||||||
|
$box->vbox->add($expander); |
||||||
|
} |
||||||
|
$box->add_action_widget($button, 0); |
||||||
|
|
||||||
|
$box->show_all(); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# create standard dialog box |
||||||
|
# |
||||||
|
sub dialog_box { |
||||||
|
my ($title, $text, $button1, $button2) = @_; |
||||||
|
|
||||||
|
my $box = Gtk2::Dialog->new($title, undef, ["destroy-with-parent"]); |
||||||
|
|
||||||
|
$box->add_action_widget($button1, 0); |
||||||
|
|
||||||
|
if(defined($button2)) { |
||||||
|
$box->add_action_widget($button2, 0); |
||||||
|
$box->action_area->set_layout('spread'); |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($text)) { |
||||||
|
my $label = create_label($text, 'center', 0, 1); |
||||||
|
$box->vbox->pack_start($label, 0, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
$box->signal_connect(response => sub { $box->destroy }); |
||||||
|
|
||||||
|
return($box); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# create standard label |
||||||
|
# |
||||||
|
sub create_label { |
||||||
|
my ($text, $mode, $wrap, $bold) = @_; |
||||||
|
|
||||||
|
$text = "<b>$text</b>" if($bold); |
||||||
|
|
||||||
|
my $label = Gtk2::Label->new($text); |
||||||
|
|
||||||
|
$label->set_justify($mode); |
||||||
|
if($mode eq 'center') { |
||||||
|
$label->set_alignment(0.5, 0.5); |
||||||
|
}elsif($mode eq 'left') { |
||||||
|
$label->set_alignment(0, 0); |
||||||
|
}elsif($mode eq 'right') { |
||||||
|
$label->set_alignment(1, 1); |
||||||
|
} |
||||||
|
|
||||||
|
$label->set_line_wrap($wrap); |
||||||
|
|
||||||
|
$label->set_markup($text) if($bold); |
||||||
|
|
||||||
|
return($label); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# write two labels to table |
||||||
|
# |
||||||
|
sub label_to_table { |
||||||
|
my ($key, $val, $table, $row, $mode, $wrap, $bold) = @_; |
||||||
|
|
||||||
|
my ($label, $entry); |
||||||
|
|
||||||
|
$label = create_label($key, $mode, $wrap, $bold); |
||||||
|
$label->set_padding(20, 0); |
||||||
|
$table->attach_defaults($label, 0, 1, $row, $row+1); |
||||||
|
|
||||||
|
$label = create_label($val, $mode, $wrap, $bold); |
||||||
|
$label->set_padding(20, 0); |
||||||
|
$table->attach_defaults($label, 1, 2, $row, $row+1); |
||||||
|
|
||||||
|
$row++; |
||||||
|
$table->resize($row, 2); |
||||||
|
|
||||||
|
return($row); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# write label and entry to table |
||||||
|
# |
||||||
|
sub entry_to_table { |
||||||
|
my ($text, $var, $table, $row, $visibility, $box) = @_; |
||||||
|
|
||||||
|
my ($label, $entry); |
||||||
|
|
||||||
|
$label = create_label($text, 'left', 0, 0); |
||||||
|
$table->attach_defaults($label, 0, 1, $row, $row+1); |
||||||
|
|
||||||
|
$entry = Gtk2::Entry->new(); |
||||||
|
$entry->set_text($$var) if(defined($$var)); |
||||||
|
|
||||||
|
$table->attach_defaults($entry, 1, 2, $row, $row+1); |
||||||
|
$entry->signal_connect('changed' => |
||||||
|
sub {GUI::CALLBACK::entry_to_var($entry, $entry, $var, $box)} ); |
||||||
|
$entry->set_visibility($visibility); |
||||||
|
|
||||||
|
return($entry); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# sort the table by the clicked column |
||||||
|
# |
||||||
|
sub sort_clist { |
||||||
|
my ($clist, $col) = @_; |
||||||
|
|
||||||
|
$clist->set_sort_column($col); |
||||||
|
$clist->sort(); |
||||||
|
|
||||||
|
return(1); |
||||||
|
} |
||||||
|
|
||||||
|
sub create_activity_bar { |
||||||
|
my ($t) = @_; |
||||||
|
|
||||||
|
my($box, $bar); |
||||||
|
|
||||||
|
$box = Gtk2::MessageDialog->new( |
||||||
|
undef, [qw/destroy-with-parent modal/], 'info', 'none', $t); |
||||||
|
|
||||||
|
$bar = Gtk2::ProgressBar->new(); |
||||||
|
$bar->pulse(); |
||||||
|
$bar->set_pulse_step(0.1); |
||||||
|
|
||||||
|
$box->vbox->add($bar); |
||||||
|
|
||||||
|
$box->show_all(); |
||||||
|
|
||||||
|
return($box, $bar); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# set curser busy |
||||||
|
# |
||||||
|
sub set_cursor { |
||||||
|
my $main = shift; |
||||||
|
my $busy = shift; |
||||||
|
|
||||||
|
if($busy) { |
||||||
|
$main->{'rootwin'}->set_cursor($main->{'busycursor'}); |
||||||
|
} else { |
||||||
|
$main->{'rootwin'}->set_cursor($main->{'cursor'}); |
||||||
|
} |
||||||
|
while(Gtk2->events_pending) { |
||||||
|
Gtk2->main_iteration; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# call file chooser |
||||||
|
# |
||||||
|
sub browse_file { |
||||||
|
my($title, $entry, $mode) = @_; |
||||||
|
|
||||||
|
my($file_chooser, $filename, $filter); |
||||||
|
|
||||||
|
$file_chooser = Gtk2::FileChooserDialog->new ($title, undef, $mode, |
||||||
|
'gtk-cancel' => 'cancel', |
||||||
|
'gtk-ok' => 'ok'); |
||||||
|
|
||||||
|
$file_chooser->add_shortcut_folder ('/tmp'); |
||||||
|
|
||||||
|
if($mode eq 'open') { |
||||||
|
$filter = Gtk2::FileFilter->new(); |
||||||
|
$filter->set_name(_("Request Files (*.pem, *.der, *.req)")); |
||||||
|
$filter->add_pattern("*.pem"); |
||||||
|
$filter->add_pattern("*.der"); |
||||||
|
$filter->add_pattern("*.req"); |
||||||
|
$file_chooser->add_filter($filter); |
||||||
|
|
||||||
|
$filter = Gtk2::FileFilter->new(); |
||||||
|
$filter->set_name(_("All Files (*.*)")); |
||||||
|
$filter->add_pattern("*"); |
||||||
|
$file_chooser->add_filter($filter); |
||||||
|
} |
||||||
|
|
||||||
|
if ('ok' eq $file_chooser->run) { |
||||||
|
$filename = $file_chooser->get_filename(); |
||||||
|
$entry->set_text($filename); |
||||||
|
} |
||||||
|
|
||||||
|
$file_chooser->destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# set text in statusbar |
||||||
|
# |
||||||
|
sub set_status { |
||||||
|
my ($main, $t) = @_; |
||||||
|
|
||||||
|
$main->{'bar'}->pop($main->{'lastid'}) if(defined($main->{'lastid'})); |
||||||
|
$main->{'lastid'} = $main->{'bar'}->get_context_id('gargs'); |
||||||
|
$main->{'bar'}->push($main->{'lastid'}, $t); |
||||||
|
} |
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
__END__ |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
GUI::HELPERS - helper functions for TinyCA, doing small jobs related to the |
||||||
|
GUI |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use GUI::HELPERS; |
||||||
|
|
||||||
|
GUI::HELPERS::print_info($text, $ext); |
||||||
|
GUI::HELPERS::print_warning($text, $ext); |
||||||
|
GUI::HELPERS::print_error($text, $ext); |
||||||
|
GUI::HELPERS::sort_clist($clist, $col); |
||||||
|
GUI::HELPERS::set_cursor($main, $busy); |
||||||
|
GUI::HELPERS::browse_file($main, $entry, $mode); |
||||||
|
GUI::HELPERS::set_status($main, $text); |
||||||
|
|
||||||
|
$box = GUI::HELPERS::dialog_box( |
||||||
|
$title, $text, $button1, $button2); |
||||||
|
$label = GUI::HELPERS::create_label( |
||||||
|
$text, $mode, $wrap, $bold); |
||||||
|
$row = GUI::HELPERS::label_to_table( |
||||||
|
$key, $val, $table, $row, $mode, $wrap, $bold); |
||||||
|
$entry = GUI::HELPERS::entry_to_table( |
||||||
|
$text, $var, $table, $row, $visibility, $box); |
||||||
|
|
||||||
|
=head1 DESCRIPTION |
||||||
|
|
||||||
|
GUI::HELPERS.pm is a library, containing some useful functions used by other |
||||||
|
TinyCA2 modules. All functions are related to the GUI. |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::print_info($text, $ext); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
creates an Gtk2::MessageDialog of the type info. The string given in $text is |
||||||
|
shown as message, the (multiline) string $ext is available through the |
||||||
|
"Details" Button. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::print_warning($text, $ext); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
is identically with GUI::HELPERS::print_warning(), only the |
||||||
|
Gtk2::MessageDialog is of type warning. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::print_error($text, $ext); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
is identically with GUI::HELPERS::print_info(), only the Gtk2::MessageDialogog |
||||||
|
is of type error and the program will shut down after closing the message. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::sort_clist($clist, $col); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
sorts the clist with the values from the given column $col. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::dialog_box($title, $text, $button1, $button2); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns the reference to a new window of type Gtk2::Dialog. $title and |
||||||
|
$button1 must be given. $text and $button2 are optional arguments and can be |
||||||
|
undef. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::create_label($text, $mode, $wrap, $bold); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns the reference to a new Gtk2::Label. $mode can be "center", "left" or |
||||||
|
"right". $wrap and $bold are boolean values. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::label_to_table($key, $val, $table, $row, $mode, $wrap, $bold); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
adds a new row to $table. The new row is appended at $row and has two columns: |
||||||
|
the first will contain a label with the content of string $k, the second the |
||||||
|
content of string $v. $mode, $wrap, $bold are the arguments for |
||||||
|
GUI::HELPERS::create_label(), mentioned above. |
||||||
|
The function returns the number of the next free row in the table. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::entry_to_table($text, $var, $table, $row, $visibility, $box); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
adds a new row to $table. The new row is appended at $row and has two columns: |
||||||
|
the first will contain a label with the content of the string $text, the |
||||||
|
second one will contain a textentry Gtk2::Entry, associated with the variable |
||||||
|
$var. $visibility controls, if the entered text will be displayed or not |
||||||
|
(passwords). |
||||||
|
The function returns the reference to the new created entry. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::set_cursor($main, $busy); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
sets the actual cursor to busy or back to normal. The value of $busy is |
||||||
|
boolean. |
||||||
|
This functions returns nothing; |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::browse_file($main, $entry, $mode); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
opens a FileChooser dialog to select files or directories. $entry is a |
||||||
|
reference to the variable, where the selected path shall be stored. If $mode |
||||||
|
is set to "open", then only files with appropriate suffixes are displyed. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 GUI::HELPERS::set_status($main, $text); |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
sets the text in $text to the statusbar at the bottom of the window. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=cut |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,112 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: WORDS.pm,v 1.2 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package GUI::WORDS; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $that = shift; |
||||||
|
|
||||||
|
my $self = { |
||||||
|
'none' => _("Not set"), |
||||||
|
'user' => _("Ask User"), |
||||||
|
'critical' => _("critical"), |
||||||
|
'noncritical' => _("not critical"), |
||||||
|
'emailcopy' => _("Copy Email"), |
||||||
|
'raw' => _("raw"), |
||||||
|
'dns' => _("DNS Name"), |
||||||
|
'ip' => _("IP Address"), |
||||||
|
'mail' => _("Email"), |
||||||
|
'server' => _("SSL Server"), |
||||||
|
'server, client' => _("SSL Server, SSL Client"), |
||||||
|
'key' => _("Key Encipherment"), |
||||||
|
'sig' => _("Digital Signature"), |
||||||
|
'keysig' => _("Key Encipherment, Digital Signature"), |
||||||
|
'objsign' => _("Object Signing"), |
||||||
|
'client, objsign' => _("SSL Client, Object Signing"), |
||||||
|
'client, email' => _("SSL Client, Email(S/MIME)"), |
||||||
|
'client' => _("SSL Client"), |
||||||
|
'email' => _("Email(S/MIME)"), |
||||||
|
'client, email, objsign'=> _("SSL Client, Email, Object Signing"), |
||||||
|
'objCA' => _("Object Signing CA"), |
||||||
|
'emailCA' => _("S/MIME CA"), |
||||||
|
'sslCA' => _("SSL CA"), |
||||||
|
'sslCA, emailCA' => _("SSL CA, S/MIME CA"), |
||||||
|
'sslCA, objCA' => _("SSL CA, Object Signing CA"), |
||||||
|
'emailCA, objCA' => _("S/MIME CA, Object Signing CA"), |
||||||
|
'sslCA, emailCA, objCA' => _("SSL CA, S/MIME CA, Object Signing CA"), |
||||||
|
'keyCertSign' => _("Certificate Signing"), |
||||||
|
'cRLSign' => _("CRL Signing"), |
||||||
|
'keyCertSign, cRLSign' => _("Certificate Signing, CRL Signing"), |
||||||
|
'CN' => _("Common Name"), |
||||||
|
'EMAIL' => _("eMail Address"), |
||||||
|
'O' => _("Organization"), |
||||||
|
'OU' => _("Organizational Unit"), |
||||||
|
'L' => _("Location"), |
||||||
|
'ST' => _("State"), |
||||||
|
'C' => _("Country"), |
||||||
|
'NOTBEFORE' => _("Creation Date"), |
||||||
|
'NOTAFTER' => _("Expiration Date"), |
||||||
|
'KEYSIZE' => _("Keylength"), |
||||||
|
'PK_ALGORITHM' => _("Public Key Algorithm"), |
||||||
|
'SIG_ALGORITHM' => _("Signature Algorithm"), |
||||||
|
'TYPE' => _("Type"), |
||||||
|
'SERIAL' => _("Serial"), |
||||||
|
'STATUS' => _("Status"), |
||||||
|
'FINGERPRINTMD5' => _("Fingerprint (MD5)"), |
||||||
|
'FINGERPRINTSHA1' => _("Fingerprint (SHA1)"), |
||||||
|
_("Not set") => 'none', |
||||||
|
_("Ask User") => 'user', |
||||||
|
_("critical") => 'critical', |
||||||
|
_("not critical") => 'noncritical', |
||||||
|
_("Copy Email") => 'emailcopy', |
||||||
|
_("raw") => 'raw', |
||||||
|
_("DNS Name") => 'dns', |
||||||
|
_("Email") => 'email', |
||||||
|
_("IP Address") => 'ip', |
||||||
|
_("SSL Server") => 'server', |
||||||
|
_("SSL Server, SSL Client") => 'server, client', |
||||||
|
_("Key Encipherment") => 'key', |
||||||
|
_("Digital Signature") => 'sig', |
||||||
|
_("Key Encipherment, Digital Signature") => 'keysig', |
||||||
|
_("Object Signing") => 'objsign', |
||||||
|
_("Email(S/MIME)") => 'email', |
||||||
|
_("SSL Client, Email(S/MIME)") => 'client, email', |
||||||
|
_("SSL Client") => 'client', |
||||||
|
_("SSL Client, Object Signing") => 'client, objsign', |
||||||
|
_("SSL Client, Email, Object Signing") => 'client, email, objsign', |
||||||
|
_("Object Signing CA") => 'objCA', |
||||||
|
_("S/MIME CA") => 'emailCA', |
||||||
|
_("SSL CA") => 'sslCA', |
||||||
|
_("SSL CA, S/MIME CA") => 'sslCA, emailCA', |
||||||
|
_("SSL CA, Object Signing CA") => 'sslCA, objCA', |
||||||
|
_("S/MIME CA, Object Signing CA") => 'emailCA, objCA', |
||||||
|
_("SSL CA, S/MIME CA, Object Signing CA")=> 'sslCA, emailCA, objCA', |
||||||
|
_("Certificate Signing") => 'keyCertSign', |
||||||
|
_("CRL Signing") => 'cRLSign', |
||||||
|
_("Certificate Signing, CRL Signing") => 'keyCertSign, cRLSign' |
||||||
|
}; |
||||||
|
|
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
|
||||||
|
$self; |
||||||
|
} |
||||||
|
|
||||||
|
1 |
@ -0,0 +1,879 @@ |
|||||||
|
# Copyright (c) Olaf Gellert <og@pre-secure.de> and |
||||||
|
# Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: X509_browser.pm,v 1.6 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package GUI::X509_browser; |
||||||
|
|
||||||
|
use HELPERS; |
||||||
|
use GUI::HELPERS; |
||||||
|
use GUI::X509_infobox; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
my $tmpdefault="/tmp"; |
||||||
|
|
||||||
|
my $version = "0.1"; |
||||||
|
my $true = 1; |
||||||
|
my $false = undef; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $that = shift; |
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
$self->{'main'} = shift; |
||||||
|
my $mode = shift; |
||||||
|
|
||||||
|
my ($font, $fontfix); |
||||||
|
|
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
|
||||||
|
if ((defined $mode) && |
||||||
|
(($mode eq 'cert') || ($mode eq 'req') || ($mode eq 'key'))) { |
||||||
|
$self->{'mode'} = $mode; |
||||||
|
} else { |
||||||
|
printf STDERR "No mode specified for X509browser\n"; |
||||||
|
return undef; |
||||||
|
} |
||||||
|
|
||||||
|
# initialize fonts and styles |
||||||
|
$font = Gtk2::Pango::FontDescription->from_string( |
||||||
|
"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"); |
||||||
|
if(defined($font)) { |
||||||
|
$self->{'stylebold'} = Gtk2::Style->new(); |
||||||
|
$self->{'stylebold'}->font_desc->from_string( |
||||||
|
"-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*"); |
||||||
|
} else { |
||||||
|
$self->{'stylebold'} = undef; |
||||||
|
} |
||||||
|
|
||||||
|
$fontfix = Gtk2::Pango::FontDescription->from_string( |
||||||
|
"-adobe-courier-medium-r-normal--*-100-*-*-*-*-*-*"); |
||||||
|
if(defined($fontfix)) { |
||||||
|
$self->{'stylefix'} = Gtk2::Style->new(); |
||||||
|
$self->{'stylefix'}->font_desc->from_string( |
||||||
|
"-adobe-courier-medium-r-normal--*-100-*-*-*-*-*-*"); |
||||||
|
} else { |
||||||
|
$self->{'stylefix'} = undef; |
||||||
|
} |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
|
||||||
|
$self; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
# sub create_window { |
||||||
|
# my ($self, $title, $ok_text, $cancel_text, |
||||||
|
# $ok_function, $cancel_function) = @_; |
||||||
|
# |
||||||
|
# my ($button_ok, $button_cancel); |
||||||
|
# |
||||||
|
# if ( $self->{'dialog_shown'} == $true ) { |
||||||
|
# return(undef); |
||||||
|
# } |
||||||
|
# |
||||||
|
# # check arguments |
||||||
|
# if ($title eq undef) { |
||||||
|
# $title = "CA browser, V$version"; |
||||||
|
# } |
||||||
|
# |
||||||
|
# if (not defined($ok_text)) { |
||||||
|
# $ok_text = _("OK"); |
||||||
|
# } |
||||||
|
# if (not defined($cancel_text)) { |
||||||
|
# $cancel_text = _("Cancel"); |
||||||
|
# } |
||||||
|
# |
||||||
|
# # initialize main window |
||||||
|
# $self->{'window'} = new Gtk::Dialog(); |
||||||
|
# |
||||||
|
# # $self->{'window'}->set_policy($false,$false,$true); |
||||||
|
# |
||||||
|
# # store pointer to vbox as "browser widget" |
||||||
|
# $self->{'browser'}=$self->{'window'}->vbox; |
||||||
|
# |
||||||
|
# if (defined $ok_function) { |
||||||
|
# # todo: we should check if this is a function reference |
||||||
|
# $self->{'User_OK_function'} = $ok_function; |
||||||
|
# } |
||||||
|
# $self->{'OK_function'} = sub { $self->ok_function(); }; |
||||||
|
# |
||||||
|
# if (defined $cancel_function) { |
||||||
|
# # todo: we should check if this is a function reference |
||||||
|
# $self->{'User_CANCEL_function'} = $cancel_function; |
||||||
|
# } |
||||||
|
# $self->{'CANCEL_function'} = sub { $self->cancel_function(); }; |
||||||
|
# |
||||||
|
# |
||||||
|
# |
||||||
|
# $button_ok = new Gtk::Button( "$ok_text" ); |
||||||
|
# $button_ok->signal_connect( "clicked", $self->{'OK_function'}); |
||||||
|
# $self->{'window'}->action_area->pack_start( $button_ok, $true, $true, 0 ); |
||||||
|
# |
||||||
|
# $button_cancel = new Gtk::Button( "$cancel_text" ); |
||||||
|
# $button_cancel->signal_connect('clicked', $self->{'CANCEL_function'}); |
||||||
|
# $self->{'window'}->action_area->pack_start( $button_cancel, $true, $true, 0 ); |
||||||
|
# |
||||||
|
# $self->{'window'}->set_title( "$title" ); |
||||||
|
# |
||||||
|
# $self->{'window'}->show_all(); |
||||||
|
# |
||||||
|
# } |
||||||
|
|
||||||
|
sub set_window { |
||||||
|
my $self = shift; |
||||||
|
my $widget = shift; |
||||||
|
|
||||||
|
if ( (not defined $self->{'browser'}) || ( $self->{'browser'} == undef )) { |
||||||
|
$self->{'browser'}=$widget; |
||||||
|
} else { |
||||||
|
# browser widget already exists |
||||||
|
return $false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sub add_list { |
||||||
|
my ($self, $actca, $directory, $crlfile, $indexfile) = @_; |
||||||
|
|
||||||
|
my ($x509listwin, @titles, @certtitles, @reqtitles, @keytitles, $column, |
||||||
|
$color, $text, $iter, $renderer); |
||||||
|
|
||||||
|
# printf STDERR "AddList: Self: $self, Dir $directory, CRL $crlfile, Index: $indexfile\n"; |
||||||
|
|
||||||
|
@reqtitles = (_("Common Name"), |
||||||
|
_("eMail Address"), |
||||||
|
_("Organizational Unit"), |
||||||
|
_("Organization"), |
||||||
|
_("Location"), |
||||||
|
_("State"), |
||||||
|
_("Country")); |
||||||
|
|
||||||
|
@certtitles = (_("Common Name"), |
||||||
|
_("eMail Address"), |
||||||
|
_("Organizational Unit"), |
||||||
|
_("Organization"), |
||||||
|
_("Location"), |
||||||
|
_("State"), |
||||||
|
_("Country"), |
||||||
|
_("Status")); |
||||||
|
|
||||||
|
@keytitles = (_("Common Name"), |
||||||
|
_("eMail Address"), |
||||||
|
_("Organizational Unit"), |
||||||
|
_("Organization"), |
||||||
|
_("Location"), |
||||||
|
_("State"), |
||||||
|
_("Country"), |
||||||
|
_("Type")); |
||||||
|
|
||||||
|
$self->{'actca'} = $actca; |
||||||
|
$self->{'actdir'} = $directory; |
||||||
|
$self->{'actcrl'} = $crlfile; |
||||||
|
$self->{'actindex'} = $indexfile; |
||||||
|
|
||||||
|
if(defined($self->{'x509box'})) { |
||||||
|
$self->{'browser'}->remove($self->{'x509box'}); |
||||||
|
$self->{'x509box'}->destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
$self->{'x509box'} = Gtk2::VBox->new(0, 0); |
||||||
|
|
||||||
|
# pane for list (top) and cert infos (bottom) |
||||||
|
$self->{'x509pane'} = Gtk2::VPaned->new(); |
||||||
|
$self->{'x509pane'}->set_position(250); |
||||||
|
$self->{'x509box'}->add($self->{'x509pane'}); |
||||||
|
|
||||||
|
$self->{'browser'}->pack_start($self->{'x509box'}, 1, 1, 0); |
||||||
|
|
||||||
|
# now the list |
||||||
|
$x509listwin = Gtk2::ScrolledWindow->new(undef, undef); |
||||||
|
$x509listwin->set_policy('automatic', 'automatic'); |
||||||
|
$x509listwin->set_shadow_type('etched-in'); |
||||||
|
$self->{'x509pane'}->pack1($x509listwin, 1, 1); |
||||||
|
|
||||||
|
# shall we display certificates, requests or keys? |
||||||
|
if ((defined $self->{'mode'}) && ($self->{'mode'} eq "cert")) { |
||||||
|
|
||||||
|
$self->{'x509store'} = Gtk2::ListStore->new( |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::Int'); |
||||||
|
|
||||||
|
@titles = @certtitles; |
||||||
|
|
||||||
|
} elsif ((defined $self->{'mode'}) && ($self->{'mode'} eq "req")) { |
||||||
|
|
||||||
|
$self->{'x509store'} = Gtk2::ListStore->new( |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::Int'); |
||||||
|
|
||||||
|
@titles = @reqtitles; |
||||||
|
|
||||||
|
} elsif ((defined $self->{'mode'}) && ($self->{'mode'} eq "key")) { |
||||||
|
|
||||||
|
$self->{'x509store'} = Gtk2::ListStore->new( |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::String', |
||||||
|
'Glib::Int'); |
||||||
|
|
||||||
|
@titles = @keytitles; |
||||||
|
|
||||||
|
} else { |
||||||
|
# undefined mode |
||||||
|
return undef; |
||||||
|
} |
||||||
|
|
||||||
|
$self->{'x509store'}->set_sort_column_id(0, 'ascending'); |
||||||
|
|
||||||
|
$self->{'x509clist'} = Gtk2::TreeView->new_with_model($self->{'x509store'}); |
||||||
|
$self->{'x509clist'}->get_selection->set_mode ('single'); |
||||||
|
|
||||||
|
for(my $i = 0; $titles[$i]; $i++) { |
||||||
|
$renderer = Gtk2::CellRendererText->new(); |
||||||
|
$column = Gtk2::TreeViewColumn->new_with_attributes( |
||||||
|
$titles[$i], $renderer, 'text' => $i); |
||||||
|
$column->set_sort_column_id($i); |
||||||
|
$column->set_resizable(1); |
||||||
|
if (($i == 7) && ($self->{'mode'} eq 'cert')) { |
||||||
|
$column->set_cell_data_func ($renderer, sub { |
||||||
|
my ($column, $cell, $model, $iter) = @_; |
||||||
|
$text = $model->get($iter, 7); |
||||||
|
$color = $text eq _("VALID")?'green':'red'; |
||||||
|
$cell->set (text => $text, foreground => $color); |
||||||
|
}); |
||||||
|
} |
||||||
|
$self->{'x509clist'}->append_column($column); |
||||||
|
} |
||||||
|
|
||||||
|
if ((defined $self->{'mode'}) && ($self->{'mode'} eq 'cert')) { |
||||||
|
$self->{'x509clist'}->get_selection->signal_connect('changed' => |
||||||
|
sub { _fill_info($self, 'cert') }); |
||||||
|
} elsif ((defined $self->{'mode'}) && ($self->{'mode'} eq 'req')) { |
||||||
|
$self->{'x509clist'}->get_selection->signal_connect('changed' => |
||||||
|
sub { _fill_info($self, 'req') }); |
||||||
|
} |
||||||
|
|
||||||
|
$x509listwin->add($self->{'x509clist'}); |
||||||
|
|
||||||
|
update($self, $directory, $crlfile, $indexfile, $true); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
sub update { |
||||||
|
my ($self, $directory, $crlfile, $indexfile, $force) = @_; |
||||||
|
|
||||||
|
$self->{'actdir'} = $directory; |
||||||
|
$self->{'actcrl'} = $crlfile; |
||||||
|
$self->{'actindex'} = $indexfile; |
||||||
|
|
||||||
|
# print STDERR "DEBUG: set new dir: $self->{'actdir'}\n"; |
||||||
|
|
||||||
|
if ($self->{'mode'} eq "cert") { |
||||||
|
update_cert($self, $directory, $crlfile, $indexfile, $force); |
||||||
|
} elsif ($self->{'mode'} eq "req") { |
||||||
|
update_req($self, $directory, $crlfile, $indexfile, $force); |
||||||
|
} elsif ($self->{'mode'} eq "key") { |
||||||
|
update_key($self, $directory, $crlfile, $indexfile, $force); |
||||||
|
} else { |
||||||
|
return undef; |
||||||
|
} |
||||||
|
|
||||||
|
if ((defined $self->{'infowin'}) && ($self->{'infowin'} ne "")) { |
||||||
|
update_info($self); |
||||||
|
} |
||||||
|
|
||||||
|
$self->{'browser'}->show_all(); |
||||||
|
|
||||||
|
return($true); |
||||||
|
} |
||||||
|
|
||||||
|
sub update_req { |
||||||
|
my ($self, $directory, $crlfile, $indexfile, $force) = @_; |
||||||
|
|
||||||
|
my ($ind, $name, $state, @line, $iter); |
||||||
|
|
||||||
|
$self->{'main'}->{'REQ'}->read_reqlist( |
||||||
|
$directory, $crlfile, $indexfile, $force, $self->{'main'}); |
||||||
|
|
||||||
|
$self->{'x509store'}->clear(); |
||||||
|
|
||||||
|
$ind = 0; |
||||||
|
foreach my $n (@{$self->{'main'}->{'REQ'}->{'reqlist'}}) { |
||||||
|
($name, $state) = split(/\%/, $n); |
||||||
|
@line = split(/\:/, $name); |
||||||
|
$iter = $self->{'x509store'}->append(); |
||||||
|
$self->{'x509store'}->set($iter, |
||||||
|
0 => $line[0], |
||||||
|
1 => $line[1], |
||||||
|
2 => $line[2], |
||||||
|
3 => $line[3], |
||||||
|
4 => $line[4], |
||||||
|
5 => $line[5], |
||||||
|
6 => $line[6], |
||||||
|
7 => $ind); |
||||||
|
$ind++; |
||||||
|
} |
||||||
|
# now select the first row to display certificate informations |
||||||
|
$self->{'x509clist'}->get_selection->select_path( |
||||||
|
Gtk2::TreePath->new_first()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
sub update_cert { |
||||||
|
my ($self, $directory, $crlfile, $indexfile, $force) = @_; |
||||||
|
|
||||||
|
my ($ind, $name, $state, @line, $iter); |
||||||
|
|
||||||
|
$self->{'main'}->{'CERT'}->read_certlist( |
||||||
|
$directory, $crlfile, $indexfile, $force, $self->{'main'}); |
||||||
|
|
||||||
|
$self->{'x509store'}->clear(); |
||||||
|
|
||||||
|
$ind = 0; |
||||||
|
foreach my $n (@{$self->{'main'}->{'CERT'}->{'certlist'}}) { |
||||||
|
($name, $state) = split(/\%/, $n); |
||||||
|
@line = split(/\:/, $name); |
||||||
|
$iter = $self->{'x509store'}->append(); |
||||||
|
$self->{'x509store'}->set($iter, |
||||||
|
0 => $line[0], |
||||||
|
1 => $line[1], |
||||||
|
2 => $line[2], |
||||||
|
3 => $line[3], |
||||||
|
4 => $line[4], |
||||||
|
5 => $line[5], |
||||||
|
6 => $line[6], |
||||||
|
7 => $state, |
||||||
|
8 => $ind); |
||||||
|
|
||||||
|
|
||||||
|
# $self->{'x509clist'}->set_text($row, 7, $state); |
||||||
|
# if($state eq _("VALID")) { |
||||||
|
# $self->{'x509clist'}->set_cell_style($row, 7, $self->{'stylegreen'}); |
||||||
|
# } else { |
||||||
|
# $self->{'x509clist'}->set_cell_style($row, 7, $self->{'stylered'}); |
||||||
|
# } |
||||||
|
# $self->{'x509clist'}->set_text($row, 8, $ind); |
||||||
|
$ind++; |
||||||
|
} |
||||||
|
# now select the first row to display certificate informations |
||||||
|
$self->{'x509clist'}->get_selection->select_path( |
||||||
|
Gtk2::TreePath->new_first()); |
||||||
|
} |
||||||
|
|
||||||
|
sub update_key { |
||||||
|
my ($self, $directory, $crlfile, $indexfile, $force) = @_; |
||||||
|
|
||||||
|
my ($ind, $name, @line, $iter, $state); |
||||||
|
|
||||||
|
$self->{'main'}->{'KEY'}->read_keylist($self->{'main'}); |
||||||
|
|
||||||
|
$self->{'x509store'}->clear(); |
||||||
|
|
||||||
|
$ind = 0; |
||||||
|
foreach my $n (@{$self->{'main'}->{'KEY'}->{'keylist'}}) { |
||||||
|
($name, $state) = split(/\%/, $n); |
||||||
|
@line = split(/\:/, $name); |
||||||
|
$iter = $self->{'x509store'}->append(); |
||||||
|
$self->{'x509store'}->set($iter, |
||||||
|
0 => $line[0], |
||||||
|
1 => $line[1], |
||||||
|
2 => $line[2], |
||||||
|
3 => $line[3], |
||||||
|
4 => $line[4], |
||||||
|
5 => $line[5], |
||||||
|
6 => $line[6], |
||||||
|
7 => $state, |
||||||
|
8 => $ind); |
||||||
|
|
||||||
|
|
||||||
|
# $self->{'x509clist'}->set_text($row, 7, $state); |
||||||
|
# if($state eq _("VALID")) { |
||||||
|
# $self->{'x509clist'}->set_cell_style($row, 7, $self->{'stylegreen'}); |
||||||
|
# } else { |
||||||
|
# $self->{'x509clist'}->set_cell_style($row, 7, $self->{'stylered'}); |
||||||
|
# } |
||||||
|
# $self->{'x509clist'}->set_text($row, 8, $ind); |
||||||
|
$ind++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sub update_info { |
||||||
|
my ($self)=@_; |
||||||
|
|
||||||
|
my ($title, $parsed, $dn); |
||||||
|
|
||||||
|
$dn = selection_dn($self); |
||||||
|
|
||||||
|
if (defined $dn) { |
||||||
|
$dn = HELPERS::enc_base64($dn); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'cert') { |
||||||
|
$parsed = $self->{'main'}->{'CERT'}->parse_cert($self->{'main'}, |
||||||
|
$dn, $false); |
||||||
|
$title = _("Certificate Information"); |
||||||
|
} else { |
||||||
|
$parsed = $self->{'main'}->{'REQ'}->parse_req($self->{'main'}, $dn, |
||||||
|
$false); |
||||||
|
$title = _("Request Information"); |
||||||
|
} |
||||||
|
|
||||||
|
defined($parsed) || |
||||||
|
GUI::HELPERS::print_error(_("Can't read file")); |
||||||
|
|
||||||
|
if(not defined($self->{'infobox'})) { |
||||||
|
$self->{'infobox'} = Gtk2::VBox->new(); |
||||||
|
} |
||||||
|
|
||||||
|
# printf STDERR "DEBUG: Infowin: $self->{'infowin'}, infobox: $self->{'infobox'}\n"; |
||||||
|
$self->{'infowin'}->display($self->{'infobox'}, $parsed, |
||||||
|
$self->{'mode'}, $title); |
||||||
|
|
||||||
|
} else { |
||||||
|
# nothing selected |
||||||
|
$self->{'infowin'}->hide(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# add infobox to the browser window |
||||||
|
# |
||||||
|
sub add_info { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($row, $index, $parsed, $title, $status, $list, $dn); |
||||||
|
|
||||||
|
if ((defined $self->{'infowin'}) && ($self->{'infowin'} ne "")) { |
||||||
|
$self->{'infowin'}->hide(); |
||||||
|
} else { |
||||||
|
$self->{'infowin'} = GUI::X509_infobox->new(); |
||||||
|
} |
||||||
|
|
||||||
|
# printf STDERR "Infowin: $self->{'infowin'}\n"; |
||||||
|
# printf STDERR "x509clist: $self->{'x509clist'}\n"; |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
if(defined($row)) { |
||||||
|
if ($self->{'mode'} eq 'cert') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'CERT'}->{'certlist'}; |
||||||
|
} else { |
||||||
|
$index = ($self->{'x509store'}->get($row))[7]; |
||||||
|
$list = $self->{'main'}->{'REQ'}->{'reqlist'}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (defined $index) { |
||||||
|
($dn, $status) = split(/\%/, $list->[$index]); |
||||||
|
$dn = HELPERS::enc_base64($dn); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'cert') { |
||||||
|
$parsed = $self->{'main'}->{'CERT'}->parse_cert($self->{'main'}, $dn, |
||||||
|
$false); |
||||||
|
$title="Certificate Information"; |
||||||
|
} else { |
||||||
|
$parsed = $self->{'main'}->{'REQ'}->parse_req($self->{'main'}, $dn, |
||||||
|
$false); |
||||||
|
$title="Request Information"; |
||||||
|
} |
||||||
|
|
||||||
|
defined($parsed) || GUI::HELPERS::print_error(_("Can't read file")); |
||||||
|
|
||||||
|
# printf STDERR "Infowin: $self->{'infowin'}\n"; |
||||||
|
$self->{'infobox'} = Gtk2::VBox->new(); |
||||||
|
$self->{'x509pane'}->pack2($self->{'infobox'}, 1, 1); |
||||||
|
$self->{'infowin'}->display($self->{'infobox'}, $parsed, $self->{'mode'}, |
||||||
|
$title); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
sub hide { |
||||||
|
my ($self) = @_; |
||||||
|
|
||||||
|
$self->{'window'}->hide(); |
||||||
|
$self->{'dialog_shown'} = $false; |
||||||
|
} |
||||||
|
|
||||||
|
sub destroy { |
||||||
|
my ($self) = @_; |
||||||
|
|
||||||
|
$self->{'window'}->destroy(); |
||||||
|
$self->{'dialog_shown'} = $false; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# signal handler for selected list items |
||||||
|
# (updates the X509_infobox window) |
||||||
|
# XXX why is that function needed?? |
||||||
|
# |
||||||
|
sub _fill_info { |
||||||
|
my ($self) = @_; |
||||||
|
|
||||||
|
# print STDERR "DEBUG: fill_info: @_\n"; |
||||||
|
update_info($self) if (defined $self->{'infowin'}); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_fname { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $dn, $status, $filename, $list); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'req') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[7]; |
||||||
|
$list = $self->{'main'}->{'REQ'}->{'reqlist'}; |
||||||
|
} elsif ($self->{'mode'} eq 'cert') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'CERT'}->{'certlist'}; |
||||||
|
} elsif ($self->{'mode'} eq 'key') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'KEY'}->{'certlist'}; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_fname():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
if (defined $index) { |
||||||
|
($dn, $status) = split(/\%/, $list->[$index]); |
||||||
|
$filename= HELPERS::enc_base64($dn); |
||||||
|
$filename=$self->{'actdir'}."/$filename".".pem"; |
||||||
|
} else { |
||||||
|
$filename = undef; |
||||||
|
} |
||||||
|
|
||||||
|
return($filename); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_dn { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $dn, $status, $list); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'req') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[7]; |
||||||
|
$list = $self->{'main'}->{'REQ'}->{'reqlist'}; |
||||||
|
} elsif ($self->{'mode'} eq 'cert') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'CERT'}->{'certlist'}; |
||||||
|
} elsif ($self->{'mode'} eq 'key') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'KEY'}->{'keylist'}; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_dn():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
if (defined $index) { |
||||||
|
($dn, $status) = split(/\%/, $list->[$index]); |
||||||
|
} else { |
||||||
|
$dn = undef; |
||||||
|
} |
||||||
|
|
||||||
|
return($dn); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_cadir { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my $dir; |
||||||
|
|
||||||
|
$dir = $self->{'actdir'}; |
||||||
|
# cut off the last directory name to provide the ca-directory |
||||||
|
$dir =~ s/\/certs|\/req|\/keys$//; |
||||||
|
return($dir); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
sub selection_caname { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $caname); |
||||||
|
|
||||||
|
$caname = $self->{'actca'}; |
||||||
|
return($caname); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_cn { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $cn); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if (($self->{'mode'} eq 'req') || |
||||||
|
($self->{'mode'} eq 'cert')|| |
||||||
|
($self->{'mode'} eq 'key')) { |
||||||
|
$cn = ($self->{'x509store'}->get($row))[0]; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_cn():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
return($cn); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_email { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $email); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if (($self->{'mode'} eq 'req') || |
||||||
|
($self->{'mode'} eq 'cert') || |
||||||
|
($self->{'mode'} eq 'key')) { |
||||||
|
$email = ($self->{'x509store'}->get($row))[1]; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_cn():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
return($email); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_status { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $dn, $status, $list); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'cert') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'CERT'}->{'certlist'}; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_status():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
if (defined $index) { |
||||||
|
($dn, $status) = split(/\%/, $list->[$index]); |
||||||
|
} else { |
||||||
|
$status = undef; |
||||||
|
} |
||||||
|
|
||||||
|
return($status); |
||||||
|
} |
||||||
|
|
||||||
|
sub selection_type { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
my ($selected, $row, $index, $dn, $type, $list); |
||||||
|
|
||||||
|
$row = $self->{'x509clist'}->get_selection->get_selected(); |
||||||
|
|
||||||
|
return undef if (not defined $row); |
||||||
|
|
||||||
|
if ($self->{'mode'} eq 'key') { |
||||||
|
$index = ($self->{'x509store'}->get($row))[8]; |
||||||
|
$list = $self->{'main'}->{'KEY'}->{'keylist'}; |
||||||
|
} else { |
||||||
|
GUI::HELPERS::print_error( |
||||||
|
_("Invalid browser mode for selection_type():"." " |
||||||
|
.$self->{'mode'})); |
||||||
|
} |
||||||
|
|
||||||
|
if (defined $index) { |
||||||
|
($dn, $type) = split(/\%/, $list->[$index]); |
||||||
|
} else { |
||||||
|
$type = undef; |
||||||
|
} |
||||||
|
|
||||||
|
return($type); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
sub ok_function { |
||||||
|
my ($self) = @_; |
||||||
|
|
||||||
|
# is there a user defined ok_function? |
||||||
|
if (defined $self->{'User_OK_function'}) { |
||||||
|
$self->{'User_OK_function'}($self, selection_fname($self)); |
||||||
|
} |
||||||
|
# otherwise do default |
||||||
|
else { |
||||||
|
printf STDOUT "%s\n", selection_fname($self); |
||||||
|
$self->hide(); |
||||||
|
} |
||||||
|
return $true; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
sub cancel_function { |
||||||
|
my ($self) = @_; |
||||||
|
|
||||||
|
# is there a user defined ok_function? |
||||||
|
if (defined $self->{'User_CANCEL_function'}) { |
||||||
|
$self->{'User_CANCEL_function'}($self, get_listselect($self)); |
||||||
|
} |
||||||
|
# otherwise do default |
||||||
|
else { |
||||||
|
$self->{'window'}->hide(); |
||||||
|
$self->{'dialog_shown'} = $false; |
||||||
|
} |
||||||
|
return $true; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# |
||||||
|
# sort the table by the clicked column |
||||||
|
# |
||||||
|
sub _sort_clist { |
||||||
|
my ($clist, $col) = @_; |
||||||
|
|
||||||
|
$clist->set_sort_column($col); |
||||||
|
$clist->sort(); |
||||||
|
|
||||||
|
return(1); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
# |
||||||
|
# called on mouseclick in certlist |
||||||
|
# |
||||||
|
sub _show_cert_menu { |
||||||
|
my ($clist, $self, $event) = @_; |
||||||
|
|
||||||
|
if ((defined($event->{'type'})) && |
||||||
|
$event->{'button'} == 3) { |
||||||
|
$self->{'certmenu'}->popup( |
||||||
|
undef, |
||||||
|
undef, |
||||||
|
0, |
||||||
|
$event->{'button'}, |
||||||
|
undef); |
||||||
|
|
||||||
|
return(1); |
||||||
|
} |
||||||
|
|
||||||
|
return(0); |
||||||
|
} |
||||||
|
|
||||||
|
$true; |
||||||
|
|
||||||
|
__END__ |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
GUI::X509_browser - Perl-Gtk2 browser for X.509 certificates and requests |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use X509_browser; |
||||||
|
|
||||||
|
$browser=X509_browser->new($mode); |
||||||
|
$browser->create_window($title, $oktext, $canceltext, |
||||||
|
\&okayfunction, \&cancelfunction); |
||||||
|
$browser->add_ca_select($cadir, @calist, $active-ca); |
||||||
|
$browser->add_list($active-ca, $X509dir, $crlfile, $indexfile); |
||||||
|
$browser->add_info(); |
||||||
|
my $selection = $browser->selection_fname(); |
||||||
|
$browser->hide(); |
||||||
|
|
||||||
|
=head1 DESCRIPTION |
||||||
|
|
||||||
|
This displays a browser for X.509v3 certificates or certification |
||||||
|
requests (CSR) from a CA managed by TinyCA2 (or some similar |
||||||
|
structure). |
||||||
|
|
||||||
|
Creation of an X509_browser is done by calling B<new()>, |
||||||
|
the argument has to be 'cert' or 'req' to display certificates |
||||||
|
or requests. |
||||||
|
|
||||||
|
A window can be created for this purpose using |
||||||
|
B<create_window($title, $oktext, $canceltext, \&okfunction, \&cancelfunction)>, |
||||||
|
all arguments are optional. |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
=item $title: |
||||||
|
|
||||||
|
the existing Gtk2::VBox inside which the info will be |
||||||
|
displayed. |
||||||
|
|
||||||
|
=item $oktext: |
||||||
|
|
||||||
|
The text to be displayed on the OK button of the dialog. |
||||||
|
|
||||||
|
=item $canceltext: |
||||||
|
|
||||||
|
The text to be displayed on the CANCEL button of the dialog. |
||||||
|
|
||||||
|
=item \&okfunction: |
||||||
|
|
||||||
|
Reference to a function that is executed on click on OK button. |
||||||
|
This function should fetch the selected result (using |
||||||
|
B<selection_fname()>) and also close the dialog using B<hide()>. |
||||||
|
|
||||||
|
=item \&cancelfunction: |
||||||
|
|
||||||
|
Reference to a function that is executed on click on CANCEL button. |
||||||
|
This function should also close the dialog using B<hide()>. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
Further functions to get information about the selected item |
||||||
|
exist, these are <B>selection_dn()</B>, <B>selection_status()</B>, |
||||||
|
<B>selection_cadir()</B> and <B>selection_caname()</B>. |
||||||
|
|
||||||
|
An existing infobox that already displays the content |
||||||
|
of some directory can be modified by calling |
||||||
|
<B>update()</B> with the same arguments that add_list(). |
||||||
|
|
||||||
|
An existing infobox is destroyed by calling B<destroy()>. |
||||||
|
|
||||||
|
=cut |
@ -0,0 +1,280 @@ |
|||||||
|
# Copyright (c) Olaf Gellert <og@pre-secure.de> and |
||||||
|
# Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: X509_infobox.pm,v 1.7 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package GUI::X509_infobox; |
||||||
|
|
||||||
|
use HELPERS; |
||||||
|
use GUI::HELPERS; |
||||||
|
use GUI::WORDS; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
my $version = "0.1"; |
||||||
|
my $true = 1; |
||||||
|
my $false = undef; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $that = shift; |
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
$self->{'init'} = shift; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
|
||||||
|
$self; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
sub display { |
||||||
|
my ($self, $parent, $parsed, $mode, $title) = @_; |
||||||
|
|
||||||
|
my ($bottombox, $textbox, $lefttable, $righttable, $leftbox, $rightbox, |
||||||
|
@fields, $scrolled); |
||||||
|
|
||||||
|
$self->{'root'} = $parent; |
||||||
|
|
||||||
|
if (defined $self->{'child'}) { |
||||||
|
$self->{'child'}->destroy(); |
||||||
|
} |
||||||
|
|
||||||
|
# if title is given create a surrounding frame with the title |
||||||
|
if (defined $title) { |
||||||
|
$self->{'child'}= Gtk2::Frame->new($title); |
||||||
|
$self->{'x509textbox'}= Gtk2::VBox->new(0,0); |
||||||
|
$self->{'child'}->add($self->{'x509textbox'}); |
||||||
|
} |
||||||
|
# otherwise we create the VBox directly inside the root widget |
||||||
|
else { |
||||||
|
$self->{'child'} = Gtk2::VBox->new(0,0); |
||||||
|
$self->{'x509textbox'} = $self->{'child'}; |
||||||
|
} |
||||||
|
|
||||||
|
# and pack it there |
||||||
|
$self->{'root'}->pack_start($self->{'child'}, 1, 1, 0); |
||||||
|
|
||||||
|
if (($mode eq 'cert') || ($mode eq 'cacert')) { |
||||||
|
# fingerprint in the top of certtextbox |
||||||
|
if(defined($self->{'certfingerprintmd5'})) { |
||||||
|
$self->{'certfingerprintmd5'}->destroy(); |
||||||
|
} |
||||||
|
$self->{'certfingerprintmd5'} = GUI::HELPERS::create_label( |
||||||
|
_("Fingerprint (MD5)").": ".$parsed->{'FINGERPRINTMD5'}, |
||||||
|
'center', 0, 0); |
||||||
|
$self->{'x509textbox'}->pack_start( $self->{'certfingerprintmd5'}, |
||||||
|
0, 0, 0); |
||||||
|
|
||||||
|
if(defined($self->{'certfingerprintsha1'})) { |
||||||
|
$self->{'certfingerprintsha1'}->destroy(); |
||||||
|
} |
||||||
|
$self->{'certfingerprintsha1'} = GUI::HELPERS::create_label( |
||||||
|
_("Fingerprint (SHA1)").": ".$parsed->{'FINGERPRINTSHA1'}, |
||||||
|
'center', 0, 0); |
||||||
|
$self->{'x509textbox'}->pack_start($self->{'certfingerprintsha1'}, |
||||||
|
0, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
if (($mode eq 'cert') || ($mode eq 'cacert')) { |
||||||
|
$bottombox = 'certbottombox'; |
||||||
|
$textbox = 'x509textbox'; |
||||||
|
$lefttable = 'certlefttable'; |
||||||
|
$leftbox = 'certleftbox'; |
||||||
|
$righttable = 'certrighttable'; |
||||||
|
$rightbox = 'certrightbox'; |
||||||
|
}else{ |
||||||
|
$bottombox = 'reqbottombox'; |
||||||
|
$textbox = 'x509textbox'; |
||||||
|
$lefttable = 'reqlefttable'; |
||||||
|
$leftbox = 'reqleftbox'; |
||||||
|
$righttable = 'reqrighttable'; |
||||||
|
$rightbox = 'reqrightbox'; |
||||||
|
} |
||||||
|
|
||||||
|
# hbox in the bottom |
||||||
|
if(defined($self->{$bottombox})) { |
||||||
|
$self->{$bottombox}->destroy(); |
||||||
|
} |
||||||
|
$self->{$bottombox} = Gtk2::HBox->new(1, 0); |
||||||
|
$self->{$textbox}->pack_start($self->{$bottombox}, 1, 1, 5); |
||||||
|
|
||||||
|
# vbox in the bottom/left |
||||||
|
if(defined($self->{$lefttable})) { |
||||||
|
$self->{$lefttable}->destroy(); |
||||||
|
} |
||||||
|
@fields = qw( CN EMAIL O OU L ST C); |
||||||
|
$self->{$lefttable} = _create_detail_table(\@fields, $parsed); |
||||||
|
|
||||||
|
# the only widget i know to set shadow type :-( |
||||||
|
$scrolled = Gtk2::ScrolledWindow->new(); |
||||||
|
$scrolled->set_shadow_type('etched-in'); |
||||||
|
$scrolled->set_policy('never', 'never'); |
||||||
|
|
||||||
|
$self->{$leftbox} = Gtk2::VBox->new(0, 0); |
||||||
|
$self->{$bottombox}->pack_start($self->{$leftbox}, 1, 1, 0); |
||||||
|
|
||||||
|
$self->{$leftbox}->pack_start($scrolled, 1, 1, 0); |
||||||
|
$scrolled->add($self->{$lefttable}); |
||||||
|
|
||||||
|
# vbox in the bottom/right |
||||||
|
if(defined($self->{$righttable})) { |
||||||
|
$self->{$righttable}->destroy(); |
||||||
|
} |
||||||
|
if ($mode eq "cacert") { |
||||||
|
@fields = qw(SERIAL NOTBEFORE NOTAFTER KEYSIZE PK_ALGORITHM SIG_ALGORITHM |
||||||
|
TYPE); |
||||||
|
} else { |
||||||
|
@fields = qw(STATUS SERIAL NOTBEFORE NOTAFTER KEYSIZE PK_ALGORITHM |
||||||
|
SIG_ALGORITHM TYPE); |
||||||
|
} |
||||||
|
|
||||||
|
$self->{$righttable} = _create_detail_table(\@fields, $parsed); |
||||||
|
|
||||||
|
$scrolled = Gtk2::ScrolledWindow->new(); |
||||||
|
$scrolled->set_shadow_type('etched-in'); |
||||||
|
$scrolled->set_policy('never', 'never'); |
||||||
|
|
||||||
|
$self->{$rightbox} = Gtk2::VBox->new(0, 0); |
||||||
|
$self->{$bottombox}->pack_start($self->{$rightbox}, 1, 1, 0); |
||||||
|
|
||||||
|
$self->{$rightbox}->pack_start($scrolled, 1, 1, 0); |
||||||
|
$scrolled->add($self->{$righttable}); |
||||||
|
|
||||||
|
$self->{$textbox}->show_all(); |
||||||
|
|
||||||
|
$parent->show_all(); |
||||||
|
} |
||||||
|
|
||||||
|
sub hide { |
||||||
|
my $self = shift; |
||||||
|
|
||||||
|
if (defined $self->{'child'}) { |
||||||
|
$self->{'child'}->destroy(); |
||||||
|
undef $self->{'child'}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# create standard table with details (cert/req) |
||||||
|
# |
||||||
|
sub _create_detail_table { |
||||||
|
my ($fields, $parsed) = @_; |
||||||
|
|
||||||
|
my ($list, $store, $rows, $words, @l, $iter, $column, $renderer); |
||||||
|
|
||||||
|
$words = GUI::WORDS->new(); |
||||||
|
|
||||||
|
$store = Gtk2::ListStore->new('Glib::String', 'Glib::String'); |
||||||
|
$list = Gtk2::TreeView->new_with_model($store); |
||||||
|
$list->set_headers_visible(0); |
||||||
|
$list->get_selection->set_mode('none'); |
||||||
|
|
||||||
|
$renderer = Gtk2::CellRendererText->new(); |
||||||
|
$column = Gtk2::TreeViewColumn->new_with_attributes( |
||||||
|
'', $renderer, 'text' => 0); |
||||||
|
$list->append_column($column); |
||||||
|
|
||||||
|
$renderer = Gtk2::CellRendererText->new(); |
||||||
|
$column = Gtk2::TreeViewColumn->new_with_attributes( |
||||||
|
'', $renderer, 'text' => 1); |
||||||
|
$list->append_column($column); |
||||||
|
|
||||||
|
|
||||||
|
foreach my $f (@{$fields}) { |
||||||
|
if(defined($parsed->{$f})){ |
||||||
|
if(ref($parsed->{$f})) { |
||||||
|
foreach(@{$parsed->{$f}}) { |
||||||
|
$iter = $store->append(); |
||||||
|
$store->set($iter, 0 => $words->{$f}, 1 => $_); |
||||||
|
# print STDERR "DEBUG: add line: @l\n"; |
||||||
|
|
||||||
|
} |
||||||
|
}else{ |
||||||
|
# print STDERR "DEBUG: add line: @l\n"; |
||||||
|
$iter = $store->append(); |
||||||
|
$store->set($iter, 0 => $words->{$f}, 1 => $parsed->{$f}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return($list); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
1; |
||||||
|
|
||||||
|
|
||||||
|
__END__ |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
GUI::X509_infobox - show X.509 certificates and requests in a Gtk2::VBox |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use X509_infobox; |
||||||
|
|
||||||
|
$infobox=X509_infobox->new(); |
||||||
|
$infobox->update($parent,$parsed,$mode,$title); |
||||||
|
$infobox->update($parent,$parsed,$mode); |
||||||
|
$infobox->hide(); |
||||||
|
|
||||||
|
=head1 DESCRIPTION |
||||||
|
|
||||||
|
This displays the information of an X.509v3 certificate or |
||||||
|
certification request (CSR) inside a given Gtk2::VBox. |
||||||
|
|
||||||
|
Creation of an X509_infobox is done by calling B<new()>, |
||||||
|
no arguments are required. |
||||||
|
|
||||||
|
The infobox is shown when inserted into an already |
||||||
|
existing Gtk2::VBox using the method B<update()>. Arguments |
||||||
|
to update are: |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
=item $parent: |
||||||
|
|
||||||
|
the existing Gtk2::VBox inside which the info will be |
||||||
|
displayed. |
||||||
|
|
||||||
|
=item $parsed: |
||||||
|
|
||||||
|
a structure returned by OpenSSL::parsecert() or OpenSSL::parsecrl() |
||||||
|
containing the required information. |
||||||
|
|
||||||
|
=item $mode: |
||||||
|
|
||||||
|
what type of information is to be displayed. Valid modes |
||||||
|
are 'req' (certification request), 'cert' (certificate), 'key' or 'cacert' |
||||||
|
(same as certificate but without displaying the validity information |
||||||
|
of the cert because this cannot be decided on from the view of the |
||||||
|
actual CA). |
||||||
|
|
||||||
|
=item $title: |
||||||
|
|
||||||
|
if specified, a surrounding frame with the given title |
||||||
|
is drawn. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
An existing infobox is destroyed by calling B<hide()>. |
||||||
|
|
||||||
|
=cut |
@ -0,0 +1,393 @@ |
|||||||
|
# Copyright (c) Olaf Gellert <og@pre-secure.de> and |
||||||
|
# Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: HELPERS.pm,v 1.6 2006/06/28 21:50:41 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
package HELPERS; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
my $version = "0.1"; |
||||||
|
my $true = 1; |
||||||
|
my $false = undef; |
||||||
|
|
||||||
|
# |
||||||
|
# generate filename from Subject-DN |
||||||
|
# |
||||||
|
sub gen_name { |
||||||
|
my $opts = shift; |
||||||
|
|
||||||
|
my $name = ''; |
||||||
|
|
||||||
|
foreach (qw(CN EMAIL OU O L ST C)) { |
||||||
|
if((not defined($opts->{$_})) || ($opts->{$_} eq '')) { |
||||||
|
$opts->{$_} = "."; |
||||||
|
} |
||||||
|
if($opts->{$_} ne '.' && not ref($opts->{$_})) { |
||||||
|
$name .= $opts->{$_}; |
||||||
|
} elsif (ref($opts->{$_})) { |
||||||
|
if(defined($opts->{$_}->[0])) { |
||||||
|
$name .= $opts->{$_}->[0]; |
||||||
|
} else { |
||||||
|
$name .= " "; |
||||||
|
} |
||||||
|
} else { |
||||||
|
$name .= " "; |
||||||
|
} |
||||||
|
$name .= ":" if($_ ne 'C'); |
||||||
|
} |
||||||
|
|
||||||
|
return($name); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# generate temporary filename |
||||||
|
# |
||||||
|
sub mktmp { |
||||||
|
my $base = shift; |
||||||
|
|
||||||
|
my @rand = (); |
||||||
|
my $ret = ''; |
||||||
|
|
||||||
|
do { |
||||||
|
for(my $i = 0; $i < 8; $i++) { |
||||||
|
push(@rand, int(rand 26)+65); |
||||||
|
} |
||||||
|
my $end = pack("C8", @rand); |
||||||
|
$ret = $base.$end; |
||||||
|
} while (-e $ret); |
||||||
|
|
||||||
|
return($ret); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
# |
||||||
|
# finished... |
||||||
|
# |
||||||
|
sub exit_clean { |
||||||
|
my ($ret) = @_; |
||||||
|
|
||||||
|
$ret = 0 unless(defined $ret); |
||||||
|
|
||||||
|
# hack to avoid busy cursor |
||||||
|
my $rootwin = Gtk2::Gdk->get_default_root_window(); |
||||||
|
my $cursor = Gtk2::Gdk::Cursor->new('left-ptr'); |
||||||
|
|
||||||
|
$rootwin->set_cursor($cursor); |
||||||
|
|
||||||
|
Gtk2->main_quit(); |
||||||
|
exit($ret); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# split Subject DN and return hash |
||||||
|
# |
||||||
|
sub parse_dn { |
||||||
|
my $dn = shift; |
||||||
|
|
||||||
|
my (@dn, $k, $v, $tmp); |
||||||
|
|
||||||
|
$tmp = {}; |
||||||
|
|
||||||
|
$dn =~ s/,/\//g; |
||||||
|
|
||||||
|
@dn = split(/\//, $dn); |
||||||
|
foreach(@dn) { |
||||||
|
s/^\s+//; |
||||||
|
s/\s+$//; |
||||||
|
($k, $v) = split(/=/); |
||||||
|
next if(not defined($k)); |
||||||
|
if($k =~ /ou/i) { |
||||||
|
$tmp->{'OU'} or $tmp->{'OU'} = []; |
||||||
|
push(@{$tmp->{'OU'}}, $v); |
||||||
|
} else { |
||||||
|
if($k =~ /emailaddress/i) { |
||||||
|
$tmp->{'EMAIL'} = $v; |
||||||
|
} else { |
||||||
|
$tmp->{uc($k)} = $v; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return($tmp); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# parse (requested) X509 extensions and return hash |
||||||
|
# |
||||||
|
sub parse_extensions { |
||||||
|
my ($lines, $mode) = @_; |
||||||
|
|
||||||
|
my ($sep, $i, $k, $v, $tmp); |
||||||
|
|
||||||
|
$sep = $mode eq "req"?"Requested extensions:":"X509v3 extensions:"; |
||||||
|
|
||||||
|
$tmp = {}; |
||||||
|
|
||||||
|
# skip everything before the extensions |
||||||
|
for($i = 0; defined($lines->[$i]) && $lines->[$i] !~ /^[\s\t]*$sep$/i; $i++) { |
||||||
|
return(undef) if not defined($lines->[$i]); |
||||||
|
} |
||||||
|
$i++; |
||||||
|
|
||||||
|
while($i < @{$lines}) { |
||||||
|
if(($lines->[$i] =~ /^[\s\t]*[^:]+:\s*$/) || |
||||||
|
($lines->[$i] =~ /^[\s\t]*[^:]+:\s+.+$/)) { |
||||||
|
if($lines->[$i] =~ /^[\s\t]*Signature Algorithm/i) { |
||||||
|
$i++; |
||||||
|
next; |
||||||
|
} |
||||||
|
$k = $lines->[$i]; |
||||||
|
$k =~ s/[\s\t:]*$//g; |
||||||
|
$k =~ s/^[\s\t]*//g; |
||||||
|
$tmp->{$k} = []; |
||||||
|
$i++; |
||||||
|
while(($lines->[$i] !~ /^[\s\t].+:\s*$/) && |
||||||
|
($lines->[$i] !~ /^[\s\t]*[^:]+:\s+.+$/) && |
||||||
|
($lines->[$i] !~ /^[\s\t]*Signature Algorithm/i) && |
||||||
|
($i < @{$lines})) { |
||||||
|
$v = $lines->[$i]; |
||||||
|
$v =~ s/^[\s]+//g; |
||||||
|
$v =~ s/[\s]+$//g; |
||||||
|
$i++; |
||||||
|
next if $v =~ /^$/; |
||||||
|
next if $v =~ /Signature Algorithm:/; |
||||||
|
my @vs = split(/,/, $v); |
||||||
|
foreach(@vs) { |
||||||
|
$_ =~ s/^\s//; |
||||||
|
$_ =~ s/\s$//; |
||||||
|
push(@{$tmp->{$k}}, $_); |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
$i++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return($tmp); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get last used export directory |
||||||
|
# |
||||||
|
sub get_export_dir { |
||||||
|
my $main = shift; |
||||||
|
|
||||||
|
open(EXPIN, "<$main->{'cadir'}/.exportdir") || return(undef); |
||||||
|
my $dir = <EXPIN>; |
||||||
|
chomp($dir); |
||||||
|
|
||||||
|
return($dir); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# write last used export directory |
||||||
|
# |
||||||
|
sub write_export_dir { |
||||||
|
my ($main, $dir) = @_; |
||||||
|
|
||||||
|
$dir =~ s:/[^/]+$::; |
||||||
|
|
||||||
|
open(EXPOUT, ">$main->{'cadir'}/.exportdir") || do { |
||||||
|
my $t = sprintf(_("Can't write exportdir: %s, %s"), |
||||||
|
"$main->{'cadir'}/.exportdir", $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print EXPOUT "$dir\n"; |
||||||
|
|
||||||
|
close(EXPOUT); |
||||||
|
|
||||||
|
return($dir); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# generate contents for subjectAltName |
||||||
|
# |
||||||
|
sub gen_subjectaltname_contents($@) |
||||||
|
{ |
||||||
|
my $type = shift || ''; |
||||||
|
my @input = map { split/,\s*|\s+/, $_ } @_; # split on ',' and ' ' |
||||||
|
my %output = (); # uniq on the fly |
||||||
|
|
||||||
|
if ($type) { # type given => use that one for all |
||||||
|
foreach my $elem (@input) { |
||||||
|
$output{$type.$elem} = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
else { # no type => use heuristigcs to guess type per element |
||||||
|
foreach my $elem (@input) { |
||||||
|
if ($elem =~ s/^(ip:|dns:)(.*)/$2/i) { |
||||||
|
$type = uc($1); |
||||||
|
} elsif ($elem =~ s/^(email:)(.*)/$2/i) { |
||||||
|
$type = lc($1); |
||||||
|
} else { |
||||||
|
if ($elem =~ /^\d+\.\d+\.\d+\.\d+$/) { # it's an IP address |
||||||
|
$type = 'IP:'; |
||||||
|
} |
||||||
|
elsif ($elem =~ /^.+\@.+\.\w+$/) { # it's a mail address |
||||||
|
$type = 'email:'; |
||||||
|
} |
||||||
|
else { |
||||||
|
$type = 'DNS:' # otherwise it's a DNS name |
||||||
|
} |
||||||
|
} |
||||||
|
$output{$type.$elem} = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
return(wantarray ? keys(%output) : join(', ', keys(%output))); |
||||||
|
} |
||||||
|
|
||||||
|
sub enc_base64 { |
||||||
|
my $data = shift; |
||||||
|
my $ret = MIME::Base64::encode($data, ''); |
||||||
|
$ret =~ tr/\/+/-_/; |
||||||
|
return $ret; |
||||||
|
} |
||||||
|
|
||||||
|
sub dec_base64 { |
||||||
|
my $data = shift; |
||||||
|
$data =~ tr/-_/\/+/; |
||||||
|
return MIME::Base64::decode($data); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
1 |
||||||
|
|
||||||
|
__END__ |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
HELPERS - helper functions for TinyCA, doing small jobs not related to the GUI |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use HELPERS; |
||||||
|
|
||||||
|
$name = HELPERS::gen_name($opts); |
||||||
|
$tmpnam = HELPERS::mktmp($base); |
||||||
|
$dnhash = HELPERS::parse_dn($dnstring); |
||||||
|
$exthash = HELPERS::parse_extensions($mode, $lines); |
||||||
|
$subjaltname = HELPERS::gen_subjectaltname_contents($type, @list); |
||||||
|
|
||||||
|
exit_clean($retcode); |
||||||
|
|
||||||
|
=head1 DESCRIPTION |
||||||
|
|
||||||
|
HELPERS.pm is just a library, containing some useful functions used by other |
||||||
|
TinyCA modules. |
||||||
|
|
||||||
|
=head1 FUNCTIONS |
||||||
|
|
||||||
|
=head2 HELPERS::gen_name($opts) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns a string with the TinyCA filename for a certificate, request or key. |
||||||
|
The filename is generated from the following parts of the Subject DN from the |
||||||
|
related request or certificate if present: |
||||||
|
|
||||||
|
CN EMAIL OU O L ST C |
||||||
|
|
||||||
|
These parts need to be elements in the given options hash. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 HELPERS::mktmp($base) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns a string, containing a uniqe filename starting with $base, which is |
||||||
|
not existing yet. |
||||||
|
|
||||||
|
$base needs to be an absolute path to allow HELPERS::mktmp() reliable check |
||||||
|
that the filename is really uniqe. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 HELPERS::parse_dn($dnstring) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns the reference to a hash containing all elements of the Subject DN, |
||||||
|
given in $dnstring. |
||||||
|
|
||||||
|
The element OU is included as an array refernce in the hash, with an array |
||||||
|
containing all values of OU. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 HELPERS::parse_extensions($mode, $lines) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
returns the reference to a hash containing all X509 extensions of the given |
||||||
|
request or certificate. |
||||||
|
|
||||||
|
The request or certificate is given in textform as an array reference |
||||||
|
with the array containing one line per element. |
||||||
|
|
||||||
|
$mode contains one of the strings "req" or "cert" depending on the type of the |
||||||
|
data. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 HELPERS::exit_clean($retcode) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
does nothing yet, than closing the Gtk application returning the exitcode |
||||||
|
given in $retcode. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 $main->HELPERS::get_export_dir() |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
Get last used export directory. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 $main->HELPERS::write_export-dir($dir) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
Store last used export directory |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=head2 HELPERS::gen_subjectaltname_contents($type, @list) |
||||||
|
|
||||||
|
=over 1 |
||||||
|
|
||||||
|
Generate a string suitable for the use as subjhectAltname contets for OpenSSL. |
||||||
|
|
||||||
|
If $Type is not empty create the contents of that type only, |
||||||
|
otherwise use either the type prefix of the list elements or |
||||||
|
the following heuristics to find the type for the appropriate elements: |
||||||
|
|
||||||
|
If the element looks like an IP address in dotted quad notation set |
||||||
|
then treat it as one. |
||||||
|
If the element contains a '@' followed by a '.' and a sequence of letters |
||||||
|
then treat the element as an email address. |
||||||
|
In all other cases treat it as a DNS name. |
||||||
|
|
||||||
|
=back |
||||||
|
|
||||||
|
=cut |
@ -0,0 +1,494 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: KEY.pm,v 1.8 2006/06/28 21:50:41 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
|
||||||
|
package KEY; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $self = {}; |
||||||
|
my $that = shift; |
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get name of keyfile to delete |
||||||
|
# |
||||||
|
sub get_del_key { |
||||||
|
my ($self, $main) = @_; |
||||||
|
|
||||||
|
my($keyname, $key, $keyfile, $row, $ind, $ca, $type); |
||||||
|
|
||||||
|
$ca = $main->{'keybrowser'}->selection_caname(); |
||||||
|
$key = $main->{'keybrowser'}->selection_dn(); |
||||||
|
|
||||||
|
if(not defined $key) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Key first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$keyname = HELPERS::enc_base64($key); |
||||||
|
|
||||||
|
$keyfile = $main->{'cadir'}."/keys/".$keyname.".pem"; |
||||||
|
|
||||||
|
if(not -s $keyfile) { |
||||||
|
GUI::HELPERS::print_warning(_("Key file not found:".$keyfile)); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_del_confirm($keyfile, 'key'); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# now really delete the key |
||||||
|
# |
||||||
|
sub del_key { |
||||||
|
my ($self, $main, $file) = @_; |
||||||
|
|
||||||
|
unlink($file); |
||||||
|
|
||||||
|
my $cadir = $main->{'keybrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$main->{'keybrowser'}->update($cadir."/keys", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# read keys in directory into list |
||||||
|
# |
||||||
|
sub read_keylist { |
||||||
|
my ($self, $main) = @_; |
||||||
|
|
||||||
|
my ($f, $modt, $tmp, $ca, $keydir, $keylist); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
$keydir = $main->{'cadir'}."/keys"; |
||||||
|
$keylist = []; |
||||||
|
|
||||||
|
$modt = (stat($keydir))[9]; |
||||||
|
|
||||||
|
if(defined($self->{'lastread'}) && |
||||||
|
$self->{'lastread'} >= $modt) { |
||||||
|
return(0); |
||||||
|
} |
||||||
|
|
||||||
|
opendir(DIR, $keydir) || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't open key directory")); |
||||||
|
return(0); |
||||||
|
}; |
||||||
|
|
||||||
|
while($f = readdir(DIR)) { |
||||||
|
next if $f =~ /^\./; |
||||||
|
$f =~ s/\.pem//; |
||||||
|
$tmp = HELPERS::dec_base64($f); |
||||||
|
next if not defined($tmp); |
||||||
|
next if $tmp eq ""; |
||||||
|
$tmp = _check_key($main, $keydir."/".$f.".pem", $tmp); |
||||||
|
push(@{$keylist}, $tmp); |
||||||
|
} |
||||||
|
@{$keylist} = sort(@{$keylist}); |
||||||
|
closedir(DIR); |
||||||
|
|
||||||
|
$self->{'keylist'} = $keylist; |
||||||
|
|
||||||
|
$self->{'lastread'} = time(); |
||||||
|
return(1); # got new list |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get the information to export the key |
||||||
|
# |
||||||
|
sub get_export_key { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
my($ca, $ind, $row, $t, $out, $cn, $email, $ret, $ext, $cadir); |
||||||
|
|
||||||
|
if(not defined($opts)) { |
||||||
|
$cn = $main->{'keybrowser'}->selection_cn(); |
||||||
|
|
||||||
|
if(not defined $cn) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Key first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$ca = $main->{'keybrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'keybrowser'}->selection_cadir(); |
||||||
|
$email = $main->{'keybrowser'}->selection_email(); |
||||||
|
|
||||||
|
$opts->{'type'} = $main->{'keybrowser'}->selection_type(); |
||||||
|
$opts->{'key'} = $main->{'keybrowser'}->selection_dn(); |
||||||
|
|
||||||
|
$opts->{'keyname'} = HELPERS::enc_base64($opts->{'key'}); |
||||||
|
$opts->{'keyfile'} = $cadir."/keys/".$opts->{'keyname'}.".pem"; |
||||||
|
$opts->{'certfile'} = $cadir."/certs/".$opts->{'keyname'}.".pem"; |
||||||
|
|
||||||
|
# set some defaults |
||||||
|
$opts->{'nopass'} = 0; |
||||||
|
$opts->{'include'} = 0; |
||||||
|
$opts->{'format'} = 'PEM'; |
||||||
|
$opts->{'friendlyname'} = ''; |
||||||
|
|
||||||
|
if((defined($email)) && $email ne '' && $email ne ' ') { |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/$email-key.pem"; |
||||||
|
}elsif((defined($cn)) && $cn ne '' && $cn ne ' ') { |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/$cn-key.pem"; |
||||||
|
}else{ |
||||||
|
$opts->{'outfile'} = "$main->{'exportdir'}/key.pem"; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_export_dialog($opts, 'key'); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'outfile'})) || ($opts->{'outfile'} eq '')) { |
||||||
|
$main->show_export_dialog($opts, 'key'); |
||||||
|
GUI::HELPERS::print_warning(_("Please give at least the output file")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if(($opts->{'nopass'} || $opts->{'format'} eq 'DER') && |
||||||
|
((not defined($opts->{'passwd'})) || ($opts->{'passwd'} eq ''))) { |
||||||
|
$main->show_key_nopasswd_dialog($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if(($opts->{'format'} eq 'PEM') || ($opts->{'format'} eq 'DER')) { |
||||||
|
unless(($opts->{'format'} eq 'PEM') && not $opts->{'nopass'}) { |
||||||
|
($out, $ext) = $main->{'OpenSSL'}->convkey( |
||||||
|
'type' => $opts->{'type'}, |
||||||
|
'inform' => 'PEM', |
||||||
|
'outform' => $opts->{'format'}, |
||||||
|
'nopass' => $opts->{'nopass'}, |
||||||
|
'pass' => $opts->{'passwd'}, |
||||||
|
'keyfile' => $opts->{'keyfile'} |
||||||
|
); |
||||||
|
|
||||||
|
if(defined($out) && $out eq 1) { |
||||||
|
$t = _("Wrong password given\nDecrypting of the Key failed\nExport is not possible"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
return; |
||||||
|
} elsif((not defined($out)) || (length($out) < 3)) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Converting failed, Export not possible"), $ext); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if(($opts->{'format'} eq 'PEM') && not $opts->{'nopass'}) { |
||||||
|
open(IN, "<$opts->{'keyfile'}") || do { |
||||||
|
$t = sprintf(_("Can't open Key file: %s: %s"), |
||||||
|
$opts->{'keyfile'}, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
$out .= $_ while(<IN>); |
||||||
|
close(IN); |
||||||
|
} |
||||||
|
if($opts->{'include'}) { |
||||||
|
open(IN, "<$opts->{'certfile'}") || do { |
||||||
|
$t = sprintf(_("Can't open Certificate file: %s: %s"), |
||||||
|
$opts->{'certfile'}, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
$out .= "\n"; |
||||||
|
$out .= $_ while(<IN>); |
||||||
|
close(IN); |
||||||
|
} |
||||||
|
|
||||||
|
open(OUT, ">$opts->{'outfile'}") || do { |
||||||
|
$t = sprintf(_("Can't open output file: %s: %s"), |
||||||
|
$opts->{'outfile'}, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
print OUT $out; |
||||||
|
close(OUT); |
||||||
|
|
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
|
||||||
|
$t = sprintf(_("Key succesfully exported to %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t); |
||||||
|
return; |
||||||
|
|
||||||
|
} elsif ($opts->{'format'} eq 'P12') { |
||||||
|
$opts->{'certfile'} = |
||||||
|
$main->{'cadir'}."/certs/".$opts->{'keyname'}.".pem"; |
||||||
|
$opts->{'cafile'} = |
||||||
|
$main->{'cadir'}."/cacert.pem"; |
||||||
|
|
||||||
|
if (-f $main->{'cadir'}."/cachain.pem") { |
||||||
|
$opts->{'cafile'} = $main->{'cadir'}."/cachain.pem"; |
||||||
|
} |
||||||
|
|
||||||
|
if(not -s $opts->{'certfile'}) { |
||||||
|
$t = _("Certificate is necessary for export as PKCS#12"); |
||||||
|
$t .= "\n"; |
||||||
|
$t .= _("Export is not possible!"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'p12passwd'})) && |
||||||
|
(not $opts->{'nopass'})) { |
||||||
|
$opts->{'includeca'} = 1; |
||||||
|
$main->show_p12_export_dialog($opts, 'key'); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
unlink($opts->{'outfile'}); |
||||||
|
($ret, $ext) = $main->{'OpenSSL'}->genp12( |
||||||
|
type => $opts->{'type'}, |
||||||
|
certfile => $opts->{'certfile'}, |
||||||
|
keyfile => $opts->{'keyfile'}, |
||||||
|
cafile => $opts->{'cafile'}, |
||||||
|
outfile => $opts->{'outfile'}, |
||||||
|
passwd => $opts->{'passwd'}, |
||||||
|
p12passwd => $opts->{'p12passwd'}, |
||||||
|
includeca => $opts->{'includeca'}, |
||||||
|
nopass => $opts->{'nopass'}, |
||||||
|
friendly => $opts->{'friendlyname'} |
||||||
|
); |
||||||
|
|
||||||
|
if($ret eq 1) { |
||||||
|
$t = "Wrong password given\nDecrypting Key failed\nGenerating PKCS#12 failed"; |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
return; |
||||||
|
} elsif($ret || (not -s $opts->{'outfile'})) { |
||||||
|
$t = _("Generating PKCS#12 failed"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
|
||||||
|
$t = sprintf(_("Certificate and Key successfully exported to %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t, $ext); |
||||||
|
return; |
||||||
|
|
||||||
|
} elsif (($opts->{'format'} eq "ZIP") || ($opts->{'format'} eq "TAR")) { |
||||||
|
$opts->{'certfile'} = |
||||||
|
$main->{'cadir'}."/certs/".$opts->{'keyname'}.".pem"; |
||||||
|
if(not -s $opts->{'certfile'}) { |
||||||
|
$t = sprintf( |
||||||
|
_("Certificate is necessary for export as %s file"), |
||||||
|
$opts->{'format'}); |
||||||
|
$t .= "\n"; |
||||||
|
$t .= _("Export is not possible!"); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'parsed'} = |
||||||
|
$main->{'CERT'}->parse_cert($main, $opts->{'keyname'}); |
||||||
|
|
||||||
|
my $tmpcert = "$main->{'tmpdir'}/cert.pem"; |
||||||
|
my $tmpkey = "$main->{'tmpdir'}/key.pem"; |
||||||
|
my $tmpcacert = "$main->{'tmpdir'}/cacert.pem"; |
||||||
|
|
||||||
|
open(OUT, ">$tmpcert") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't create temporary file")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT $opts->{'parsed'}->{'PEM'}; |
||||||
|
close OUT; |
||||||
|
|
||||||
|
# store key in temporary location |
||||||
|
{ |
||||||
|
open(IN, "<$opts->{'keyfile'}") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't read Key file")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
my @key = <IN>; |
||||||
|
close IN; |
||||||
|
|
||||||
|
open(OUT, ">$tmpkey") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't create temporary file")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT @key; |
||||||
|
close OUT; |
||||||
|
} |
||||||
|
|
||||||
|
# store cacert in temporary location |
||||||
|
{ |
||||||
|
$opts->{'cafile'} = $main->{'cadir'}."/cacert.pem"; |
||||||
|
open(IN, "<$opts->{'cafile'}") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't read CA certificate")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
my @cacert = <IN>; |
||||||
|
close IN; |
||||||
|
|
||||||
|
open(OUT, ">$tmpcacert") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't create temporary file")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT @cacert; |
||||||
|
close OUT; |
||||||
|
} |
||||||
|
|
||||||
|
unlink($opts->{'outfile'}); |
||||||
|
if($opts->{'format'} eq 'ZIP') { |
||||||
|
system($main->{'init'}->{'zipbin'}, '-j', $opts->{'outfile'}, |
||||||
|
$tmpcacert, $tmpkey, $tmpcert); |
||||||
|
my $ret = $? >> 8; |
||||||
|
} elsif ($opts->{'format'} eq 'TAR') { |
||||||
|
system($main->{'init'}->{'tarbin'}, 'cfv', $opts->{'outfile'}, |
||||||
|
$tmpcacert, $tmpkey, $tmpcert); |
||||||
|
my $ret = $? >> 8; |
||||||
|
} |
||||||
|
|
||||||
|
if(not -s $opts->{'outfile'} || $ret) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
sprintf(_("Generating %s file failed"), |
||||||
|
$opts->{'format'})); |
||||||
|
} else { |
||||||
|
$main->{'exportdir'} = HELPERS::write_export_dir($main, |
||||||
|
$opts->{'outfile'}); |
||||||
|
$t = sprintf( |
||||||
|
_("Certificate and Key successfully exported to %s"), |
||||||
|
$opts->{'outfile'}); |
||||||
|
GUI::HELPERS::print_info($t); |
||||||
|
} |
||||||
|
unlink($tmpcacert); |
||||||
|
unlink($tmpcert); |
||||||
|
unlink($tmpkey); |
||||||
|
|
||||||
|
return; |
||||||
|
|
||||||
|
} else { |
||||||
|
$t = sprintf(_("Invalid format for export requested: %s"), |
||||||
|
$opts->{'format'}); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
GUI::HELPERS::print_warning(_("Something Failed ??")); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# check if its a dsa or rsa key |
||||||
|
sub _check_key { |
||||||
|
my ($main, $file, $name) = @_; |
||||||
|
|
||||||
|
my ($t, $type); |
||||||
|
|
||||||
|
open(KEY, "<$file") || do { |
||||||
|
$t = sprintf(_("Can't open Key file: %s: %s"), |
||||||
|
$file, $!); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
while(<KEY>) { |
||||||
|
if(/RSA PRIVATE KEY/i) { |
||||||
|
$type = "RSA"; |
||||||
|
last; |
||||||
|
} elsif(/DSA PRIVATE KEY/i) { |
||||||
|
$type = "DSA"; |
||||||
|
last; |
||||||
|
} else { |
||||||
|
$type = "UNKNOWN"; |
||||||
|
} |
||||||
|
} |
||||||
|
close(KEY); |
||||||
|
|
||||||
|
if(defined($type) && $type ne "") { |
||||||
|
$name .= "%".$type; |
||||||
|
} |
||||||
|
|
||||||
|
return($name); |
||||||
|
} |
||||||
|
|
||||||
|
sub key_change_passwd { |
||||||
|
my ($self, $main, $file, $oldpass, $newpass) = @_; |
||||||
|
my $opts = {}; |
||||||
|
my ($t, $ret, $ext); |
||||||
|
|
||||||
|
my $inform = "DER"; |
||||||
|
my $outform = "PEM"; |
||||||
|
|
||||||
|
my($type); |
||||||
|
|
||||||
|
# ckeck file format |
||||||
|
open(KEY, "<$file") || do { |
||||||
|
$t = sprintf(_("Can't open Key file:\n%s"), |
||||||
|
$file); |
||||||
|
GUI::HELPERS::print_warning($t); |
||||||
|
return(1); |
||||||
|
}; |
||||||
|
while(<KEY>) { |
||||||
|
if(/BEGIN RSA PRIVATE KEY/) { |
||||||
|
$inform = "PEM"; |
||||||
|
$type = "RSA"; |
||||||
|
last; |
||||||
|
} elsif(/BEGIN RSA PRIVATE KEY/){ |
||||||
|
$inform = "PEM"; |
||||||
|
$type = "DSA"; |
||||||
|
last; |
||||||
|
} else { |
||||||
|
$type = "UNKNOWN"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
($ret, $ext) = $main->{'OpenSSL'}->convkey( |
||||||
|
'type' => $type, |
||||||
|
'inform' => $inform, |
||||||
|
'outform' => $outform, |
||||||
|
'nopass' => 0, |
||||||
|
'pass' => $newpass, |
||||||
|
'oldpass' => $oldpass, |
||||||
|
'keyfile' => $file |
||||||
|
); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
if($ret eq 1) { |
||||||
|
$t = _("Generating key failed"); |
||||||
|
|
||||||
|
if($ext =~ /unable to load Private Key/) { |
||||||
|
$t .= _("The password for your old CA Key is wrong"); |
||||||
|
} |
||||||
|
GUI::HELPERS::print_warning(($t), $ext); |
||||||
|
return($ret); |
||||||
|
} |
||||||
|
|
||||||
|
return($ret); |
||||||
|
} |
||||||
|
|
||||||
|
1 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,777 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: REQ.pm,v 1.7 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
|
||||||
|
package REQ; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $that = shift; |
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
$self->{'OpenSSL'} = shift; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# check if all data for creating a new request is available |
||||||
|
# |
||||||
|
sub get_req_create { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
my ($name, $action, $parsed, $reqfile, $keyfile, $ca, $t); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
|
||||||
|
if(!(defined($opts)) || !(ref($opts))) { |
||||||
|
if(defined($opts) && $opts eq "signserver") { |
||||||
|
$opts = {}; |
||||||
|
$opts->{'sign'} = 1; |
||||||
|
$opts->{'type'} = "server"; |
||||||
|
} elsif(defined($opts) && $opts eq "signclient") { |
||||||
|
$opts = {}; |
||||||
|
$opts->{'sign'} = 1; |
||||||
|
$opts->{'type'} = "client"; |
||||||
|
} elsif (defined($opts)) { |
||||||
|
$t = sprintf(_("Strange value for 'opts': %s"), $opts); |
||||||
|
GUI::HELPERS::print_error($t); |
||||||
|
} |
||||||
|
$opts->{'bits'} = 4096; |
||||||
|
$opts->{'digest'} = 'sha1'; |
||||||
|
$opts->{'algo'} = 'rsa'; |
||||||
|
if(defined($opts) && $opts eq "sign") { |
||||||
|
$opts->{'sign'} = 1; |
||||||
|
} |
||||||
|
|
||||||
|
$parsed = $main->{'CERT'}->parse_cert($main, 'CA'); |
||||||
|
|
||||||
|
defined($parsed) || |
||||||
|
GUI::HELPERS::print_error(_("Can't read CA certificate")); |
||||||
|
|
||||||
|
# set defaults |
||||||
|
if(defined $parsed->{'C'}) { |
||||||
|
$opts->{'C'} = $parsed->{'C'}; |
||||||
|
} |
||||||
|
if(defined $parsed->{'ST'}) { |
||||||
|
$opts->{'ST'} = $parsed->{'ST'}; |
||||||
|
} |
||||||
|
if(defined $parsed->{'L'}) { |
||||||
|
$opts->{'L'} = $parsed->{'L'}; |
||||||
|
} |
||||||
|
if(defined $parsed->{'O'}) { |
||||||
|
$opts->{'O'} = $parsed->{'O'}; |
||||||
|
} |
||||||
|
my $cc = 0; |
||||||
|
foreach my $ou (@{$parsed->{'OU'}}) { |
||||||
|
$opts->{'OU'}->[$cc++] = $ou; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_req_dialog($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'CN'})) || |
||||||
|
($opts->{'CN'} eq "") || |
||||||
|
(not defined($opts->{'passwd'})) || |
||||||
|
($opts->{'passwd'} eq "")) { |
||||||
|
$main->show_req_dialog($opts); |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Please specify at least Common Name ") |
||||||
|
._("and Password")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((not defined($opts->{'passwd2'})) || |
||||||
|
$opts->{'passwd'} ne $opts->{'passwd2'}) { |
||||||
|
$main->show_req_dialog($opts); |
||||||
|
GUI::HELPERS::print_warning(_("Passwords don't match")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'C'} = uc($opts->{'C'}); |
||||||
|
|
||||||
|
if((defined $opts->{'C'}) && |
||||||
|
($opts->{'C'} ne "") && |
||||||
|
(length($opts->{'C'}) != 2)) { |
||||||
|
$main->show_req_dialog($opts); |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Country must be exact 2 letter code")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$name = HELPERS::gen_name($opts); |
||||||
|
|
||||||
|
$opts->{'reqname'} = HELPERS::enc_base64($name); |
||||||
|
|
||||||
|
$reqfile = $main->{'CA'}->{$ca}->{'dir'}."/req/".$opts->{'reqname'}.".pem"; |
||||||
|
$keyfile = $main->{'CA'}->{$ca}->{'dir'}."/keys/".$opts->{'reqname'}.".pem"; |
||||||
|
|
||||||
|
if(-s $reqfile || -s $keyfile) { |
||||||
|
$main->show_req_overwrite_warning($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$self->create_req($main, $opts); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# create new request and key |
||||||
|
# |
||||||
|
sub create_req { |
||||||
|
my ($self, $main, $opts) = @_; |
||||||
|
|
||||||
|
my($reqfile, $keyfile, $ca, $ret, $ext, $cadir); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
$cadir = $main->{'CA'}->{$ca}->{'dir'}; |
||||||
|
|
||||||
|
$reqfile = $cadir."/req/".$opts->{'reqname'}.".pem"; |
||||||
|
$keyfile = $cadir."/keys/".$opts->{'reqname'}.".pem"; |
||||||
|
|
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->newkey( |
||||||
|
'algo' => $opts->{'algo'}, |
||||||
|
'bits' => $opts->{'bits'}, |
||||||
|
'outfile' => $keyfile, |
||||||
|
'pass' => $opts->{'passwd'} |
||||||
|
); |
||||||
|
|
||||||
|
if (not -s $keyfile || $ret) { |
||||||
|
unlink($keyfile); |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Generating key failed"), $ext); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
my @dn = ( $opts->{'C'}, $opts->{'ST'}, $opts->{'L'}, $opts->{'O'} ); |
||||||
|
if(ref($opts->{'OU'})) { |
||||||
|
foreach my $ou (@{$opts->{'OU'}}) { |
||||||
|
push(@dn,$ou); |
||||||
|
} |
||||||
|
} else { |
||||||
|
push(@dn, $opts->{'OU'}); |
||||||
|
} |
||||||
|
@dn = (@dn, $opts->{'CN'}, $opts->{'EMAIL'}, '', ''); |
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->newreq( |
||||||
|
'config' => $main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
'outfile' => $reqfile, |
||||||
|
'keyfile' => $keyfile, |
||||||
|
'digest' => $opts->{'digest'}, |
||||||
|
'pass' => $opts->{'passwd'}, |
||||||
|
'dn' => \@dn, |
||||||
|
); |
||||||
|
|
||||||
|
if (not -s $reqfile || $ret) { |
||||||
|
unlink($keyfile); |
||||||
|
unlink($reqfile); |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Generating Request failed"), $ext); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
my $parsed = $self->parse_req($main, $opts->{'reqname'}, 1); |
||||||
|
|
||||||
|
$main->{'reqbrowser'}->update($cadir."/req", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
$main->{'keybrowser'}->update($cadir."/keys", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
if($opts->{'sign'}) { |
||||||
|
$opts->{'reqfile'} = $reqfile; |
||||||
|
$opts->{'passwd'} = undef; # to sign request, ca-password is needed |
||||||
|
$self->get_sign_req($main, $opts); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get name of requestfile to delete |
||||||
|
# |
||||||
|
sub get_del_req { |
||||||
|
my ($self, $main) = @_; |
||||||
|
|
||||||
|
my($reqname, $req, $reqfile, $row, $ind, $ca, $cadir); |
||||||
|
|
||||||
|
$ca = $main->{'reqbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'reqbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
if(not(defined($reqfile))) { |
||||||
|
$req = $main->{'reqbrowser'}->selection_dn(); |
||||||
|
|
||||||
|
|
||||||
|
if(not defined($req)) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Request first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$reqname = HELPERS::enc_base64($req); |
||||||
|
$reqfile = $cadir."/req/".$reqname.".pem"; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if(not -s $reqfile) { |
||||||
|
GUI::HELPERS::print_warning(_("Request file not found")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_del_confirm($reqfile, 'req'); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# now really delete the requestfile |
||||||
|
# |
||||||
|
sub del_req { |
||||||
|
my ($self, $main, $file) = @_; |
||||||
|
|
||||||
|
my ($ca, $cadir); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
unlink($file); |
||||||
|
|
||||||
|
$ca = $main->{'reqbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'reqbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$main->{'reqbrowser'}->update($cadir."/req", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub read_reqlist { |
||||||
|
my ($self, $reqdir, $crlfile, $indexfile, $force, $main) = @_; |
||||||
|
|
||||||
|
my ($f, $modt, $d, $reqlist, $c, $p, $t); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$reqlist = []; |
||||||
|
|
||||||
|
$modt = (stat($reqdir))[9]; |
||||||
|
|
||||||
|
if(defined($self->{'lastread'}) && |
||||||
|
$self->{'lastread'} >= $modt) { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
return(0); |
||||||
|
} |
||||||
|
|
||||||
|
opendir(DIR, $reqdir) || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Can't open Request directory")); |
||||||
|
return(0); |
||||||
|
}; |
||||||
|
|
||||||
|
while($f = readdir(DIR)) { |
||||||
|
next if $f =~ /^\./; |
||||||
|
$c++; |
||||||
|
} |
||||||
|
rewinddir(DIR); |
||||||
|
|
||||||
|
$main->{'barbox'}->pack_start($main->{'progress'}, 0, 0, 0); |
||||||
|
$main->{'progress'}->show(); |
||||||
|
while($f = readdir(DIR)) { |
||||||
|
next if $f =~ /^\./; |
||||||
|
$f =~ s/\.pem//; |
||||||
|
$d = HELPERS::dec_base64($f); |
||||||
|
next if not defined($d); |
||||||
|
next if $d eq ""; |
||||||
|
push(@{$reqlist}, $d); |
||||||
|
|
||||||
|
if(defined($main)) { |
||||||
|
$t = sprintf(_(" Read Request: %s"), $d); |
||||||
|
GUI::HELPERS::set_status($main, $t); |
||||||
|
$p += 100/$c; |
||||||
|
if($p/100 <= 1) { |
||||||
|
$main->{'progress'}->set_fraction($p/100); |
||||||
|
while(Gtk2->events_pending) { |
||||||
|
Gtk2->main_iteration; |
||||||
|
} |
||||||
|
} |
||||||
|
select(undef, undef, undef, 0.025); |
||||||
|
} |
||||||
|
} |
||||||
|
@{$reqlist} = sort(@{$reqlist}); |
||||||
|
closedir(DIR); |
||||||
|
|
||||||
|
delete($self->{'reqlist'}); |
||||||
|
$self->{'reqlist'} = $reqlist; |
||||||
|
|
||||||
|
$self->{'lastread'} = time(); |
||||||
|
|
||||||
|
if(defined($main)) { |
||||||
|
$main->{'progress'}->set_fraction(0); |
||||||
|
$main->{'barbox'}->remove($main->{'progress'}); |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
} |
||||||
|
|
||||||
|
return(1); # got new list |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get name of request to sign |
||||||
|
# |
||||||
|
sub get_sign_req { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
my($time, $parsed, $ca, $cadir, $ext, $ret); |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
$time = time(); |
||||||
|
$ca = $main->{'reqbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'reqbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
if(not(defined($opts->{'reqfile'}))) { |
||||||
|
$opts->{'req'} = $main->{'reqbrowser'}->selection_dn(); |
||||||
|
|
||||||
|
if(not defined($opts->{'req'})) { |
||||||
|
GUI::HELPERS::print_info(_("Please select a Request first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'reqname'} = HELPERS::enc_base64($opts->{'req'}); |
||||||
|
$opts->{'reqfile'} = $cadir."/req/".$opts->{'reqname'}.".pem"; |
||||||
|
} |
||||||
|
|
||||||
|
if(not -s $opts->{'reqfile'}) { |
||||||
|
GUI::HELPERS::print_warning(_("Request file not found")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((-s $cadir."/certs/".$opts->{'reqname'}.".pem") && |
||||||
|
(!(defined($opts->{'overwrite'})) || ($opts->{'overwrite'} ne 'true'))) { |
||||||
|
$main->show_cert_overwrite_confirm($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$parsed = $main->{'CERT'}->parse_cert($main, 'CA'); |
||||||
|
|
||||||
|
defined($parsed) || |
||||||
|
GUI::HELPERS::print_error(_("Can't read CA certificate")); |
||||||
|
|
||||||
|
if(!defined($opts->{'passwd'})) { |
||||||
|
$opts->{'days'} = |
||||||
|
$main->{'TCONFIG'}->{$opts->{'type'}."_ca"}->{'default_days'}; |
||||||
|
|
||||||
|
if($opts->{'days'} > (($parsed->{'EXPDATE'}/86400) - ($time/86400))) { |
||||||
|
$opts->{'days'} = int(($parsed->{'EXPDATE'}/86400) - ($time/86400)); |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_req_sign_dialog($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if((($time + ($opts->{'days'} * 86400)) > $parsed->{'EXPDATE'}) && |
||||||
|
(!(defined($opts->{'ignoredate'})) || |
||||||
|
$opts->{'ignoredate'} ne 'true')){ |
||||||
|
$main->show_req_date_warning($opts); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# try to find message digest used for the request |
||||||
|
$parsed = undef; |
||||||
|
$parsed = $self->parse_req($main, $opts->{'reqname'}, 1); |
||||||
|
defined($parsed) || |
||||||
|
GUI::HELPERS::print_error(_("Can't read Request file")); |
||||||
|
|
||||||
|
if(defined($parsed->{'SIG_ALGORITHM'})) { |
||||||
|
$opts->{'digest'} = $parsed->{'SIG_ALGORITHM'}; |
||||||
|
|
||||||
|
if($opts->{'digest'} =~ /^md2/) { |
||||||
|
$opts->{'digest'} = "md2"; |
||||||
|
} elsif ($opts->{'digest'} =~ /^mdc2/) { |
||||||
|
$opts->{'digest'} = "mdc2"; |
||||||
|
} elsif ($opts->{'digest'} =~ /^md4/) { |
||||||
|
$opts->{'digest'} = "md4"; |
||||||
|
} elsif ($opts->{'digest'} =~ /^md5/) { |
||||||
|
$opts->{'digest'} = "md5"; |
||||||
|
} elsif ($opts->{'digest'} =~ /^sha1/) { |
||||||
|
$opts->{'digest'} = "sha1"; |
||||||
|
} elsif ($opts->{'digest'} =~ /^ripemd160/) { |
||||||
|
$opts->{'digest'} = "ripemd160"; |
||||||
|
} else { |
||||||
|
} |
||||||
|
} else { |
||||||
|
$opts->{'digest'} = 0; |
||||||
|
} |
||||||
|
|
||||||
|
($ret, $ext) = $self->sign_req($main, $opts); |
||||||
|
|
||||||
|
return($ret, $ext); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# now really sign the request |
||||||
|
# |
||||||
|
sub sign_req { |
||||||
|
my ($self, $main, $opts) = @_; |
||||||
|
|
||||||
|
my($serial, $certout, $certfile, $certfile2, $ca, $cadir, $ret, $t, $ext); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'reqbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'reqbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$serial = $cadir."/serial"; |
||||||
|
open(IN, "<$serial") || do { |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Can't read serial")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
$serial = <IN>; |
||||||
|
chomp($serial); |
||||||
|
close IN; |
||||||
|
|
||||||
|
if(not defined($opts->{'nsSslServerName'})) { |
||||||
|
$opts->{'nsSslServerName'} = 'none'; |
||||||
|
} |
||||||
|
if(not defined($opts->{'nsRevocationUrl'})) { |
||||||
|
$opts->{'nsRevocationUrl'} = 'none'; |
||||||
|
} |
||||||
|
if(not defined($opts->{'nsRenewalUrl'})) { |
||||||
|
$opts->{'nsRenewalUrl'} = 'none'; |
||||||
|
} |
||||||
|
if(not defined($opts->{'subjectAltName'})) { |
||||||
|
$opts->{'subjectAltName'} = 'none'; |
||||||
|
$opts->{'subjectAltNameType'} = 'none'; |
||||||
|
} else { |
||||||
|
$opts->{'subjectAltNameType'} = |
||||||
|
$main->{TCONFIG}->{$opts->{'type'}.'_cert'}->{'subjectAltNameType'}; |
||||||
|
} |
||||||
|
if(not defined($opts->{'extendedKeyUsage'})) { |
||||||
|
$opts->{'extendedKeyUsage'} = 'none'; |
||||||
|
$opts->{'extendedKeyUsageType'} = 'none'; |
||||||
|
} else { |
||||||
|
$opts->{'extendedKeyUsageType'} = |
||||||
|
$main->{TCONFIG}->{$opts->{'type'}.'_cert'}->{'extendedKeyUsageType'}; |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") { |
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->signreq( |
||||||
|
'mode' => $opts->{'mode'}, |
||||||
|
'config' => $main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
'reqfile' => $opts->{'reqfile'}, |
||||||
|
'keyfile' => $opts->{'keyfile'}, |
||||||
|
'cacertfile' => $opts->{'cacertfile'}, |
||||||
|
'outdir' => $opts->{'outdir'}, |
||||||
|
'days' => $opts->{'days'}, |
||||||
|
'parentpw' => $opts->{'parentpw'}, |
||||||
|
'caname' => "ca_ca", |
||||||
|
'revocationurl' => $opts->{'nsRevocationUrl'}, |
||||||
|
'renewalurl' => $opts->{'nsRenewalUrl'}, |
||||||
|
'subjaltname' => $opts->{'subjectAltName'}, |
||||||
|
'subjaltnametype' => $opts->{'subjectAltNameType'}, |
||||||
|
'extendedkeyusage' => $opts->{'extendedKeyUsage'}, |
||||||
|
'extendedkeyusagetype' => $opts->{'extendedKeyUsageType'}, |
||||||
|
'noemaildn' => $opts->{'noemaildn'}, |
||||||
|
'digest' => $opts->{'digest'} |
||||||
|
); |
||||||
|
} else { |
||||||
|
($ret, $ext) = $self->{'OpenSSL'}->signreq( |
||||||
|
'config' => $main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
'reqfile' => $opts->{'reqfile'}, |
||||||
|
'days' => $opts->{'days'}, |
||||||
|
'pass' => $opts->{'passwd'}, |
||||||
|
'caname' => $opts->{'type'}."_ca", |
||||||
|
'sslservername' => $opts->{'nsSslServerName'}, |
||||||
|
'revocationurl' => $opts->{'nsRevocationUrl'}, |
||||||
|
'renewalurl' => $opts->{'nsRenewalUrl'}, |
||||||
|
'subjaltname' => $opts->{'subjectAltName'}, |
||||||
|
'subjaltnametype' => $opts->{'subjectAltNameType'}, |
||||||
|
'extendedkeyusage' => $opts->{'extendedKeyUsage'}, |
||||||
|
'extendedkeyusagetype' => $opts->{'extendedKeyUsageType'}, |
||||||
|
'noemaildn' => $opts->{'noemaildn'}, |
||||||
|
'digest' => $opts->{'digest'} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
if($ret eq 1) { |
||||||
|
$t = _("Wrong CA password given\nSigning of the Request failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret eq 2) { |
||||||
|
$t = _("CA Key not found\nSigning of the Request failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret eq 3) { |
||||||
|
$t = _("Certificate already existing\nSigning of the Request failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret eq 4) { |
||||||
|
$t = _("Invalid IP Address given\nSigning of the Request failed"); |
||||||
|
GUI::HELPERS::print_warning($t, $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} elsif($ret) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Signing of the Request failed"), $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return($ret, $ext); |
||||||
|
} |
||||||
|
|
||||||
|
if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") { |
||||||
|
$certout = $cadir."/newcerts/".$serial.".pem"; |
||||||
|
$certfile = $opts->{'outfile'}; |
||||||
|
$certfile2 = $cadir."/certs/".$opts->{'reqname'}.".pem"; |
||||||
|
} else { |
||||||
|
$certout = $cadir."/newcerts/".$serial.".pem"; |
||||||
|
$certfile = $cadir."/certs/".$opts->{'reqname'}.".pem"; |
||||||
|
#print STDERR "DEBUG: write certificate to: ".$cadir."/certs/".$opts->{'reqname'}.".pem"; |
||||||
|
} |
||||||
|
|
||||||
|
if (not -s $certout) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Signing of the Request failed"), $ext); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
open(IN, "<$certout") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't read Certificate file")); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
}; |
||||||
|
open(OUT, ">$certfile") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't write Certificate file")); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT while(<IN>); |
||||||
|
|
||||||
|
if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") { |
||||||
|
close OUT; |
||||||
|
open(OUT, ">$certfile2") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't write Certificate file")); |
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
return; |
||||||
|
}; |
||||||
|
seek(IN, 0, 0); |
||||||
|
print OUT while(<IN>); |
||||||
|
} |
||||||
|
|
||||||
|
close IN; close OUT; |
||||||
|
|
||||||
|
GUI::HELPERS::print_info( |
||||||
|
_("Request signed succesfully.\nCertificate created"), $ext); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$main->{'CERT'}->reread_cert($main, |
||||||
|
HELPERS::dec_base64($opts->{'reqname'})); |
||||||
|
|
||||||
|
$main->{'certbrowser'}->update($cadir."/certs", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
delete($opts->{$_}) foreach(keys(%$opts)); |
||||||
|
$opts = undef; |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return($ret, $ext); |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# get informations/verifications to import request from file |
||||||
|
# |
||||||
|
sub get_import_req { |
||||||
|
my ($self, $main, $opts, $box) = @_; |
||||||
|
|
||||||
|
my ($ret, $ext, $der); |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
my($ca, $parsed, $file, $format); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
|
||||||
|
if(not defined($opts)) { |
||||||
|
$main->show_req_import_dialog(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if(not defined($opts->{'infile'})) { |
||||||
|
$main->show_req_import_dialog(); |
||||||
|
GUI::HELPERS::print_warning(_("Please select a Request file first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
if(not -s $opts->{'infile'}) { |
||||||
|
$main->show_req_import_dialog(); |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Can't find Request file: ").$opts->{'infile'}); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
open(IN, "<$opts->{'infile'}") || do { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Can't read Request file:").$opts->{'infile'}); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
$opts->{'in'} .= $_ while(<IN>); |
||||||
|
|
||||||
|
if($opts->{'in'} =~ /-BEGIN[\s\w]+CERTIFICATE REQUEST-/i) { |
||||||
|
$format = "PEM"; |
||||||
|
$file = $opts->{'infile'}; |
||||||
|
} else { |
||||||
|
$format = "DER"; |
||||||
|
} |
||||||
|
|
||||||
|
if($format eq "DER") { |
||||||
|
($ret, $der, $ext) = $opts->{'in'} = $self->{'OpenSSL'}->convdata( |
||||||
|
'cmd' => 'req', |
||||||
|
'data' => $opts->{'in'}, |
||||||
|
'inform' => 'DER', |
||||||
|
'outform' => 'PEM' |
||||||
|
); |
||||||
|
|
||||||
|
if($ret) { |
||||||
|
GUI::HELPERS::print_warning( |
||||||
|
_("Error converting Request"), $ext); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$opts->{'tmpfile'} = |
||||||
|
HELPERS::mktmp($self->{'OpenSSL'}->{'tmp'}."/import"); |
||||||
|
|
||||||
|
open(TMP, ">$opts->{'tmpfile'}") || do { |
||||||
|
GUI::HELPERS::print_warning( _("Can't create temporary file: %s: %s"), |
||||||
|
$opts->{'tmpfile'}, $!); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print TMP $opts->{'in'}; |
||||||
|
close(TMP); |
||||||
|
$file = $opts->{'tmpfile'}; |
||||||
|
} |
||||||
|
|
||||||
|
$parsed = $self->{'OpenSSL'}->parsereq( |
||||||
|
$main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
$file); |
||||||
|
|
||||||
|
if(not defined($parsed)) { |
||||||
|
unlink($opts->{'tmpfile'}); |
||||||
|
GUI::HELPERS::print_warning(_("Parsing Request failed")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$main->show_import_verification("req", $opts, $parsed); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
# |
||||||
|
# import request |
||||||
|
# |
||||||
|
sub import_req { |
||||||
|
my ($self, $main, $opts, $parsed, $box) = @_; |
||||||
|
|
||||||
|
my ($ca, $cadir); |
||||||
|
|
||||||
|
$box->destroy() if(defined($box)); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'reqbrowser'}->selection_caname(); |
||||||
|
$cadir = $main->{'reqbrowser'}->selection_cadir(); |
||||||
|
|
||||||
|
$opts->{'name'} = HELPERS::gen_name($parsed); |
||||||
|
|
||||||
|
$opts->{'reqname'} = HELPERS::enc_base64($opts->{'name'}); |
||||||
|
|
||||||
|
$opts->{'reqfile'} = $cadir."/req/".$opts->{'reqname'}.".pem"; |
||||||
|
|
||||||
|
open(OUT, ">$opts->{'reqfile'}") || do { |
||||||
|
unlink($opts->{'tmpfile'}); |
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
GUI::HELPERS::print_warning(_("Can't open output file: %s: %s"), |
||||||
|
$opts->{'reqfile'}, $!); |
||||||
|
return; |
||||||
|
}; |
||||||
|
print OUT $opts->{'in'}; |
||||||
|
close OUT; |
||||||
|
|
||||||
|
$main->{'reqbrowser'}->update($cadir."/req", |
||||||
|
$cadir."/crl/crl.pem", |
||||||
|
$cadir."/index.txt", |
||||||
|
0); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub parse_req { |
||||||
|
my ($self, $main, $name, $force) = @_; |
||||||
|
|
||||||
|
my ($parsed, $ca, $reqfile, $req); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 1); |
||||||
|
|
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
|
||||||
|
$reqfile = $main->{'CA'}->{$ca}->{'dir'}."/req/".$name.".pem"; |
||||||
|
|
||||||
|
$parsed = $self->{'OpenSSL'}->parsereq($main->{'CA'}->{$ca}->{'cnf'}, |
||||||
|
$reqfile, $force); |
||||||
|
|
||||||
|
GUI::HELPERS::set_cursor($main, 0); |
||||||
|
|
||||||
|
return($parsed); |
||||||
|
} |
||||||
|
|
||||||
|
1 |
||||||
|
|
@ -0,0 +1,555 @@ |
|||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# $Id: TCONFIG.pm,v 1.2 2006/06/28 21:50:42 sm Exp $ |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
use strict; |
||||||
|
|
||||||
|
package TCONFIG; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
|
||||||
|
sub new { |
||||||
|
my $self = {}; |
||||||
|
my $that = shift; |
||||||
|
my $class = ref($that) || $that; |
||||||
|
|
||||||
|
bless($self, $class); |
||||||
|
} |
||||||
|
|
||||||
|
sub init_config { |
||||||
|
my ($self, $main, $ca) = @_; |
||||||
|
|
||||||
|
my($file, @lines, $i, $section, $l, $k, $v); |
||||||
|
|
||||||
|
if(not defined($ca)) { |
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
} |
||||||
|
if(not defined($ca)) { |
||||||
|
GUI::HELPERS::print_warning(_("Please select a CA first")); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$file = $main->{'CA'}->{$ca}->{'cnf'}; |
||||||
|
|
||||||
|
open(IN, "<$file") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't open configuration")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
@lines = <IN>; |
||||||
|
close IN; |
||||||
|
chomp(@lines); |
||||||
|
|
||||||
|
# clean old configuration |
||||||
|
foreach $k (keys(%$self)) { |
||||||
|
delete($self->{$k}); |
||||||
|
} |
||||||
|
|
||||||
|
foreach $l (@lines) { |
||||||
|
next if $l =~ /^#/; |
||||||
|
next if $l =~ /^$/; |
||||||
|
next if $l =~ /^ *$/; |
||||||
|
|
||||||
|
# find section |
||||||
|
if($l =~ /\[\s*([^\s]+)\s*\]/) { |
||||||
|
$section = $1; |
||||||
|
} elsif ($l =~ /^([^\s\t]+)[\s\t]*=[\s\t]*([^\s\t]+.*)$/) { |
||||||
|
if($section eq "ca" || |
||||||
|
$section eq "policy_client" || |
||||||
|
$section eq "policy_server" || |
||||||
|
$section eq "policy_ca" || |
||||||
|
$section eq "req" || |
||||||
|
$section eq "req_distinguished_name" || |
||||||
|
$section eq "v3_req" || |
||||||
|
$section eq "req_attributes") { |
||||||
|
if(not defined($self->{$section})) { |
||||||
|
$self->{$section} = []; |
||||||
|
} |
||||||
|
push(@{$self->{$section}}, $l); |
||||||
|
} else { |
||||||
|
$k = $1; |
||||||
|
$v = $2; |
||||||
|
# really ugly hack XXX |
||||||
|
if($v =~ /ENV::(\w+)$/) { |
||||||
|
$ENV{$1} = 'dummy'; |
||||||
|
} |
||||||
|
if(not defined($self->{$section})) { |
||||||
|
$self->{$section} = {}; |
||||||
|
} |
||||||
|
$self->{$section}->{$k} = $v; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# store nsSslServerName information |
||||||
|
if(defined($self->{'server_cert'}->{'nsSslServerName'})) { |
||||||
|
if($self->{'server_cert'}->{'nsSslServerName'} |
||||||
|
=~ /ENV:/) { |
||||||
|
$self->{'server_cert'}->{'nsSslServerName'} = 'user'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{'server_cert'}->{'nsSslServerName'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
# store subjectAltName information |
||||||
|
# ca |
||||||
|
if(defined($self->{'v3_ca'}->{'subjectAltName'})) { |
||||||
|
if($self->{'v3_ca'}->{'subjectAltName'} eq 'email:copy') { |
||||||
|
$self->{'v3_ca'}->{'subjectAltName'} = 'emailcopy'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{'v3_ca'}->{'subjectAltName'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
# server |
||||||
|
if(defined($self->{'server_cert'}->{'subjectAltName'})) { |
||||||
|
if($self->{'server_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*IP/) { |
||||||
|
$self->{'server_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
$self->{'server_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'server_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*DNS/) { |
||||||
|
$self->{'server_cert'}->{'subjectAltNameType'} = 'dns'; |
||||||
|
$self->{'server_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'server_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*RAW/) { |
||||||
|
$self->{'server_cert'}->{'subjectAltNameType'} = 'raw'; |
||||||
|
$self->{'server_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'server_cert'}->{'subjectAltName'} |
||||||
|
eq 'email:copy') { |
||||||
|
$self->{'server_cert'}->{'subjectAltName'} = 'emailcopy'; |
||||||
|
$self->{'server_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{'server_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
$self->{'server_cert'}->{'subjectAltName'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
# client |
||||||
|
if(defined($self->{'client_cert'}->{'subjectAltName'})) { |
||||||
|
if($self->{'client_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*IP/) { |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'client_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*DNS/) { |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'dns'; |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'client_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*EMAIL/) { |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'mail'; |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'client_cert'}->{'subjectAltName'} |
||||||
|
=~ /ENV:.*RAW/) { |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'raw'; |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'user'; |
||||||
|
}elsif($self->{'client_cert'}->{'subjectAltName'} |
||||||
|
eq 'email:copy') { |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'emailcopy'; |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{'client_cert'}->{'subjectAltNameType'} = 'ip'; |
||||||
|
$self->{'client_cert'}->{'subjectAltName'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
foreach my $sect ('server_cert', 'client_cert', 'v3_ca') { |
||||||
|
# store nsRevocationUrl information |
||||||
|
if(defined($self->{$sect}->{'nsRevocationUrl'})) { |
||||||
|
if($self->{$sect}->{'nsRevocationUrl'} |
||||||
|
=~ /ENV:/) { |
||||||
|
$self->{$sect}->{'nsRevocationUrl'} = 'user'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'nsRevocationUrl'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
# store nsRenewalUrl information |
||||||
|
if(defined($self->{$sect}->{'nsRenewalUrl'})) { |
||||||
|
if($self->{$sect}->{'nsRenewalUrl'} |
||||||
|
=~ /ENV:/) { |
||||||
|
$self->{$sect}->{'nsRenewalUrl'} = 'user'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'nsRenewalUrl'} = 'none'; |
||||||
|
} |
||||||
|
|
||||||
|
# store extendedKeyUsage information |
||||||
|
if(defined($self->{$sect}->{'extendedKeyUsage'})) { |
||||||
|
if($self->{$sect}->{'extendedKeyUsage'} =~ /critical/) { |
||||||
|
$self->{$sect}->{'extendedKeyUsageType'} = 'critical'; |
||||||
|
$self->{$sect}->{'extendedKeyUsage'} =~ s/critical\s*,\s*//; |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'extendedKeyUsageType'} = 'noncritical'; |
||||||
|
} |
||||||
|
if($self->{$sect}->{'extendedKeyUsage'} |
||||||
|
=~ /ENV:/) { |
||||||
|
$self->{$sect}->{'extendedKeyUsage'} = 'user'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'extendedKeyUsage'} = 'none'; |
||||||
|
$self->{$sect}->{'extendedKeyUsageType'} = 'noncritical'; |
||||||
|
} |
||||||
|
|
||||||
|
# store keyUsage information |
||||||
|
if(defined($self->{$sect}->{'keyUsage'})) { |
||||||
|
if($self->{$sect}->{'keyUsage'} =~ /critical/) { |
||||||
|
$self->{$sect}->{'keyUsageType'} = 'critical'; |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'keyUsageType'} = 'noncritical'; |
||||||
|
} |
||||||
|
if($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /digitalSignature, keyEncipherment/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'keysig'; |
||||||
|
} elsif($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /digitalSignature/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'sig'; |
||||||
|
} elsif($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /keyEncipherment/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'key'; |
||||||
|
} elsif($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /keyCertSign, cRLSign/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'keyCertSign, cRLSign'; |
||||||
|
} elsif($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /keyCertSign/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'keyCertSign'; |
||||||
|
} elsif($self->{$sect}->{'keyUsage'} |
||||||
|
=~ /cRLSign/) { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'cRLSign'; |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'none'; |
||||||
|
} |
||||||
|
}else { |
||||||
|
$self->{$sect}->{'keyUsage'} = 'none'; |
||||||
|
$self->{$sect}->{'keyUsageType'} = 'noncritical'; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# hack to add new section to openssl.cnf, if old config |
||||||
|
if(not defined($self->{'ca_ca'})) { |
||||||
|
$self->{'ca_ca'} = $self->{'server_ca'}; |
||||||
|
$self->{'ca_ca'}->{'x509_extensions'} = "v3_ca"; |
||||||
|
$self->{'server_ca'}->{'x509_extensions'} = "server_cert"; |
||||||
|
|
||||||
|
$self->write_config($main, $ca); |
||||||
|
} |
||||||
|
if($self->{'server_ca'}->{'x509_extensions'} eq "v3_ca") { |
||||||
|
$self->{'server_ca'}->{'x509_extensions'} = "server_cert"; |
||||||
|
$self->write_config($main, $ca); |
||||||
|
} |
||||||
|
|
||||||
|
# hack to add new option |
||||||
|
if(not defined($self->{'ca_ca'}->{'unique_subject'})) { |
||||||
|
$self->{'ca_ca'}->{'unique_subject'} = "yes"; |
||||||
|
|
||||||
|
$self->write_config($main, $ca); |
||||||
|
} |
||||||
|
if(not defined($self->{'server_ca'}->{'unique_subject'})) { |
||||||
|
$self->{'server_ca'}->{'unique_subject'} = "yes"; |
||||||
|
|
||||||
|
$self->write_config($main, $ca); |
||||||
|
} |
||||||
|
if(not defined($self->{'client_ca'}->{'unique_subject'})) { |
||||||
|
$self->{'client_ca'}->{'unique_subject'} = "yes"; |
||||||
|
|
||||||
|
$self->write_config($main, $ca); |
||||||
|
} |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub config_ca { |
||||||
|
my ($self, $main, $ca) = @_; |
||||||
|
|
||||||
|
my($action); |
||||||
|
|
||||||
|
if(not defined($ca)) { |
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
} |
||||||
|
if(not defined($ca)) { |
||||||
|
GUI::HELPERS::print_warning(_("Can't get CA name")); |
||||||
|
} |
||||||
|
|
||||||
|
$action = GUI::TCONFIG::show_config_ca($main, $ca); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub config_openssl { |
||||||
|
my ($self, $main, $ca) = @_; |
||||||
|
|
||||||
|
if(not defined($ca)) { |
||||||
|
$ca = $main->{'CA'}->{'actca'}; |
||||||
|
} |
||||||
|
if(not defined($ca)) { |
||||||
|
GUI::HELPERS::print_warning(_("Can't get CA name")); |
||||||
|
} |
||||||
|
|
||||||
|
GUI::TCONFIG::show_configbox($main, $ca); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
sub write_config { |
||||||
|
my ($self, $main, $ca) = @_; |
||||||
|
|
||||||
|
my($file, @sections, $line, $sect, $key, $val, @opts); |
||||||
|
|
||||||
|
# these sections are not configurable |
||||||
|
@sections = qw( |
||||||
|
ca |
||||||
|
policy_client |
||||||
|
policy_server |
||||||
|
policy_ca |
||||||
|
req |
||||||
|
req_distinguished_name |
||||||
|
v3_req |
||||||
|
req_attributes |
||||||
|
); |
||||||
|
|
||||||
|
$file = $main->{'CA'}->{$ca}->{'cnf'}; |
||||||
|
|
||||||
|
open(OUT, ">$file") || do { |
||||||
|
GUI::HELPERS::print_warning(_("Can't open configfile")); |
||||||
|
return; |
||||||
|
}; |
||||||
|
|
||||||
|
foreach $sect (@sections) { |
||||||
|
print OUT "[ $sect ]\n"; |
||||||
|
foreach $line (@{$self->{$sect}}) { |
||||||
|
print OUT "$line\n"; |
||||||
|
} |
||||||
|
print OUT "\n"; |
||||||
|
} |
||||||
|
|
||||||
|
# these sections are configurable |
||||||
|
@sections = qw( |
||||||
|
v3_ca |
||||||
|
crl_ext |
||||||
|
server_ca |
||||||
|
client_ca |
||||||
|
ca_ca |
||||||
|
client_cert |
||||||
|
server_cert |
||||||
|
); |
||||||
|
|
||||||
|
foreach $sect (@sections) { |
||||||
|
print OUT "[ $sect ]\n"; |
||||||
|
if($sect eq "v3_ca") { |
||||||
|
@opts = qw( |
||||||
|
subjectKeyIdentifier |
||||||
|
authorityKeyIdentifier |
||||||
|
basicConstraints |
||||||
|
nsCertType |
||||||
|
issuerAltName |
||||||
|
nsComment |
||||||
|
crlDistributionPoints |
||||||
|
nsCaRevocationUrl |
||||||
|
nsCaPolicyUrl |
||||||
|
nsRevocationUrl |
||||||
|
nsRenewalUrl |
||||||
|
); |
||||||
|
|
||||||
|
foreach $key (@opts) { |
||||||
|
if(defined($self->{$sect}->{$key}) && |
||||||
|
$self->{$sect}->{$key} ne '' && |
||||||
|
$self->{$sect}->{$key} ne 'none') { |
||||||
|
print OUT "$key = $self->{$sect}->{$key}\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'subjectAltName'})) { |
||||||
|
if($self->{$sect}->{'subjectAltName'} eq 'emailcopy') { |
||||||
|
print OUT "subjectAltName = email:copy\n"; |
||||||
|
} elsif($self->{$sect}->{'subjectAltName'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'keyUsage'})) { |
||||||
|
if($self->{$sect}->{'keyUsage'} eq 'keyCertSign') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, keyCertSign\n"; |
||||||
|
} else { |
||||||
|
print OUT "keyUsage = keyCertSign\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'cRLSign') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, cRLSign\n"; |
||||||
|
}else { |
||||||
|
print OUT "keyUsage = cRLSign\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'keyCertSign, cRLSign') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, keyCertSign, cRLSign\n"; |
||||||
|
}else { |
||||||
|
print OUT "keyUsage = keyCertSign, cRLSign\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
} elsif($sect eq "server_cert" || |
||||||
|
$sect eq "client_cert") { |
||||||
|
@opts = qw( |
||||||
|
basicConstraints |
||||||
|
nsCertType |
||||||
|
nsComment |
||||||
|
subjectKeyIdentifier |
||||||
|
authorityKeyIdentifier |
||||||
|
issuerAltName |
||||||
|
crlDistributionPoints |
||||||
|
nsCaRevocationUrl |
||||||
|
nsBaseUrl |
||||||
|
nsCaPolicyUrl |
||||||
|
); |
||||||
|
|
||||||
|
foreach $key (@opts) { |
||||||
|
if(defined($self->{$sect}->{$key}) && |
||||||
|
$self->{$sect}->{$key} ne '' && |
||||||
|
$self->{$sect}->{$key} ne 'none') { |
||||||
|
print OUT "$key = $self->{$sect}->{$key}\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'nsSslServerName'})) { |
||||||
|
if($self->{$sect}->{'nsSslServerName'} eq 'user') { |
||||||
|
print OUT "nsSslServerName = \$ENV::NSSSLSERVERNAME\n"; |
||||||
|
} elsif($self->{$sect}->{'nsSslServerName'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'nsRevocationUrl'})) { |
||||||
|
if($self->{$sect}->{'nsRevocationUrl'} eq 'user') { |
||||||
|
print OUT "nsRevocationUrl = \$ENV::NSREVOCATIONURL\n"; |
||||||
|
} elsif($self->{$sect}->{'nsRevocationUrl'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'nsRenewalUrl'})) { |
||||||
|
if($self->{$sect}->{'nsRenewalUrl'} eq 'user') { |
||||||
|
print OUT "nsRenewalUrl = \$ENV::NSRENEWALURL\n"; |
||||||
|
} elsif($self->{$sect}->{'nsRenewalUrl'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'subjectAltName'})) { |
||||||
|
if($self->{$sect}->{'subjectAltName'} eq 'user') { |
||||||
|
if($self->{$sect}->{'subjectAltNameType'} eq 'ip') { |
||||||
|
print OUT "subjectAltName = \$ENV::SUBJECTALTNAMEIP\n"; |
||||||
|
} elsif($self->{$sect}->{'subjectAltNameType'} eq 'dns') { |
||||||
|
print OUT "subjectAltName = \$ENV::SUBJECTALTNAMEDNS\n"; |
||||||
|
} elsif($self->{$sect}->{'subjectAltNameType'} eq 'mail') { |
||||||
|
print OUT "subjectAltName = \$ENV::SUBJECTALTNAMEEMAIL\n"; |
||||||
|
} elsif($self->{$sect}->{'subjectAltNameType'} eq 'raw') { |
||||||
|
print OUT "subjectAltName = \$ENV::SUBJECTALTNAMERAW\n"; |
||||||
|
} |
||||||
|
} elsif($self->{$sect}->{'subjectAltName'} eq 'emailcopy') { |
||||||
|
print OUT "subjectAltName = email:copy\n"; |
||||||
|
} elsif($self->{$sect}->{'subjectAltName'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'keyUsage'})) { |
||||||
|
if($self->{$sect}->{'keyUsage'} eq 'key') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, keyEncipherment\n"; |
||||||
|
} else { |
||||||
|
print OUT "keyUsage = keyEncipherment\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'sig') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, digitalSignature\n"; |
||||||
|
}else { |
||||||
|
print OUT "keyUsage = digitalSignature\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'keysig') { |
||||||
|
if($self->{$sect}->{'keyUsageType'} eq 'critical') { |
||||||
|
print OUT "keyUsage = critical, digitalSignature, keyEncipherment\n"; |
||||||
|
}else { |
||||||
|
print OUT "keyUsage = digitalSignature, keyEncipherment\n"; |
||||||
|
} |
||||||
|
}elsif($self->{$sect}->{'keyUsage'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
if(defined($self->{$sect}->{'extendedKeyUsage'})) { |
||||||
|
if(($self->{$sect}->{'extendedKeyUsage'} ne 'none') && |
||||||
|
($self->{$sect}->{'extendedKeyUsage'} ne '')) { |
||||||
|
if($self->{$sect}->{'extendedKeyUsage'} eq 'user') { |
||||||
|
if($self->{$sect}->{'extendedKeyUsageType'} eq 'critical') { |
||||||
|
print OUT "extendedKeyUsage = critical, \$ENV::EXTENDEDKEYUSAGE\n"; |
||||||
|
} else { |
||||||
|
print OUT "extendedKeyUsage = \$ENV::EXTENDEDKEYUSAGE\n"; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if($self->{$sect}->{'extendedKeyUsageType'} eq 'critical') { |
||||||
|
print OUT "extendedKeyUsage = critical, $self->{$sect}->{'extendedKeyUsage'}\n"; |
||||||
|
} else { |
||||||
|
print OUT "extendedKeyUsage = $self->{$sect}->{'extendedKeyUsage'}\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
} elsif ($self->{$sect}->{'extendedKeyUsage'} eq 'none') { |
||||||
|
;# do nothing |
||||||
|
} |
||||||
|
} |
||||||
|
} elsif(($sect eq "server_ca") || |
||||||
|
($sect eq "client_ca") || |
||||||
|
($sect eq "ca_ca")) { |
||||||
|
@opts = qw( |
||||||
|
dir |
||||||
|
certs |
||||||
|
crl_dir |
||||||
|
database |
||||||
|
new_certs_dir |
||||||
|
certificate |
||||||
|
serial |
||||||
|
crl |
||||||
|
private_key |
||||||
|
RANDFILE |
||||||
|
x509_extensions |
||||||
|
default_days |
||||||
|
default_crl_days |
||||||
|
default_md |
||||||
|
preserve |
||||||
|
policy |
||||||
|
unique_subject |
||||||
|
); |
||||||
|
|
||||||
|
foreach $key (@opts) { |
||||||
|
if(defined($self->{$sect}->{$key}) && |
||||||
|
$self->{$sect}->{$key} ne '' && |
||||||
|
$self->{$sect}->{$key} ne 'none') { |
||||||
|
print OUT "$key = $self->{$sect}->{$key}\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
} else { |
||||||
|
while(($key, $val) = each(%{$self->{$sect}})) { |
||||||
|
if(defined($val) && $val ne "") { |
||||||
|
print OUT "$key = $val\n"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
print OUT "\n"; |
||||||
|
} |
||||||
|
|
||||||
|
close OUT; |
||||||
|
|
||||||
|
# print STDERR "DEBUG: wrote config and reinit\n"; |
||||||
|
# $self->init_config($main, $ca); |
||||||
|
|
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
1 |
@ -0,0 +1,25 @@ |
|||||||
|
POTFILES=$(wildcard ../lib/*.pm) $(wildcard ../lib/GUI/*.pm) ../tinyca2
|
||||||
|
CATALOGS=de.mo es.mo cs.mo fr.mo sv.mo
|
||||||
|
|
||||||
|
all: $(CATALOGS) |
||||||
|
|
||||||
|
.po.mo: |
||||||
|
msgfmt -o $@ $<
|
||||||
|
install -m 644 $@ ../locale/`basename $@ .mo`/LC_MESSAGES/tinyca2.mo
|
||||||
|
|
||||||
|
%.po: tinyca2.pot |
||||||
|
msgmerge -vU $@ tinyca2.pot
|
||||||
|
|
||||||
|
tinyca2.pot: $(POTFILES) |
||||||
|
xgettext --add-comments \
|
||||||
|
--keyword=_ \
|
||||||
|
--keyword=N_ \
|
||||||
|
--language=C \
|
||||||
|
-o tinyca2.pot \
|
||||||
|
$(POTFILES); \
|
||||||
|
|
||||||
|
clean: |
||||||
|
rm -f $(CATALOGS)
|
||||||
|
rm -f tinyca2.pot
|
||||||
|
|
||||||
|
.SUFFIXES: .po .pot .mo |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,147 @@ |
|||||||
|
[ ca ] |
||||||
|
default_ca = server_ca |
||||||
|
|
||||||
|
[ client_ca ] |
||||||
|
dir = %dir% |
||||||
|
certs = $dir/certs |
||||||
|
crl_dir = $dir/crl |
||||||
|
database = $dir/index.txt |
||||||
|
new_certs_dir = $dir/newcerts |
||||||
|
certificate = $dir/cacert.pem |
||||||
|
serial = $dir/serial |
||||||
|
crl = $dir/crl.pem |
||||||
|
private_key = $dir/cacert.key |
||||||
|
RANDFILE = $dir/.rand |
||||||
|
x509_extensions = client_cert |
||||||
|
default_days = 365 |
||||||
|
default_crl_days= 30 |
||||||
|
default_md = sha1 |
||||||
|
preserve = no |
||||||
|
policy = policy_client |
||||||
|
|
||||||
|
[ server_ca ] |
||||||
|
dir = %dir% |
||||||
|
certs = $dir/certs |
||||||
|
crl_dir = $dir/crl |
||||||
|
database = $dir/index.txt |
||||||
|
new_certs_dir = $dir/newcerts |
||||||
|
certificate = $dir/cacert.pem |
||||||
|
serial = $dir/serial |
||||||
|
crl = $dir/crl.pem |
||||||
|
private_key = $dir/cacert.key |
||||||
|
RANDFILE = $dir/.rand |
||||||
|
x509_extensions = server_cert |
||||||
|
default_days = 365 |
||||||
|
default_crl_days= 30 |
||||||
|
default_md = sha1 |
||||||
|
preserve = no |
||||||
|
policy = policy_server |
||||||
|
|
||||||
|
[ ca_ca ] |
||||||
|
dir = %dir% |
||||||
|
certs = $dir/certs |
||||||
|
crl_dir = $dir/crl |
||||||
|
database = $dir/index.txt |
||||||
|
new_certs_dir = $dir/newcerts |
||||||
|
certificate = $dir/cacert.pem |
||||||
|
serial = $dir/serial |
||||||
|
crl = $dir/crl.pem |
||||||
|
private_key = $dir/cacert.key |
||||||
|
RANDFILE = $dir/.rand |
||||||
|
x509_extensions = v3_ca |
||||||
|
default_days = 365 |
||||||
|
default_crl_days= 30 |
||||||
|
default_md = sha1 |
||||||
|
preserve = no |
||||||
|
policy = policy_ca |
||||||
|
|
||||||
|
[ policy_client ] |
||||||
|
countryName = optional |
||||||
|
stateOrProvinceName = optional |
||||||
|
organizationName = optional |
||||||
|
organizationalUnitName = optional |
||||||
|
commonName = supplied |
||||||
|
emailAddress = optional |
||||||
|
|
||||||
|
[ policy_server ] |
||||||
|
countryName = optional |
||||||
|
stateOrProvinceName = optional |
||||||
|
organizationName = optional |
||||||
|
organizationalUnitName = optional |
||||||
|
commonName = supplied |
||||||
|
emailAddress = optional |
||||||
|
|
||||||
|
[ policy_ca ] |
||||||
|
countryName = optional |
||||||
|
stateOrProvinceName = optional |
||||||
|
organizationName = optional |
||||||
|
organizationalUnitName = optional |
||||||
|
commonName = supplied |
||||||
|
emailAddress = optional |
||||||
|
|
||||||
|
[ req ] |
||||||
|
default_bits = 4096 |
||||||
|
default_keyfile = privkey.pem |
||||||
|
distinguished_name = req_distinguished_name |
||||||
|
attributes = req_attributes |
||||||
|
x509_extensions = v3_ca |
||||||
|
string_mask = nombstr |
||||||
|
req_extensions = v3_req |
||||||
|
|
||||||
|
[ req_distinguished_name ] |
||||||
|
countryName = Country Name (2 letter code) |
||||||
|
countryName_default = AU |
||||||
|
countryName_min = 2 |
||||||
|
countryName_max = 2 |
||||||
|
stateOrProvinceName = State or Province Name (full name) |
||||||
|
stateOrProvinceName_default = Some-State |
||||||
|
localityName = Locality Name (eg, city) |
||||||
|
0.organizationName = Organization Name (eg, company) |
||||||
|
0.organizationName_default = Internet Widgits Pty Ltd |
||||||
|
organizationalUnitName = Organizational Unit Name (eg, section) |
||||||
|
commonName = Common Name (eg, YOUR name) |
||||||
|
commonName_max = 64 |
||||||
|
emailAddress = Email Address |
||||||
|
emailAddress_max = 40 |
||||||
|
|
||||||
|
[ v3_req ] |
||||||
|
basicConstraints = CA:FALSE |
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment |
||||||
|
|
||||||
|
[ req_attributes ] |
||||||
|
challengePassword = A challenge password |
||||||
|
challengePassword_min = 4 |
||||||
|
challengePassword_max = 20 |
||||||
|
unstructuredName = An optional company name |
||||||
|
|
||||||
|
[ client_cert ] |
||||||
|
basicConstraints=CA:FALSE |
||||||
|
nsCertType = client, email, objsign |
||||||
|
nsComment = "TinyCA Generated Certificate" |
||||||
|
keyUsage = nonRepudiation, digitalSignature, keyEncipherment |
||||||
|
subjectKeyIdentifier=hash |
||||||
|
authorityKeyIdentifier=keyid,issuer:always |
||||||
|
subjectAltName=email:copy |
||||||
|
issuerAltName=issuer:copy |
||||||
|
|
||||||
|
[ server_cert ] |
||||||
|
basicConstraints=CA:FALSE |
||||||
|
nsCertType = server |
||||||
|
nsComment = "TinyCA Generated Certificate" |
||||||
|
subjectKeyIdentifier=hash |
||||||
|
authorityKeyIdentifier=keyid,issuer:always |
||||||
|
subjectAltName=email:copy |
||||||
|
issuerAltName=issuer:copy |
||||||
|
|
||||||
|
[ v3_ca ] |
||||||
|
nsComment = "TinyCA Generated Certificate" |
||||||
|
subjectKeyIdentifier=hash |
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always |
||||||
|
basicConstraints = critical,CA:true |
||||||
|
keyUsage = keyCertSign, cRLSign |
||||||
|
nsCertType = sslCA, emailCA |
||||||
|
subjectAltName=email:copy |
||||||
|
issuerAltName=issuer:copy |
||||||
|
|
||||||
|
[ crl_ext ] |
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always |
@ -0,0 +1,115 @@ |
|||||||
|
#!/usr/bin/perl -w |
||||||
|
# |
||||||
|
# $Id: tinyca2,v 1.6 2006/07/04 19:53:16 sm Exp $ |
||||||
|
# |
||||||
|
# Copyright (c) Stephan Martin <sm@sm-zone.net> |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. |
||||||
|
|
||||||
|
BEGIN { unshift(@INC, './lib'); # put here the location of the modules |
||||||
|
} |
||||||
|
|
||||||
|
use strict; |
||||||
|
|
||||||
|
use Gtk2 '-init'; |
||||||
|
|
||||||
|
use MIME::Base64; |
||||||
|
|
||||||
|
use POSIX; |
||||||
|
use Locale::gettext; |
||||||
|
|
||||||
|
use OpenSSL; |
||||||
|
use CA; |
||||||
|
use GUI; |
||||||
|
use HELPERS; |
||||||
|
use GUI::TCONFIG; |
||||||
|
use GUI::HELPERS; |
||||||
|
use GUI::CALLBACK; |
||||||
|
use GUI::WORDS; |
||||||
|
use GUI::X509_infobox; |
||||||
|
use GUI::X509_browser; |
||||||
|
use CERT; |
||||||
|
use REQ; |
||||||
|
use KEY; |
||||||
|
use TCONFIG; |
||||||
|
|
||||||
|
setlocale(LC_MESSAGES, ""); |
||||||
|
bindtextdomain("tinyca2", "./locale/"); |
||||||
|
textdomain("tinyca2"); |
||||||
|
|
||||||
|
# https://bugs.gentoo.org/show_bug.cgi?id=78576 |
||||||
|
$ENV{XLIB_SKIP_ARGB_VISUALS}= '1'; |
||||||
|
|
||||||
|
my $init = {}; |
||||||
|
|
||||||
|
# location of openssl |
||||||
|
$init->{'opensslbin'} = "/usr/bin/openssl"; |
||||||
|
$init->{'zipbin'} = "/usr/bin/zip"; |
||||||
|
$init->{'tarbin'} = "/bin/tar"; |
||||||
|
|
||||||
|
if(not -x $init->{'opensslbin'}) { |
||||||
|
printf(gettext("Can't execute %s.\n"), $init->{'opensslbin'}); |
||||||
|
print gettext("Configure correct path to openssl in tinyca.\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
if(not -x $init->{'zipbin'}) { |
||||||
|
print gettext("zip command not found, support disabled.\n"); |
||||||
|
print gettext("Configure correct path to zip in tinyca.\n"); |
||||||
|
} |
||||||
|
|
||||||
|
if(not -x $init->{'tarbin'}) { |
||||||
|
print gettext("tar command not found, support disabled.\n"); |
||||||
|
print gettext("Configure correct path to tar in tinyca.\n"); |
||||||
|
} |
||||||
|
|
||||||
|
# directory with the templates |
||||||
|
$init->{'templatedir'} = "./templates"; |
||||||
|
|
||||||
|
if(not -d $init->{'templatedir'}) { |
||||||
|
print gettext("Can't find templatedir.\n"); |
||||||
|
print gettext("Please configure correct path with templates in tinyca.\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
# location for CA files |
||||||
|
$init->{'basedir'} = $ENV{HOME}."/.TinyCA"; |
||||||
|
$init->{'exportdir'} = $ENV{HOME}; |
||||||
|
|
||||||
|
umask(0077); |
||||||
|
|
||||||
|
# create main object and initialize CA |
||||||
|
my $gui = GUI->new($init); |
||||||
|
|
||||||
|
# and now run... |
||||||
|
$gui->{'mw'}->show_all(); |
||||||
|
|
||||||
|
# decide what to do on startup |
||||||
|
if(@{$gui->{'CA'}->{'calist'}}) { |
||||||
|
$gui->{'CA'}->get_open_name($gui); |
||||||
|
} else { |
||||||
|
$gui->{'CA'}->get_ca_create($gui); |
||||||
|
} |
||||||
|
|
||||||
|
sub _ { |
||||||
|
my $s = gettext(@_); |
||||||
|
utf8::decode($s); |
||||||
|
return($s); |
||||||
|
} |
||||||
|
|
||||||
|
Gtk2->main(); |
||||||
|
|
||||||
|
exit(0); |
||||||
|
|
@ -0,0 +1,38 @@ |
|||||||
|
[Desktop Entry] |
||||||
|
Encoding=UTF-8 |
||||||
|
Type=Application |
||||||
|
GenericName=Tool to manage a Certification Authority |
||||||
|
Name=TinyCA2 |
||||||
|
Exec=tinyca2 |
||||||
|
|
||||||
|
Categories=Network;Security |
||||||
|
GenericName[bg]=GenericName(tinyca.desktop): Управление на сертификационните регистри (Certification Authority) |
||||||
|
Name[cs]=TinyCA2 |
||||||
|
GenericName[cs]=Nástroj pro správu certifikační autority |
||||||
|
Name[de]=TinyCA2 |
||||||
|
GenericName[de]=Werkzeug zum Verwalten einer Certification Authority |
||||||
|
Name[es]=TinyCA2 |
||||||
|
GenericName[es]=Herramienta para gestionar autoridades certificadoras |
||||||
|
Name[fr]=TinyCA2 |
||||||
|
GenericName[fr]=Outil de gestion d'une autorité de certification |
||||||
|
Name[hu]=TinyCA2 |
||||||
|
GenericName[hu]=CA (Certification Authority) kezelő segédeszköz |
||||||
|
Name[it]=TinyCA2 |
||||||
|
GenericName[it]=Tool d'amministrazione per una certification authority |
||||||
|
Name[ja]=TinyCA2 |
||||||
|
GenericName[ja]=認証局の管理ツール |
||||||
|
Name[nb]=TinyCA2 |
||||||
|
GenericName[nb]=Administrasjonsverktøy for sertifikater |
||||||
|
Name[nl]=TinyCA2 |
||||||
|
GenericName[nl]=Programma om een certificaat autoriteit te beheren |
||||||
|
Name[pl]=TinyCA2 |
||||||
|
GenericName[pl]=Narzędzie do zarządzania centrum certyfikacyjnym |
||||||
|
Name[pt_BR]=TinyCA2 |
||||||
|
GenericName[pt_BR]=Ferramenta para gerenciar uma Autoridade de Certificação |
||||||
|
Name[sk]=TinyCA2 |
||||||
|
GenericName[sk]=Nástroj pre správu certifikačnej autority |
||||||
|
Name[zh_CN]=TinyCA2 |
||||||
|
GenericName[zh_CN]=管理证书授权者的工具 |
||||||
|
Name[zh_TW]=TinyCA2 |
||||||
|
GenericName[zh_TW]=管理認證授權的工具 |
||||||
|
X-SuSE-translate=true |
@ -0,0 +1,170 @@ |
|||||||
|
# spec file for package tinyca |
||||||
|
# |
||||||
|
# $Id: tinyca2.spec,v 1.9 2006/07/25 20:10:54 sm Exp $ |
||||||
|
# |
||||||
|
# Copyright (c) 2002 Stephan Martin |
||||||
|
# This file and all modifications and additions to the pristine |
||||||
|
# package are under the same license as the package itself. |
||||||
|
# |
||||||
|
|
||||||
|
%define bindir %{_bindir} |
||||||
|
%define libdir %{_datadir}/TinyCA2/lib |
||||||
|
%define templatesdir %{_datadir}/TinyCA2/templates |
||||||
|
%define localedir %{_datadir}/TinyCA2/locale/ |
||||||
|
|
||||||
|
Name: tinyca2 |
||||||
|
URL: http://tinyca.sm-zone.net/ |
||||||
|
Group: Productivity/Networking/Security |
||||||
|
License: GPL |
||||||
|
Requires: perl perl-Gtk2 perl-MIME-Base64 |
||||||
|
Packager: Stephan Martin <sm@sm-zone.net> |
||||||
|
Version: @version@ |
||||||
|
Release: 0 |
||||||
|
Source0: %{name}-%{version}.tar.gz |
||||||
|
Source1: %{name}.desktop |
||||||
|
Summary: Graphical Tool for Managing a Certification Authority |
||||||
|
BuildArch: noarch |
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build |
||||||
|
|
||||||
|
%description |
||||||
|
TinyCA is a graphical tool written in Perl/Gtk to manage a small |
||||||
|
Certification Authority (CA) using openssl. |
||||||
|
|
||||||
|
TinyCA supports - creation and revocation of x509 - S/MIME |
||||||
|
certificates. |
||||||
|
|
||||||
|
- PKCS#10 requests. |
||||||
|
|
||||||
|
- exporting certificates as PEM, DER, TXT, and PKCS#12. |
||||||
|
|
||||||
|
- server certificates for use in web servers, email servers, IPsec, |
||||||
|
and more. |
||||||
|
|
||||||
|
- client certificates for use in web browsers, email clients, IPsec, |
||||||
|
and more. |
||||||
|
|
||||||
|
- creation and management of SubCAs |
||||||
|
|
||||||
|
|
||||||
|
Authors: |
||||||
|
-------- |
||||||
|
Stephan Martin <sm@sm-zone.net> |
||||||
|
|
||||||
|
%prep |
||||||
|
%setup |
||||||
|
|
||||||
|
%build |
||||||
|
# Configure pristine source |
||||||
|
perl -pi -e 's:./lib:%{libdir}:g' tinyca2 |
||||||
|
perl -pi -e 's:./templates:%{templatesdir}:g' tinyca2 |
||||||
|
perl -pi -e 's:./locale:%{localedir}:g' tinyca2 |
||||||
|
make -C po |
||||||
|
|
||||||
|
%install |
||||||
|
[ "$RPM_BUILD_ROOT" != "/" ] && [ -d $RPM_BUILD_ROOT ] && rm -rf $RPM_BUILD_ROOT; |
||||||
|
|
||||||
|
LANGUAGES="de es cs fr sv" |
||||||
|
|
||||||
|
mkdir -p $RPM_BUILD_ROOT%{bindir} |
||||||
|
mkdir -p $RPM_BUILD_ROOT%{libdir} |
||||||
|
mkdir -p $RPM_BUILD_ROOT%{libdir}/GUI |
||||||
|
mkdir -p $RPM_BUILD_ROOT%{templatesdir} |
||||||
|
|
||||||
|
install -m 644 lib/*.pm $RPM_BUILD_ROOT%{libdir} |
||||||
|
install -m 644 lib/GUI/*.pm $RPM_BUILD_ROOT%{libdir}/GUI/ |
||||||
|
install -m 644 templates/openssl.cnf $RPM_BUILD_ROOT%{templatesdir} |
||||||
|
install -m 755 tinyca2 $RPM_BUILD_ROOT%{bindir} |
||||||
|
mkdir -p $RPM_BUILD_ROOT/usr/share/applications/ |
||||||
|
install -m 644 tinyca2.desktop $RPM_BUILD_ROOT/usr/share/applications/ |
||||||
|
|
||||||
|
for LANG in $LANGUAGES; do |
||||||
|
mkdir -p $RPM_BUILD_ROOT%{localedir}/$LANG/LC_MESSAGES/ |
||||||
|
install -m 644 locale/$LANG/LC_MESSAGES/tinyca2.mo %{buildroot}%{localedir}/$LANG/LC_MESSAGES/ |
||||||
|
done |
||||||
|
|
||||||
|
%clean |
||||||
|
rm -rf %{buildroot} |
||||||
|
|
||||||
|
%files |
||||||
|
%defattr(-,root,root) |
||||||
|
%doc CHANGES |
||||||
|
%dir %{_datadir}/TinyCA2 |
||||||
|
%{bindir}/tinyca2 |
||||||
|
%{_datadir}/TinyCA2/* |
||||||
|
%{_datadir}/applications/* |
||||||
|
|
||||||
|
%changelog |
||||||
|
* Sun Dec 5 2004 - sm@sm-zone.net |
||||||
|
- import functioins added |
||||||
|
* Fri Aug 13 2004 - sm@sm-zone.net |
||||||
|
- czech translation |
||||||
|
* Sun Jun 13 2004 - sm@sm-zone.net |
||||||
|
- gui polishing |
||||||
|
- code cleanup |
||||||
|
- some usability improvements |
||||||
|
* Wed Jun 2 2004 - sm@sm-zone.net |
||||||
|
- gui polishing |
||||||
|
- GUI module splitted to several files |
||||||
|
* Fri Oct 3 2003 - sm@sm-zone.net |
||||||
|
- added a lot of configuration options |
||||||
|
- correctly import/show details of requests without extensions |
||||||
|
(thanks to James.Leavitt@anywaregroup.com) |
||||||
|
* Mon Sep 1 2003 - sm@sm-zone.net |
||||||
|
- added renewal of certificates |
||||||
|
* Wed Aug 13 2003 - sm@sm-zone.net |
||||||
|
- rewite, now using perl-Gtk |
||||||
|
* Sat Jul 5 2003 - sm@sm-zone.net |
||||||
|
- added german translation |
||||||
|
* Tue Jul 1 2003 - sm@sm-zone.net |
||||||
|
- convert index.txt if openssl changed from 0.9.6x to 0.9.7x |
||||||
|
* Fri Jun 27 2003 - sm@sm-zone.net |
||||||
|
- added export into zip-file |
||||||
|
thanks to ludwig.nussel@suse.de |
||||||
|
* Mon Jun 23 2003 - sm@sm-zone.net |
||||||
|
- some tiny usability improvements |
||||||
|
thanks to ludwig.nussel@suse.de again |
||||||
|
* Thu Jun 19 2003 - sm@sm-zone.net |
||||||
|
- some usability improvements |
||||||
|
thanks to ludwig.nussel@suse.de |
||||||
|
- some more configuration options |
||||||
|
* Fri Oct 4 2002 - sm@sm-zone.net |
||||||
|
- Fixed bug exporting keys in PEM format |
||||||
|
- Fixed possible empty lines in cert/key/reqlist |
||||||
|
thanks to waldemar.mertke@gmx.de |
||||||
|
* Fri Sep 27 2002 - sm@sm-zone.net |
||||||
|
- fixed some minor bugs and typos (e.g. concerning openssl 0.9.7) |
||||||
|
thanks to iebgener@yahoo.com and waldemar.mertke@gmx.de |
||||||
|
* Wed Aug 21 2002 - sm@sm-zone.net |
||||||
|
- fixed revocation |
||||||
|
- added some colors |
||||||
|
- thanks to curly@e-card.bg |
||||||
|
* Sun Aug 18 2002 - sm@sm-zone.net |
||||||
|
- new version 0.4.0 |
||||||
|
- works independent of OpenCA modules now |
||||||
|
- some enhancements to functionality (e.g. export of key without |
||||||
|
passwd) |
||||||
|
- some smaller bugfixes in usability |
||||||
|
- new specfile (thanks to oron@actcom.co.il) |
||||||
|
* Thu Jun 6 2002 - Oron Peled <oron@actcom.co.il> |
||||||
|
- Cleaned .spec file |
||||||
|
* Mon Jun 3 2002 - sm@sm-zone.net |
||||||
|
- fixed wrong templatedir when creating new CA |
||||||
|
* Sun Jun 2 2002 - sm@sm-zone.net |
||||||
|
- fixed some minor bugs and typos |
||||||
|
* Sat May 11 2002 - sm@sm-zone.net |
||||||
|
- Added parser for x509 extensions |
||||||
|
* Fri May 03 2002 - sm@sm-zone.net |
||||||
|
- added possibility to view requests/certificates |
||||||
|
* Thu Apr 18 2002 - sm@sm-zone.net |
||||||
|
- added configuration |
||||||
|
* Sun Apr 7 2002 - sm@sm-zone.net |
||||||
|
- improved usability |
||||||
|
* Sun Mar 31 2002 - sm@sm-zone.net |
||||||
|
- added function to delete ca |
||||||
|
* Sat Mar 30 2002 - sm@sm-zone.net |
||||||
|
- allow import of pkcs#10 requests |
||||||
|
* Thu Mar 21 2002 - sm@sm-zone.et |
||||||
|
- use different listboxes |
||||||
|
* Mon Mar 18 2002 - sm@sm-zone.net |
||||||
|
- initial package |
||||||
|
|
Reference in new issue