diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | data/glade/Makefile.am | 5 | ||||
-rw-r--r-- | data/glade/certs-manager.glade | 530 | ||||
-rw-r--r-- | data/ui/epiphany-ui.xml | 1 | ||||
-rw-r--r-- | embed/Makefile.am | 11 | ||||
-rw-r--r-- | embed/ephy-certificate-manager.c | 72 | ||||
-rw-r--r-- | embed/ephy-certificate-manager.h | 68 | ||||
-rw-r--r-- | embed/ephy-x509-cert.c | 53 | ||||
-rw-r--r-- | embed/ephy-x509-cert.h | 61 | ||||
-rw-r--r-- | embed/mozilla/Makefile.am | 6 | ||||
-rw-r--r-- | embed/mozilla/mozilla-embed-single.cpp | 157 | ||||
-rw-r--r-- | embed/mozilla/mozilla-x509-cert.cpp | 263 | ||||
-rw-r--r-- | embed/mozilla/mozilla-x509-cert.h | 62 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/ephy-certificate-manager.c | 517 | ||||
-rw-r--r-- | src/ephy-certificate-manager.h | 59 | ||||
-rw-r--r-- | src/ephy-window.c | 15 | ||||
-rw-r--r-- | src/window-commands.c | 17 | ||||
-rw-r--r-- | src/window-commands.h | 3 |
20 files changed, 1952 insertions, 1 deletions
@@ -1,3 +1,28 @@ +2005-12-11 Christian Persch <chpe@cvs.gnome.org> + + * configure.ac: + * data/glade/Makefile.am: + * data/glade/certs-manager.glade: + * data/ui/epiphany-ui.xml: + * embed/Makefile.am: + A embed/ephy-certificate-manager.c: + A embed/ephy-certificate-manager.h: + A embed/ephy-x509-cert.c: + A embed/ephy-x509-cert.h: + * embed/mozilla/Makefile.am: + * embed/mozilla/mozilla-embed-single.cpp: + A embed/mozilla/mozilla-x509-cert.cpp: + A embed/mozilla/mozilla-x509-cert.h: + * src/Makefile.am: + A src/ephy-certificate-manager.c: + A src/ephy-certificate-manager.h: + * src/ephy-window.c: + * src/window-commands.c: + * src/window-commands.h: + + Add certificate manager. Patch by Robert Marcano and Crispin + Flowerday. Fixes bug #119090. + 2005-12-08 Christian Persch <chpe@cvs.gnome.org> * src/pdm-dialog.c: (pdm_dialog_cookies_construct), diff --git a/configure.ac b/configure.ac index 0f5a708c8..34886e01e 100644 --- a/configure.ac +++ b/configure.ac @@ -531,6 +531,8 @@ fi # Additional features # ******************* +# Zeroconf bookmarks sites + AC_MSG_CHECKING([whether to enable zeroconf bookmarks support]) AC_ARG_ENABLE([zeroconf], AS_HELP_STRING([--enable-zeroconf],[Whether to enable zeroconf bookmarks support (default:disabled)]), @@ -543,6 +545,24 @@ fi AM_CONDITIONAL([ENABLE_ZEROCONF],[test "x$enable_zeroconf" = "xyes"]) +# Certificates manager + +if test "$enable_psm" = "yes"; then + +AC_MSG_CHECKING([whether to build the certificates manager]) +AC_ARG_ENABLE([certificate-manager], + AS_HELP_STRING([--enable-certificate-manager],[Whether to enable the certificate manager (experimental; default:disabled)]), + [],[enable_certificate_manager=no]) +AC_MSG_RESULT([$enable_certificate_manager]) + +fi + +if test "$enable_certificate_manager" = "yes"; then + AC_DEFINE([ENABLE_CERTIFICATE_MANAGER],[1],[Define to enable the certificate manager build]) +fi + +AM_CONDITIONAL([ENABLE_CERTIFICATE_MANAGER],[test "$enable_certificate_manager" = "yes"]) + # ******************************* # Add warning flags # ******************************* diff --git a/data/glade/Makefile.am b/data/glade/Makefile.am index 904743c7c..9deaab63e 100644 --- a/data/glade/Makefile.am +++ b/data/glade/Makefile.am @@ -4,6 +4,11 @@ glade_DATA = \ prefs-dialog.glade \ print.glade +if ENABLE_CERTIFICATE_MANAGER +glade_DATA += \ + certs-manager.glade +endif + gladedir = $(pkgdatadir)/glade EXTRA_DIST = $(glade_DATA) diff --git a/data/glade/certs-manager.glade b/data/glade/certs-manager.glade new file mode 100644 index 000000000..16a662df0 --- /dev/null +++ b/data/glade/certs-manager.glade @@ -0,0 +1,530 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> + +<widget class="GtkDialog" id="certs_manager_dialog"> + <property name="border_width">5</property> + <property name="title" translatable="yes">Certificates</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="icon_name">gtk-dialog-authentication</property> + <property name="role">epiphany-certificate-manager</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="focus_on_map">True</property> + <property name="urgency_hint">False</property> + <property name="has_separator">False</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child internal-child="action_area"> + <widget class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + + <child> + <widget class="GtkButton" id="helpbutton1"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-help</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-11</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="import_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Import</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">1</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="closebutton1"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-close</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">-7</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">GTK_PACK_END</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="notebook"> + <property name="border_width">5</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="show_tabs">True</property> + <property name="show_border">True</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="personal_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + <property name="fixed_height_mode">False</property> + <property name="hover_selection">False</property> + <property name="hover_expand">False</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="personal_remove_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="personal_view_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_View</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="personal_export_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Export</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Personal</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox15"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow5"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="server_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + <property name="fixed_height_mode">False</property> + <property name="hover_selection">False</property> + <property name="hover_expand">False</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkAlignment" id="alignment15"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox5"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="server_remove_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="server_view_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_View</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="server_props_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-properties</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes">Web Sites</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox18"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow6"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="ca_treeview"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + <property name="fixed_height_mode">False</property> + <property name="hover_selection">False</property> + <property name="hover_expand">False</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkAlignment" id="alignment18"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox6"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="ca_remove_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-remove</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="ca_view_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_View</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + + <child> + <widget class="GtkButton" id="ca_props_button"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-properties</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes">Authorities</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/data/ui/epiphany-ui.xml b/data/ui/epiphany-ui.xml index 0fffaa2b9..2e0ef6fd2 100644 --- a/data/ui/epiphany-ui.xml +++ b/data/ui/epiphany-ui.xml @@ -31,6 +31,7 @@ <menuitem name="EditFindPrevMenu" action="EditFindPrev"/> <separator name="EditSep3"/> <menuitem name="EditPersonalDataMenu" action="EditPersonalData"/> +<!-- <menuitem name="EditCertificatesMenu" action="EditCertificates"/> --> <menuitem name="EditToolbarMenu" action="EditToolbar"/> <menuitem name="EditPrefsMenu" action="EditPrefs"/> </menu> diff --git a/embed/Makefile.am b/embed/Makefile.am index 323217601..de5375508 100644 --- a/embed/Makefile.am +++ b/embed/Makefile.am @@ -52,6 +52,16 @@ libephyembed_la_SOURCES = \ $(NOINST_H_FILES) \ $(BUILT_SOURCES) +if ENABLE_CERTIFICATE_MANAGER +INST_H_FILES += \ + ephy-certificate-manager.h \ + ephy-x509-cert.h + +libephyembed_la_SOURCES += \ + ephy-certificate-manager.c \ + ephy-x509-cert.c +endif + libephyembed_la_CPPFLAGS = \ -I$(top_builddir)/lib \ -I$(top_srcdir)/embed/mozilla \ @@ -79,7 +89,6 @@ libephyembedfactory_la_CFLAGS = \ $(DEPENDENCIES_CFLAGS) \ $(AM_CFLAGS) - BUILT_SOURCES = \ ephy-embed-type-builtins.c \ ephy-embed-type-builtins.h diff --git a/embed/ephy-certificate-manager.c b/embed/ephy-certificate-manager.c new file mode 100644 index 000000000..da75077cc --- /dev/null +++ b/embed/ephy-certificate-manager.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#include <config.h> + +#include "ephy-certificate-manager.h" + +GType +ephy_certificate_manager_get_type (void) +{ + static GType ephy_certificate_manager_type = 0; + + if (ephy_certificate_manager_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyCertificateManagerIface), + NULL, + NULL, + }; + + ephy_certificate_manager_type = g_type_register_static (G_TYPE_INTERFACE, + "EphyCertificateManager", + &our_info, + (GTypeFlags)0); + } + + return ephy_certificate_manager_type; +} + +/* Certificates */ +GList * +ephy_certificate_manager_get_certificates (EphyCertificateManager *manager, + EphyX509CertType type) +{ + EphyCertificateManagerIface *iface = EPHY_CERTIFICATE_MANAGER_GET_IFACE (manager); + return iface->get_certificates (manager, type); +} + +gboolean +ephy_certificate_manager_remove_certificate (EphyCertificateManager *manager, + EphyX509Cert *cert) +{ + EphyCertificateManagerIface *iface = EPHY_CERTIFICATE_MANAGER_GET_IFACE (manager); + return iface->remove_certificate (manager, cert); +} + +gboolean +ephy_certificate_manager_import (EphyCertificateManager *manager, + const gchar *file) +{ + EphyCertificateManagerIface *iface = EPHY_CERTIFICATE_MANAGER_GET_IFACE (manager); + return iface->import (manager, file); +} diff --git a/embed/ephy-certificate-manager.h b/embed/ephy-certificate-manager.h new file mode 100644 index 000000000..51b505ed2 --- /dev/null +++ b/embed/ephy-certificate-manager.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#ifndef EPHY_CERTIFICATE_MANAGER_H +#define EPHY_CERTIFICATE_MANAGER_H + +#include <glib-object.h> + +#include "ephy-x509-cert.h" + +G_BEGIN_DECLS + +#define EPHY_TYPE_CERTIFICATE_MANAGER (ephy_certificate_manager_get_type ()) +#define EPHY_CERTIFICATE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_CERTIFICATE_MANAGER, EphyCertificateManager)) +#define EPHY_CERTIFICATE_MANAGER_IFACE(klass) (G_TYPE_CHECK_IFACE_CAST ((klass), EPHY_TYPE_CERTIFICATE_MANAGER, EphyCertificateManagerIface)) +#define EPHY_IS_CERTIFICATE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_CERTIFICATE_MANAGER)) +#define EPHY_IS_CERTIFICATE_MANAGER_IFACE(klass) (G_TYPE_CHECK_IFACE_TYPE ((klass), EPHY_TYPE_CERTIFICATE_MANAGER)) +#define EPHY_CERTIFICATE_MANAGER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_CERTIFICATE_MANAGER, EphyCertificateManagerIface)) + +typedef struct _EphyCertificateManager EphyCertificateManager; +typedef struct _EphyCertificateManagerIface EphyCertificateManagerIface; + +struct _EphyCertificateManagerIface +{ + GTypeInterface base_iface; + + /* Methods */ + GList * (* get_certificates) (EphyCertificateManager *manager, + EphyX509CertType type); + gboolean (* remove_certificate) (EphyCertificateManager *manager, + EphyX509Cert *cert); + gboolean (* import) (EphyCertificateManager *manager, + const gchar *file); +}; + +GType ephy_certificate_manager_get_type (void); + +/* Certificate */ +GList * ephy_certificate_manager_get_certificates (EphyCertificateManager *manager, + EphyX509CertType type); + +gboolean ephy_certificate_manager_remove_certificate (EphyCertificateManager *manager, + EphyX509Cert *cert); + +gboolean ephy_certificate_manager_import (EphyCertificateManager *manager, + const gchar *file); + +G_END_DECLS + +#endif diff --git a/embed/ephy-x509-cert.c b/embed/ephy-x509-cert.c new file mode 100644 index 000000000..824d3d807 --- /dev/null +++ b/embed/ephy-x509-cert.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#include <config.h> + +#include "ephy-x509-cert.h" + +GType +ephy_x509_cert_get_type (void) +{ + static GType ephy_x509_cert_type = 0; + + if (ephy_x509_cert_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyX509CertIface), + NULL, + NULL, + }; + ephy_x509_cert_type = g_type_register_static (G_TYPE_INTERFACE, + "EphyEmbedX509cert", + &our_info, + (GTypeFlags)0); + } + + return ephy_x509_cert_type; +} + +const char * +ephy_x509_cert_get_title (EphyX509Cert *cert) +{ + EphyX509CertIface *iface = EPHY_X509_CERT_GET_IFACE (cert); + return iface->get_title (cert); +} diff --git a/embed/ephy-x509-cert.h b/embed/ephy-x509-cert.h new file mode 100644 index 000000000..8fa89316d --- /dev/null +++ b/embed/ephy-x509-cert.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2003 Robert Marcano + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#ifndef EPHY_X509_CERT_H +#define EPHY_X509_CERT_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +typedef enum +{ + PERSONAL_CERTIFICATE, + SERVER_CERTIFICATE, + CA_CERTIFICATE +} EphyX509CertType; + + +#define EPHY_TYPE_X509_CERT (ephy_x509_cert_get_type ()) +#define EPHY_X509_CERT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_X509_CERT, EphyX509Cert)) +#define EPHY_X509_CERT_IFACE(klass) (G_TYPE_CHECK_IFACE_CAST ((klass), EPHY_TYPE_X509_CERT, EphyX509CertIface)) +#define EPHY_IS_X509_CERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_X509_CERT)) +#define EPHY_IS_X509_CERT_IFACE(klass) (G_TYPE_CHECK_IFACE_TYPE ((klass), EPHY_TYPE_X509_CERT)) +#define EPHY_X509_CERT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_X509_CERT, EphyX509CertIface)) + +typedef struct _EphyX509Cert EphyX509Cert; +typedef struct _EphyX509CertIface EphyX509CertIface; + +struct _EphyX509CertIface +{ + GTypeInterface base_iface; + + /* Methods */ + const char * (* get_title) (EphyX509Cert *cert); +}; + +GType ephy_x509_cert_get_type (void); + +/* Base */ +const char * ephy_x509_cert_get_title (EphyX509Cert *cert); + +G_END_DECLS + +#endif diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am index c27dd0965..dff497be4 100644 --- a/embed/mozilla/Makefile.am +++ b/embed/mozilla/Makefile.am @@ -68,6 +68,12 @@ libephymozillaembed_la_SOURCES += \ GtkNSSSecurityWarningDialogs.h endif +if ENABLE_CERTIFICATE_MANAGER +libephymozillaembed_la_SOURCES += \ + mozilla-x509-cert.cpp \ + mozilla-x509-cert.h +endif + if HAVE_GECKO_1_8 libephymozillaembed_la_SOURCES += \ EphyBadCertRejector.cpp \ diff --git a/embed/mozilla/mozilla-embed-single.cpp b/embed/mozilla/mozilla-embed-single.cpp index 201689516..94359c8a3 100644 --- a/embed/mozilla/mozilla-embed-single.cpp +++ b/embed/mozilla/mozilla-embed-single.cpp @@ -1,6 +1,8 @@ /* vim:set ts=8 noet sw=8: * Copyright (C) 2000-2004 Marco Pesenti Gritti + * Copyright (C) 2003 Robert Marcano * Copyright (C) 2003, 2004 Christian Persch + * Copyright (C) 2005 Crispin Flowerday * * 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 @@ -28,6 +30,7 @@ #include "ephy-cookie-manager.h" #include "ephy-password-manager.h" #include "ephy-permission-manager.h" +#include "ephy-certificate-manager.h" #include "ephy-embed-shell.h" #include "glib.h" @@ -44,6 +47,7 @@ #include "EphyBrowser.h" #include "EphyUtils.h" #include "MozillaPrivate.h" +#include "mozilla-x509-cert.h" #include <glib/gi18n.h> #include <libgnomevfs/gnome-vfs-utils.h> @@ -68,6 +72,11 @@ #include <nsILocalFile.h> #include <nsIURI.h> +#ifdef HAVE_MOZILLA_PSM +#include <nsIX509Cert.h> +#include <nsIX509CertDB.h> +#endif + #ifdef HAVE_NSIPASSWORD_H #include <nsIPassword.h> #endif @@ -122,6 +131,10 @@ static void ephy_password_manager_iface_init (EphyPasswordManagerIface *iface); static void ephy_permission_manager_iface_init (EphyPermissionManagerIface *iface); static void mozilla_embed_single_init (MozillaEmbedSingle *ges); +#ifdef ENABLE_CERTIFICATE_MANAGER +static void ephy_certificate_manager_iface_init (EphyCertificateManagerIface *iface); +#endif + static GObjectClass *parent_class = NULL; GType @@ -172,6 +185,15 @@ mozilla_embed_single_get_type (void) NULL }; +#ifdef ENABLE_CERTIFICATE_MANAGER + static const GInterfaceInfo certificate_manager_info = + { + (GInterfaceInitFunc) ephy_certificate_manager_iface_init, + NULL, + NULL + }; +#endif + type = g_type_register_static (G_TYPE_OBJECT, "MozillaEmbedSingle", &our_info, @@ -192,6 +214,11 @@ mozilla_embed_single_get_type (void) g_type_add_interface_static (type, EPHY_TYPE_PERMISSION_MANAGER, &permission_manager_info); +#ifdef ENABLE_CERTIFICATE_MANAGER + g_type_add_interface_static (type, + EPHY_TYPE_CERTIFICATE_MANAGER, + &certificate_manager_info); +#endif } return type; @@ -1009,6 +1036,124 @@ impl_open_window (EphyEmbedSingle *single, return EphyUtils::FindEmbed (newWindow); } +#ifdef ENABLE_CERTIFICATE_MANAGER + +static gboolean +impl_remove_certificate (EphyCertificateManager *manager, + EphyX509Cert *cert) +{ + nsresult rv; + + nsCOMPtr<nsIX509CertDB> certDB; + certDB = do_GetService (NS_X509CERTDB_CONTRACTID); + if (!certDB) return FALSE; + + nsCOMPtr<nsIX509Cert> mozCert; + rv = mozilla_x509_cert_get_mozilla_cert (MOZILLA_X509_CERT (cert), + getter_AddRefs (mozCert)); + if (NS_FAILED (rv)) return FALSE; + + rv = certDB->DeleteCertificate (mozCert); + if (NS_FAILED (rv)) return FALSE; + + return TRUE; +} + +#define NICK_DELIMITER PRUnichar('\001') + +static GList * +retrieveCerts (PRUint32 type) +{ + nsresult rv; + + nsCOMPtr<nsIX509CertDB> certDB; + certDB = do_GetService (NS_X509CERTDB_CONTRACTID); + if (!certDB) return NULL; + + PRUint32 count; + PRUnichar **certNameList = NULL; + + rv = certDB->FindCertNicknames (NULL, type, &count, &certNameList); + if (NS_FAILED (rv)) return NULL; + + LOG("Certificates found: %i", count); + + GList *list = NULL; + for (PRUint32 i = 0; i < count; i++) + { + /* HACK HACK, this is EVIL, the string for each cert is: + <DELIMITER>nicknameOrEmailAddress<DELIMITER>dbKey + So we need to chop off the dbKey to look it up in the database. + + https://bugzilla.mozilla.org/show_bug.cgi?id=214742 + */ + nsEmbedCString full_string; + NS_UTF16ToCString (nsEmbedString(certNameList[i]), + NS_CSTRING_ENCODING_UTF8, full_string); + + const char *key = full_string.get(); + char *pos = strrchr (key, NICK_DELIMITER); + if (!pos) continue; + + nsCOMPtr<nsIX509Cert> mozilla_cert; + rv = certDB->FindCertByDBKey (pos, NULL, getter_AddRefs (mozilla_cert)); + if (NS_FAILED (rv)) continue; + + MozillaX509Cert *cert = mozilla_x509_cert_new (mozilla_cert); + list = g_list_prepend (list, cert); + } + + NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY (count, certNameList); + return list; +} + +static GList * +impl_get_certificates (EphyCertificateManager *manager, + EphyX509CertType type) +{ + int moz_type = nsIX509Cert::USER_CERT; + switch (type) + { + case PERSONAL_CERTIFICATE: + moz_type = nsIX509Cert::USER_CERT; + break; + case SERVER_CERTIFICATE: + moz_type = nsIX509Cert::SERVER_CERT; + break; + case CA_CERTIFICATE: + moz_type = nsIX509Cert::CA_CERT; + break; + } + return retrieveCerts (moz_type); +} + +static gboolean +impl_import (EphyCertificateManager *manager, + const gchar *file) +{ + nsresult rv; + nsCOMPtr<nsIX509CertDB> certDB; + certDB = do_GetService (NS_X509CERTDB_CONTRACTID); + if (!certDB) return NULL; + + nsCOMPtr<nsILocalFile> localFile; + localFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + + // TODO Is this correct ? + nsEmbedString path; + NS_CStringToUTF16 (nsEmbedCString(file), + NS_CSTRING_ENCODING_UTF8, path); + + + localFile->InitWithPath (path); + rv = certDB->ImportPKCS12File(NULL, localFile); + if (NS_FAILED (rv)) return FALSE; + + return TRUE; +} + +#endif /* ENABLE_CERTIFICATE_MANAGER */ + static void mozilla_embed_single_get_property (GObject *object, guint prop_id, @@ -1093,3 +1238,15 @@ ephy_permission_manager_iface_init (EphyPermissionManagerIface *iface) iface->test = impl_permission_manager_test; iface->list = impl_permission_manager_list; } + +#ifdef ENABLE_CERTIFICATE_MANAGER + +static void +ephy_certificate_manager_iface_init (EphyCertificateManagerIface *iface) +{ + iface->get_certificates = impl_get_certificates; + iface->remove_certificate = impl_remove_certificate; + iface->import = impl_import; +} + +#endif /* ENABLE_CERTIFICATE_MANAGER */ diff --git a/embed/mozilla/mozilla-x509-cert.cpp b/embed/mozilla/mozilla-x509-cert.cpp new file mode 100644 index 000000000..c80ee918d --- /dev/null +++ b/embed/mozilla/mozilla-x509-cert.cpp @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#include "mozilla-config.h" + +#include "config.h" + +#include "mozilla-x509-cert.h" +#include "ephy-debug.h" + +#undef MOZILLA_INTERNAL_API +#include <nsEmbedString.h> +#define MOZILLA_INTERNAL_API 1 + +#define MOZILLA_X509_CERT_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \ + MOZILLA_TYPE_X509_CERT, MozillaX509CertPrivate)) + +static void mozilla_x509_cert_class_init (MozillaX509CertClass *klass); +static void ephy_x509_cert_init (EphyX509CertIface *iface); +static void mozilla_x509_cert_init (MozillaX509Cert *cert); + +struct _MozillaX509CertPrivate +{ + nsIX509Cert * mozilla_cert; + gchar *title; +}; + +enum +{ + PROP_0, + PROP_MOZILLA_CERT +}; + +static GObjectClass *parent_class = NULL; + +GType +mozilla_x509_cert_get_type (void) +{ + static GType mozilla_x509_cert_type = 0; + + if (mozilla_x509_cert_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (MozillaX509CertClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) mozilla_x509_cert_class_init, + NULL, + NULL, /* class_data */ + sizeof (MozillaX509Cert), + 0, /* n_preallocs */ + (GInstanceInitFunc) mozilla_x509_cert_init + }; + + static const GInterfaceInfo x509_cert_info = + { + (GInterfaceInitFunc) ephy_x509_cert_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + mozilla_x509_cert_type = g_type_register_static (G_TYPE_OBJECT, + "MozillaX509Cert", + &our_info, + (GTypeFlags)0); + g_type_add_interface_static (mozilla_x509_cert_type, + EPHY_TYPE_X509_CERT, + &x509_cert_info); + } + + return mozilla_x509_cert_type; +} + +static void +mozilla_x509_cert_set_mozilla_cert (MozillaX509Cert *cert, + nsIX509Cert *mozilla_cert) +{ + nsCOMPtr<nsIX509Cert> tmpcert = cert->priv->mozilla_cert; + + if (cert->priv->mozilla_cert) + { + NS_RELEASE (cert->priv->mozilla_cert); + } + + cert->priv->mozilla_cert = mozilla_cert; + NS_IF_ADDREF (cert->priv->mozilla_cert); +} + + +nsresult +mozilla_x509_cert_get_mozilla_cert (MozillaX509Cert *cert, nsIX509Cert**aCert) +{ + *aCert = cert->priv->mozilla_cert; + NS_IF_ADDREF (*aCert); + + return *aCert ? NS_OK : NS_ERROR_FAILURE; +} + +static const char* +impl_get_title (EphyX509Cert *cert) +{ + MozillaX509Cert *m_cert = MOZILLA_X509_CERT (cert); + + /* lazy initialization of the title private variable */ + if (m_cert->priv->title != NULL) + { + return m_cert->priv->title; + } + + /* This title logic is adapted from Mozilla source at + mozilla/security/manager/ssl/src/nsCertTree.cpp */ + nsEmbedString name; + m_cert->priv->mozilla_cert->GetCommonName (name); + if (name.Length()) + { + nsEmbedCString cname; + NS_UTF16ToCString (name, NS_CSTRING_ENCODING_UTF8, cname); + + m_cert->priv->title = g_strdup (cname.get()); + } + else + { + /* No common name, so get the nickname instead */ + nsEmbedString nick; + m_cert->priv->mozilla_cert->GetNickname (nick); + + nsEmbedCString cnick; + NS_UTF16ToCString (nick, NS_CSTRING_ENCODING_UTF8, cnick); + + const char * str = cnick.get(); + char * colon = strchr (str, ':'); + if (colon) + { + m_cert->priv->title = g_strdup (colon+1); + } + else + { + m_cert->priv->title = g_strdup (cnick.get()); + } + } + + return m_cert->priv->title; +} + +static void +impl_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MozillaX509Cert *cert = MOZILLA_X509_CERT (object); + + switch (prop_id) + { + case PROP_MOZILLA_CERT: + mozilla_x509_cert_set_mozilla_cert(cert, + (nsIX509Cert*)g_value_get_pointer (value)); + break; + default: + break; + } +} + +static void +impl_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MozillaX509Cert *cert = MOZILLA_X509_CERT (object); + + switch (prop_id) + { + case PROP_MOZILLA_CERT: + g_value_set_pointer (value, cert->priv->mozilla_cert); + break; + default: + break; + } +} + +static void +mozilla_x509_cert_init (MozillaX509Cert *cert) +{ + cert->priv = MOZILLA_X509_CERT_GET_PRIVATE (cert); +} + +static void +mozilla_x509_cert_finalize (GObject *object) +{ + MozillaX509Cert *cert = MOZILLA_X509_CERT (object); + + LOG ("Finalizing MozillaX509Cert %p", cert); + + if (cert->priv->mozilla_cert) + { + NS_RELEASE (cert->priv->mozilla_cert); + } + + if (cert->priv->title) + { + g_free (cert->priv->title); + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_x509_cert_init (EphyX509CertIface *iface) +{ + iface->get_title = impl_get_title; +} + +static void +mozilla_x509_cert_class_init (MozillaX509CertClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = (GObjectClass*)g_type_class_peek_parent (klass); + + object_class->finalize = mozilla_x509_cert_finalize; + object_class->set_property = impl_set_property; + object_class->get_property = impl_get_property; + + g_object_class_install_property (object_class, + PROP_MOZILLA_CERT, + g_param_spec_pointer ("mozilla-cert", + "Mozilla-Cert", + "Mozilla XPCOM certificate", + (GParamFlags)(G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY))); + + g_type_class_add_private (object_class, sizeof (MozillaX509CertPrivate)); +} + +MozillaX509Cert * +mozilla_x509_cert_new (nsIX509Cert *moz_cert) +{ + MozillaX509Cert *cert; + + cert = (MozillaX509Cert*)g_object_new (MOZILLA_TYPE_X509_CERT, + "mozilla-cert", moz_cert, + NULL); + return cert; +} diff --git a/embed/mozilla/mozilla-x509-cert.h b/embed/mozilla/mozilla-x509-cert.h new file mode 100644 index 000000000..eb0cbe5ec --- /dev/null +++ b/embed/mozilla/mozilla-x509-cert.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2003 Robert Marcano + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#ifndef MOZILLA_X509_CERT_H +#define MOZILLA_X509_CERT_H + +#include "ephy-x509-cert.h" + +#include <glib-object.h> +#include <nsCOMPtr.h> +#include <nsIX509Cert.h> + +G_BEGIN_DECLS + +#define MOZILLA_TYPE_X509_CERT (mozilla_x509_cert_get_type ()) +#define MOZILLA_X509_CERT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOZILLA_TYPE_X509_CERT, MozillaX509Cert)) +#define MOZILLA_X509_CERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOZILLA_TYPE_X509_CERT, MozillaX509CertClass)) +#define MOZILLA_IS_X509_CERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOZILLA_TYPE_X509_CERT)) +#define MOZILLA_IS_X509_CERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOZILLA_TYPE_X509_CERT)) +#define MOZILLA_X509_CERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_TYPE_X509_CERT, MozillaX509CertClass)) + +typedef struct _MozillaX509Cert MozillaX509Cert; +typedef struct _MozillaX509CertPrivate MozillaX509CertPrivate; +typedef struct _MozillaX509CertClass MozillaX509CertClass; + +struct _MozillaX509Cert +{ + GObject parent; + MozillaX509CertPrivate *priv; +}; + +struct _MozillaX509CertClass +{ + GObjectClass parent_class; +}; + +GType mozilla_x509_cert_get_type (void); + +MozillaX509Cert *mozilla_x509_cert_new (nsIX509Cert *aMozCert); + +nsresult mozilla_x509_cert_get_mozilla_cert (MozillaX509Cert *cert, nsIX509Cert **cert); + +G_END_DECLS + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index a4d36a42b..2d43a5f08 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -105,6 +105,14 @@ libephymain_la_SOURCES = \ $(INST_H_FILES) \ $(NOINST_H_FILES) +if ENABLE_CERTIFICATE_MANAGER +NOINST_H_FILES += \ + ephy-certificate-manager.h + +libephymain_la_SOURCES += \ + ephy-certificate-manager.c +endif + libephymain_la_CPPFLAGS = \ -I$(top_builddir)/lib \ -I$(top_builddir)/lib/egg \ diff --git a/src/ephy-certificate-manager.c b/src/ephy-certificate-manager.c new file mode 100644 index 000000000..48721b3b2 --- /dev/null +++ b/src/ephy-certificate-manager.c @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#include "config.h" + +#include "ephy-certificate-manager.h" +#include "ephy-shell.h" +#include "ephy-embed-shell.h" +#include "ephy-gui.h" +#include "ephy-x509-cert.h" +#include "ephy-certificate-manager.h" +#include "ephy-embed-single.h" +#include "ephy-file-helpers.h" +#include "ephy-file-chooser.h" + +#include <gtk/gtkdialog.h> +#include <gtk/gtkbutton.h> +#include <gtk/gtkcellrenderertext.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtkliststore.h> + +#include <glib/gi18n.h> +#include <glib.h> + +/* Glade callbacks */ +void +certs_manager_dialog_response_cb (GtkDialog *dialog, + gint response_id, + CertsManagerDialog *cm_dialog); +void +certs_manager_dialog_remove_button_clicked_cb (GtkButton *button, + CertsManagerDialog *dialog); +static void +tree_view_selection_changed_cb (GtkTreeSelection *selection, + CertsManagerDialog *dialog); + +static GObjectClass *parent_class = NULL; + +#define EPHY_CERTIFICATE_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_CERTS_MANAGER_DIALOG, CertsManagerDialogPrivate)) + +struct _CertsManagerDialogPrivate +{ + EphyCertificateManager *certs_manager; +}; + +enum +{ + RESPONSE_IMPORT = 1 +}; + +enum +{ + PROP_WINDOW, + PERSONAL_TREE_VIEW, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + SERVER_TREE_VIEW, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + CA_TREE_VIEW, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON +}; + +static const +EphyDialogProperty properties [] = +{ + { "certs_manager_dialog", NULL, PT_NORMAL, 0 }, + { "personal_treeview", NULL, PT_NORMAL, 0 }, + { "personal_remove_button", NULL, PT_NORMAL, 0 }, + { "personal_view_button", NULL, PT_NORMAL, 0 }, + { "personal_export_button", NULL, PT_NORMAL, 0 }, + { "server_treeview", NULL, PT_NORMAL, 0 }, + { "server_remove_button", NULL, PT_NORMAL, 0 }, + { "server_view_button", NULL, PT_NORMAL, 0 }, + { "server_props_button", NULL, PT_NORMAL, 0 }, + { "ca_treeview", NULL, PT_NORMAL, 0 }, + { "ca_remove_button", NULL, PT_NORMAL, 0 }, + { "ca_view_button", NULL, PT_NORMAL, 0 }, + { "ca_props_button", NULL, PT_NORMAL, 0 }, + + { NULL } +}; + +enum +{ + COL_NAME, + COL_CERT, + N_COLUMNS +}; + +static void +init_tree_view (CertsManagerDialog *dialog, GtkTreeView *tree_view) +{ + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + GtkTreeViewColumn * column; + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_set_headers_visible (tree_view, TRUE); + gtk_tree_view_insert_column_with_attributes (tree_view, + -1, + _("Name"), + renderer, + "text", COL_NAME, + NULL); + column = gtk_tree_view_get_column (tree_view, COL_NAME); + gtk_tree_view_column_set_sort_column_id (column, COL_NAME); + selection = gtk_tree_view_get_selection (tree_view); + g_signal_connect (selection, + "changed", + G_CALLBACK (tree_view_selection_changed_cb), + dialog); + + +} + + +static void +append_cert (EphyX509Cert* cert, GtkListStore *list_store) +{ + GtkTreeIter iter; + const char *title; + + title = ephy_x509_cert_get_title (cert); + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + COL_NAME, title, + COL_CERT, cert, + -1); +} + +static void +fill_tree_view_from_list (GtkTreeView *tree_view, + GList *list) +{ + GtkListStore *list_store; + + list_store = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING, + G_TYPE_OBJECT); + g_list_foreach (list, (GFunc)append_cert, list_store); + gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL (list_store)); +} + +static void +set_buttons_sensitive (CertsManagerDialog *dialog, + gint button1, + gint button2, + gint button3, + gboolean value) +{ + GtkWidget *widget; + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button1].id); + gtk_widget_set_sensitive (widget, value); + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button2].id); + gtk_widget_set_sensitive (widget, value); + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button3].id); + gtk_widget_set_sensitive (widget, value); +} + + +static void +chooser_response_cb (EphyFileChooser *chooser, + int response, + CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv = dialog->priv; + if (response == GTK_RESPONSE_ACCEPT) + { + char *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); + + ephy_certificate_manager_import (priv->certs_manager, file); + + g_free (file); + } + + gtk_widget_destroy (GTK_WIDGET (chooser)); +} + +static void +import (GtkDialog *dialog, CertsManagerDialog *cm_dialog) +{ + EphyFileChooser *chooser; + + chooser = ephy_file_chooser_new (_("Import Certificate"), + GTK_WIDGET (dialog), + GTK_FILE_CHOOSER_ACTION_OPEN, + NULL, + EPHY_FILE_FILTER_ALL); + + g_signal_connect (chooser, "response", G_CALLBACK (chooser_response_cb), cm_dialog); + + gtk_widget_show (GTK_WIDGET (chooser)); +} + +void +certs_manager_dialog_response_cb (GtkDialog *widget, + int response, + CertsManagerDialog *dialog) +{ + if (response == GTK_RESPONSE_HELP) + { + /* TODO open help */ + return; + } + else if (response == RESPONSE_IMPORT) + { + import (widget, dialog); + return; + } + + g_object_unref (dialog); +} + +void +certs_manager_dialog_remove_button_clicked_cb (GtkButton *button, + CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv = dialog->priv; + GtkTreeView *tree_view = NULL; + GtkTreeModel *model; + GtkTreeSelection *tree_selection; + EphyDialog *ephy_dialog; + GtkButton *personal_button; + GtkButton *server_button; + GtkButton *ca_button; + GList *selected_list, *remove_list = NULL, *l, *r; + GtkTreeIter iter; + GtkTreePath *path; + + ephy_dialog = EPHY_DIALOG (dialog); + personal_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_REMOVE_BUTTON].id)); + server_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_REMOVE_BUTTON].id)); + ca_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[CA_REMOVE_BUTTON].id)); + if (button == personal_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_TREE_VIEW].id)); + else if (button == server_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_TREE_VIEW].id)); + else if (button == ca_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[CA_TREE_VIEW].id)); + g_assert (tree_view != NULL); + tree_selection = gtk_tree_view_get_selection (tree_view); + selected_list = gtk_tree_selection_get_selected_rows (tree_selection, &model); + + for (l = selected_list; l != NULL; l = l->next) + { + remove_list = g_list_prepend (remove_list, + gtk_tree_row_reference_new (model, + (GtkTreePath *)l->data)); + } + for (r = remove_list; r != NULL; r = r->next) + { + EphyX509Cert *cert; + GValue val = {0, }; + path = gtk_tree_row_reference_get_path ((GtkTreeRowReference *)r->data); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get_value (model, &iter, COL_CERT, &val); + cert = EPHY_X509_CERT (g_value_dup_object (&val)); + g_value_unset (&val); + + // TODO check return value and notify if an error ocurred + ephy_certificate_manager_remove_certificate (priv->certs_manager, + cert); + g_object_unref (cert); + + gtk_list_store_remove (GTK_LIST_STORE (model), + &iter); + + gtk_tree_row_reference_free ((GtkTreeRowReference *)r->data); + gtk_tree_path_free (path); + } + g_list_free (selected_list); + g_list_free (remove_list); +} + +static void +tree_view_selection_changed_cb (GtkTreeSelection *selection, + CertsManagerDialog *dialog) +{ + gint count; + EphyDialog *ephy_dialog; + GtkTreeView *tree_view; + GtkTreeView *personal_tree_view; + GtkTreeView *server_tree_view; + GtkTreeView *ca_tree_view; + gboolean has_selection; + + ephy_dialog = EPHY_DIALOG (dialog); + tree_view = gtk_tree_selection_get_tree_view (selection); + personal_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_TREE_VIEW].id)); + server_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_TREE_VIEW].id)); + ca_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[CA_TREE_VIEW].id)); + count = gtk_tree_selection_count_selected_rows (selection); + has_selection = count == 0 ? FALSE : TRUE; + if (tree_view == personal_tree_view) + set_buttons_sensitive (dialog, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + has_selection); + else if (tree_view == server_tree_view) + set_buttons_sensitive (dialog, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + has_selection); + else if (tree_view == ca_tree_view) + set_buttons_sensitive (dialog, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON, + has_selection); +} + + +static void +certs_manager_dialog_init (CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv; + EphyEmbedShell *shell; + GtkWidget *window; + GtkTreeView *personal_treeview; + GtkTreeView *server_treeview; + GtkTreeView *ca_treeview; + GList *personalCerts; + GList *serverCerts; + GList *caCerts; + GtkWidget *button; + + priv = dialog->priv = EPHY_CERTIFICATE_MANAGER_GET_PRIVATE (dialog); + + shell = ephy_embed_shell_get_default (); + g_object_ref (shell); + + priv->certs_manager = EPHY_CERTIFICATE_MANAGER (ephy_embed_shell_get_embed_single (shell)); + + ephy_dialog_construct (EPHY_DIALOG (dialog), + properties, + ephy_file ("certs-manager.glade"), + "certs_manager_dialog", + NULL); + + window = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[PROP_WINDOW].id); + g_signal_connect (window, "response", + G_CALLBACK (certs_manager_dialog_response_cb), dialog); + + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[PERSONAL_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[CA_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[SERVER_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + + /* disabling buttons until a certificate is selected */ + set_buttons_sensitive (dialog, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + FALSE); + set_buttons_sensitive (dialog, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + FALSE); + set_buttons_sensitive (dialog, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON, + FALSE); + + /* filling personal treeview */ + personalCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + PERSONAL_CERTIFICATE); + + personal_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[PERSONAL_TREE_VIEW].id)); + init_tree_view (dialog, personal_treeview); + fill_tree_view_from_list (personal_treeview, personalCerts); + /* filling server treeview */ + serverCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + SERVER_CERTIFICATE); + server_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[SERVER_TREE_VIEW].id)); + init_tree_view (dialog, server_treeview); + fill_tree_view_from_list (server_treeview, serverCerts); + /* filling ca treeview */ + caCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + CA_CERTIFICATE); + ca_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[CA_TREE_VIEW].id)); + init_tree_view (dialog, ca_treeview); + fill_tree_view_from_list (ca_treeview, caCerts); + + g_list_foreach (personalCerts, (GFunc)g_object_unref, NULL); + g_list_free (personalCerts); + + g_list_foreach (serverCerts, (GFunc)g_object_unref, NULL); + g_list_free (serverCerts); + + g_list_foreach (caCerts, (GFunc)g_object_unref, NULL); + g_list_free (caCerts); +} + +static void +certs_manager_dialog_finalize (GObject *object) +{ + //CertsManagerDialog *dialog = EPHY_CERTS_MANAGER_DIALOG (object); + //CertsManagerDialogPrivate *priv = dialog->priv; + EphyEmbedShell *shell; + + /* TODO free certs in the treeviews */ + + G_OBJECT_CLASS (parent_class)->finalize (object); + + shell = ephy_embed_shell_get_default (); + g_object_unref (shell); +} + +static void +certs_manager_dialog_class_init (CertsManagerDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = certs_manager_dialog_finalize; + + g_type_class_add_private (object_class, sizeof (CertsManagerDialogPrivate)); +} + +/* public functions */ + +GType +certs_manager_dialog_get_type (void) +{ + static GType certs_manager_dialog_type = 0; + + if (certs_manager_dialog_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (CertsManagerDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) certs_manager_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (CertsManagerDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) certs_manager_dialog_init + }; + + certs_manager_dialog_type = g_type_register_static (EPHY_TYPE_DIALOG, + "CertsManagerDialog", + &our_info, 0); + } + + return certs_manager_dialog_type; + +} + +EphyDialog * +certs_manager_dialog_new (void) +{ + return g_object_new (EPHY_TYPE_CERTS_MANAGER_DIALOG, NULL); +} diff --git a/src/ephy-certificate-manager.h b/src/ephy-certificate-manager.h new file mode 100644 index 000000000..507dbfdef --- /dev/null +++ b/src/ephy-certificate-manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2003 Robert Marcano + * + * 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, 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-1307, USA. + * + * $Id$ + */ + +#ifndef CERTS_MANAGER_DIALOG_H +#define CERTS_MANAGER_DIALOG_H + +#include <glib.h> +#include "ephy-dialog.h" + +G_BEGIN_DECLS + +#define EPHY_TYPE_CERTS_MANAGER_DIALOG (certs_manager_dialog_get_type ()) +#define EPHY_CERTS_MANAGER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_CERTS_MANAGER_DIALOG, CertsManagerDialog)) +#define EPHY_CERTS_MANAGER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_CERTS_MANAGER_DIALOG, CertsManagerDialogClass)) +#define EPHY_IS_CERTS_MANAGER_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_CERTS_MANAGER_DIALOG)) +#define EPHY_IS_CERTS_MANAGER_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_CERTS_MANAGER_DIALOG)) +#define EPHY_CERTS_MANAGER_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_CERTS_MANAGER_DIALOG, CertsManagerDialogClass)) + +typedef struct _CertsManagerDialogClass CertsManagerDialogClass; +typedef struct _CertsManagerDialog CertsManagerDialog; +typedef struct _CertsManagerDialogPrivate CertsManagerDialogPrivate; + +struct _CertsManagerDialogClass +{ + EphyDialogClass parent_class; +}; + +struct _CertsManagerDialog +{ + EphyDialog parent; + + /*< private >*/ + CertsManagerDialogPrivate *priv; +}; + +GType certs_manager_dialog_get_type (void); + +EphyDialog *certs_manager_dialog_new (void); + +G_END_DECLS + +#endif diff --git a/src/ephy-window.c b/src/ephy-window.c index 87cb491f8..0a6b64e1b 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -185,6 +185,11 @@ static const GtkActionEntry ephy_menu_entries [] = { { "EditPersonalData", NULL, N_("P_ersonal Data"), NULL, N_("View and remove cookies and passwords"), G_CALLBACK (window_cmd_edit_personal_data) }, +#ifdef ENABLE_CERTIFICATE_MANAGER + { "EditCertificates", NULL, N_("Cert_ificates"), NULL, + N_("Manage Certificates"), + G_CALLBACK (window_cmd_edit_certificates) }, +#endif { "EditToolbar", NULL, N_("T_oolbars"), NULL, N_("Customize toolbars"), G_CALLBACK (window_cmd_edit_toolbar) }, @@ -3085,6 +3090,16 @@ ephy_window_constructor (GType type, g_warning ("Could not merge epiphany-ui.xml: %s", error->message); g_error_free (error); } +#if ENABLE_CERTIFICATE_MANAGER +{ + guint ui_id; + ui_id = gtk_ui_manager_new_merge_id (priv->manager); + gtk_ui_manager_add_ui (priv->manager, ui_id, + "/menubar/EditMenu/EditPersonalDataMenu", + "EditCertificates", "EditCertificates", + GTK_UI_MANAGER_MENUITEM, FALSE); +} +#endif /* Initialize the menus */ priv->tabs_menu = ephy_tabs_menu_new (window); diff --git a/src/window-commands.c b/src/window-commands.c index 68d0dc710..e3fc9d3d6 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -670,6 +670,23 @@ window_cmd_edit_personal_data (GtkAction *action, } } +#ifdef ENABLE_CERTIFICATE_MANAGER + +#include "ephy-certificate-manager.h" + +void +window_cmd_edit_certificates (GtkAction *action, + EphyWindow *window) +{ + EphyDialog *dialog; + + dialog = certs_manager_dialog_new (); + + ephy_dialog_show (dialog); +} + +#endif /* ENABLE_CERTIFICATE_MANAGER */ + void window_cmd_edit_prefs (GtkAction *action, EphyWindow *window) diff --git a/src/window-commands.h b/src/window-commands.h index 8043bda59..fa8607808 100644 --- a/src/window-commands.h +++ b/src/window-commands.h @@ -124,6 +124,9 @@ void window_cmd_go_history (GtkAction *action, void window_cmd_edit_personal_data (GtkAction *action, EphyWindow *window); +void window_cmd_edit_certificates (GtkAction *action, + EphyWindow *window); + void window_cmd_edit_prefs (GtkAction *action, EphyWindow *window); |