Imported former upstream version 0.7.5

This commit is contained in:
2016-12-05 19:21:56 +01:00
commit e136e7cbbf
28 changed files with 24757 additions and 0 deletions

173
lib/GUI/CALLBACK.pm Normal file
View File

@@ -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

479
lib/GUI/HELPERS.pm Normal file
View File

@@ -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

1502
lib/GUI/TCONFIG.pm Normal file

File diff suppressed because it is too large Load Diff

112
lib/GUI/WORDS.pm Normal file
View File

@@ -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

879
lib/GUI/X509_browser.pm Normal file
View File

@@ -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

280
lib/GUI/X509_infobox.pm Normal file
View File

@@ -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