Imported former upstream version 0.7.5
This commit is contained in:
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
|
||||
|
Loading…
Reference in New Issue