diff options
Diffstat (limited to 'embed/mozilla')
-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 |
4 files changed, 488 insertions, 0 deletions
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 |