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:
parent
ce55e98a7d
commit
3919ee03e3
6 changed files with 118 additions and 25 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue