2006-12-06 [colin] 2.6.1cvs8

* src/ssl_manager.c
	* src/common/ssl_certificate.c
	* src/common/ssl_certificate.h
		Handle multiple certificates per host/port
This commit is contained in:
Colin Leroy 2006-12-06 07:24:40 +00:00
parent ce55e98a7d
commit 3919ee03e3
6 changed files with 118 additions and 25 deletions

View file

@ -1,3 +1,10 @@
2006-12-06 [colin] 2.6.1cvs8
* src/ssl_manager.c
* src/common/ssl_certificate.c
* src/common/ssl_certificate.h
Handle multiple certificates per host/port
2006-12-06 [colin] 2.6.1cvs7
* src/etpan/imap-thread.c

View file

@ -2115,3 +2115,4 @@
( cvs diff -u -r 1.3.12.20 -r 1.3.12.21 src/message_search.c; cvs diff -u -r 1.15.2.38 -r 1.15.2.39 src/summary_search.c; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/gtk/combobox.c; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 src/gtk/combobox.h; cvs diff -u -r 1.5.2.45 -r 1.5.2.46 src/gtk/gtkutils.c; cvs diff -u -r 1.4.2.27 -r 1.4.2.28 src/gtk/gtkutils.h; ) > 2.6.1cvs5.patchset
( cvs diff -u -r 1.207.2.136 -r 1.207.2.137 src/folderview.c; ) > 2.6.1cvs6.patchset
( cvs diff -u -r 1.1.4.58 -r 1.1.4.59 src/etpan/imap-thread.c; ) > 2.6.1cvs7.patchset
( cvs diff -u -r 1.3.2.23 -r 1.3.2.24 src/ssl_manager.c; cvs diff -u -r 1.4.2.13 -r 1.4.2.14 src/common/ssl_certificate.c; cvs diff -u -r 1.1.4.5 -r 1.1.4.6 src/common/ssl_certificate.h; ) > 2.6.1cvs8.patchset

View file

@ -11,7 +11,7 @@ MINOR_VERSION=6
MICRO_VERSION=1
INTERFACE_AGE=0
BINARY_AGE=0
EXTRA_VERSION=7
EXTRA_VERSION=8
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=

View file

@ -128,6 +128,8 @@ SSLCertificate *ssl_certificate_new(X509 *x509_cert, gchar *host, gushort port)
static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert, gchar *host, gushort port, gboolean lookup)
{
SSLCertificate *cert = g_new0(SSLCertificate, 1);
unsigned int n;
unsigned char md[EVP_MAX_MD_SIZE];
if (host == NULL || x509_cert == NULL) {
ssl_certificate_destroy(cert);
@ -139,6 +141,11 @@ static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert, gchar *host,
else
cert->host = g_strdup(host);
cert->port = port;
/* fingerprint */
X509_digest(cert->x509_cert, EVP_md5(), md, &n);
cert->fingerprint = readable_fingerprint(md, (int)n);
return cert;
}
@ -157,7 +164,7 @@ static void ssl_certificate_save (SSLCertificate *cert)
port = g_strdup_printf("%d", cert->port);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
cert->host, ".", port, ".cert", NULL);
cert->host, ".", port, ".", cert->fingerprint, ".cert", NULL);
g_free(port);
fp = g_fopen(file, "wb");
@ -261,6 +268,7 @@ void ssl_certificate_destroy(SSLCertificate *cert)
if (cert->x509_cert)
X509_free(cert->x509_cert);
g_free(cert->host);
g_free(cert->fingerprint);
g_free(cert);
cert = NULL;
}
@ -272,25 +280,26 @@ void ssl_certificate_delete_from_disk(SSLCertificate *cert)
buf = g_strdup_printf("%d", cert->port);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
cert->host, ".", buf, ".cert", NULL);
cert->host, ".", buf, ".", cert->fingerprint, ".cert", NULL);
g_unlink (file);
g_free(buf);
g_free(file);
g_free(buf);
}
SSLCertificate *ssl_certificate_find (gchar *host, gushort port)
SSLCertificate *ssl_certificate_find (gchar *host, gushort port, const gchar *fingerprint)
{
return ssl_certificate_find_lookup (host, port, TRUE);
return ssl_certificate_find_lookup (host, port, fingerprint, TRUE);
}
SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, gboolean lookup)
SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, const gchar *fingerprint, gboolean lookup)
{
gchar *file;
gchar *file = NULL;
gchar *buf;
gchar *fqdn_host;
SSLCertificate *cert = NULL;
X509 *tmp_x509;
FILE *fp;
FILE *fp = NULL;
gboolean must_rename = FALSE;
if (lookup)
fqdn_host = get_fqdn(host);
@ -298,27 +307,52 @@ SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, gboolean
fqdn_host = g_strdup(host);
buf = g_strdup_printf("%d", port);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
if (fingerprint != NULL) {
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
fqdn_host, ".", buf, ".", fingerprint, ".cert", NULL);
fp = g_fopen(file, "rb");
}
if (fp == NULL) {
/* see if we have the old one */
g_free(file);
file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
fqdn_host, ".", buf, ".cert", NULL);
fp = g_fopen(file, "rb");
g_free(buf);
fp = g_fopen(file, "rb");
if (fp)
must_rename = (fingerprint != NULL);
}
if (fp == NULL) {
g_free(file);
g_free(fqdn_host);
g_free(buf);
return NULL;
}
if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) {
cert = ssl_certificate_new_lookup(tmp_x509, fqdn_host, port, lookup);
X509_free(tmp_x509);
}
fclose(fp);
g_free(file);
g_free(fqdn_host);
if (must_rename) {
gchar *old = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
fqdn_host, ".", buf, ".cert", NULL);
gchar *new = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
"certs", G_DIR_SEPARATOR_S,
fqdn_host, ".", buf, ".", fingerprint, ".cert", NULL);
move_file(old, new, TRUE);
g_free(old);
g_free(new);
}
g_free(buf);
g_free(fqdn_host);
return cert;
}
@ -370,7 +404,10 @@ gboolean ssl_certificate_check (X509 *x509_cert, gchar *fqdn, gchar *host, gusho
SSLCertificate *known_cert;
SSLCertHookData cert_hook_data;
gchar *fqdn_host = NULL;
gchar *fingerprint;
unsigned int n;
unsigned char md[EVP_MAX_MD_SIZE];
if (fqdn)
fqdn_host = g_strdup(fqdn);
else if (host)
@ -388,8 +425,13 @@ gboolean ssl_certificate_check (X509 *x509_cert, gchar *fqdn, gchar *host, gusho
return FALSE;
}
known_cert = ssl_certificate_find_lookup (fqdn_host, port, FALSE);
/* fingerprint */
X509_digest(x509_cert, EVP_md5(), md, &n);
fingerprint = readable_fingerprint(md, (int)n);
known_cert = ssl_certificate_find_lookup (fqdn_host, port, fingerprint, FALSE);
g_free(fingerprint);
g_free(fqdn_host);
if (known_cert == NULL) {

View file

@ -40,6 +40,7 @@ struct _SSLCertificate
X509 *x509_cert;
gchar *host;
gushort port;
gchar *fingerprint;
};
typedef struct _SSLCertHookData SSLCertHookData;
@ -52,8 +53,8 @@ struct _SSLCertHookData
gboolean accept;
};
SSLCertificate *ssl_certificate_find (gchar *host, gushort port);
SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, gboolean lookup);
SSLCertificate *ssl_certificate_find (gchar *host, gushort port, const gchar *fingerprint);
SSLCertificate *ssl_certificate_find_lookup (gchar *host, gushort port, const gchar *fingerprint, gboolean lookup);
gboolean ssl_certificate_check (X509 *x509_cert, gchar *fqdn, gchar *host, gushort port);
char* ssl_certificate_to_string(SSLCertificate *cert);
void ssl_certificate_destroy(SSLCertificate *cert);

View file

@ -211,16 +211,24 @@ void ssl_manager_create(void)
static char *get_server(char *str)
{
char *ret = NULL, *tmp = g_strdup(str);
char *first_pos = NULL, *last_pos = NULL, *previous_pos = NULL;
char *first_pos = NULL, *last_pos = NULL;
char *previous_pos = NULL, *pre_previous_pos = NULL;
int previous_dot_pos;
if (!strchr(tmp, ':')) {
/* no fingerprint */
if (strstr(tmp, ".cert"))
*(strstr(tmp, ".cert")+1) = '.';
}
first_pos = tmp;
while (tmp && (tmp = strstr(tmp,".")) != NULL) {
tmp++;
pre_previous_pos = previous_pos;
previous_pos = last_pos;
last_pos = tmp;
}
previous_dot_pos = (previous_pos - first_pos);
previous_dot_pos = (pre_previous_pos - first_pos);
if (previous_dot_pos - 1 > 0)
ret = g_strndup(first_pos, previous_dot_pos - 1);
else
@ -230,10 +238,43 @@ static char *get_server(char *str)
}
static char *get_port(char *str)
{
char *ret = NULL, *tmp = g_strdup(str);
char *last_pos = NULL;
char *previous_pos = NULL, *pre_previous_pos = NULL;
if (!strchr(tmp, ':')) {
/* no fingerprint */
if (strstr(tmp, ".cert"))
*(strstr(tmp, ".cert")+1) = '.';
}
while (tmp && (tmp = strstr(tmp,".")) != NULL) {
tmp++;
pre_previous_pos = previous_pos;
previous_pos = last_pos;
last_pos = tmp;
}
if (previous_pos && pre_previous_pos && (int)(previous_pos - pre_previous_pos - 1) > 0)
ret = g_strndup(pre_previous_pos, (int)(previous_pos - pre_previous_pos - 1));
else
ret = g_strdup("0");
g_free(tmp);
return ret;
}
static char *get_fingerprint(char *str)
{
char *ret = NULL, *tmp = g_strdup(str);
char *previous_pos = NULL, *last_pos = NULL;
if (!strchr(tmp, ':')) {
/* no fingerprint */
if (strstr(tmp, ".cert"))
*(strstr(tmp, ".cert")+1) = '.';
}
while (tmp && (tmp = strstr(tmp,".")) != NULL) {
tmp++;
previous_pos = last_pos;
@ -242,7 +283,7 @@ static char *get_port(char *str)
if (last_pos && previous_pos && (int)(last_pos - previous_pos - 1) > 0)
ret = g_strndup(previous_pos, (int)(last_pos - previous_pos - 1));
else
ret = g_strdup("0");
ret = NULL;
g_free(tmp);
return ret;
@ -297,7 +338,7 @@ static void ssl_manager_load_certs (void)
}
while ((d = readdir(dir)) != NULL) {
gchar *server, *port;
gchar *server, *port, *fp;
SSLCertificate *cert;
if(!strstr(d->d_name, ".cert"))
@ -305,15 +346,16 @@ static void ssl_manager_load_certs (void)
server = get_server(d->d_name);
port = get_port(d->d_name);
fp = get_fingerprint(d->d_name);
cert = ssl_certificate_find_lookup(server, atoi(port), FALSE);
cert = ssl_certificate_find_lookup(server, atoi(port), fp, FALSE);
ssl_manager_list_view_insert_cert(manager.certlist, NULL,
server, port, cert);
g_free(server);
g_free(port);
g_free(fp);
row++;
}
closedir(dir);