Example #1
0
static void
ssl_gnutls_init_gnutls(void)
{
	/* Configure GnuTLS to use glib memory management */
	/* I expect that this isn't really necessary, but it may prevent
	   some bugs */
	/* TODO: It may be necessary to wrap this allocators for GnuTLS.
	   If there are strange bugs, perhaps look here (yes, I am a
	   hypocrite) */
	gnutls_global_set_mem_functions(
		(gnutls_alloc_function)   g_malloc, /* malloc */
		(gnutls_alloc_function)   g_malloc, /* secure malloc */
		NULL,      /* mem_is_secure */
		(gnutls_realloc_function) g_realloc, /* realloc */
		(gnutls_free_function)    g_free     /* free */
		);

	gnutls_global_init();

	gnutls_certificate_allocate_credentials(&xcred);

	/* TODO: I can likely remove this */
	gnutls_certificate_set_x509_trust_file(xcred, "ca.pem",
		GNUTLS_X509_FMT_PEM);
}
Example #2
0
G_GNUC_COLD void
tls_global_init(void)
{
    static const struct {
        const char * const name;
        const int major;
        const int minor;
    } f = {
        "tls", 1, 0
    };
    char *cert_file, *key_file;

#if !defined(REMAP_ZALLOC) && !defined(TRACK_MALLOC) && !defined(TRACK_ZALLOC)
    gnutls_global_set_mem_functions(halloc, halloc, NULL, hrealloc, hfree);
#endif

    if (gnutls_global_init()) {
        g_error("gnutls_global_init() failed");
    }

#ifdef USE_TLS_CUSTOM_IO
    gnutls_global_set_log_level(9);
    gnutls_global_set_log_function(tls_log_function);
#endif	/* USE_TLS_CUSTOM_IO */

    get_dh_params();
    gnutls_certificate_allocate_credentials(&cert_cred);

    key_file = make_pathname(settings_config_dir(), "key.pem");
    cert_file = make_pathname(settings_config_dir(), "cert.pem");

    if (file_exists(key_file) && file_exists(cert_file)) {
        int ret;

        ret = gnutls_certificate_set_x509_key_file(cert_cred,
                cert_file, key_file, GNUTLS_X509_FMT_PEM);
        if (ret < 0) {
            g_warning("gnutls_certificate_set_x509_key_file() failed: %s",
                      gnutls_strerror(ret));
        } else {
            gnutls_certificate_set_dh_params(cert_cred, get_dh_params());
        }
    }
    HFREE_NULL(key_file);
    HFREE_NULL(cert_file);

    header_features_add(FEATURES_CONNECTIONS, f.name, f.major, f.minor);
    header_features_add(FEATURES_G2_CONNECTIONS, f.name, f.major, f.minor);
    header_features_add(FEATURES_DOWNLOADS, f.name, f.major, f.minor);
    header_features_add(FEATURES_UPLOADS, f.name, f.major, f.minor);
}
Example #3
0
static void
ssl_gnutls_init_gnutls(void)
{
	const char *debug_level;
	const char *host_priorities_str;

	/* Configure GnuTLS to use glib memory management */
	/* I expect that this isn't really necessary, but it may prevent
	   some bugs */
	/* TODO: It may be necessary to wrap this allocators for GnuTLS.
	   If there are strange bugs, perhaps look here (yes, I am a
	   hypocrite) */
	gnutls_global_set_mem_functions(
		(gnutls_alloc_function)   g_malloc, /* malloc */
		(gnutls_alloc_function)   g_malloc, /* secure malloc */
		NULL,      /* mem_is_secure */
		(gnutls_realloc_function) g_realloc, /* realloc */
		(gnutls_free_function)    g_free     /* free */
		);

	debug_level = g_getenv("PURPLE_GNUTLS_DEBUG");
	if (debug_level) {
		int level = atoi(debug_level);
		if (level < 0) {
			purple_debug_warning("gnutls", "Assuming log level 0 instead of %d\n",
			                     level);
			level = 0;
		}

		/* "The level is an integer between 0 and 9. Higher values mean more verbosity." */
		gnutls_global_set_log_level(level);
		gnutls_global_set_log_function(ssl_gnutls_log);
	}

	/* Expected format: host=priority;host2=priority;*=priority
	 * where "*" is used to override the default priority string for
	 * libpurple.
	 */
	host_priorities_str = g_getenv("PURPLE_GNUTLS_PRIORITIES");
	if (host_priorities_str) {
#ifndef HAVE_GNUTLS_PRIORITY_FUNCS
		purple_debug_warning("gnutls", "Warning, PURPLE_GNUTLS_PRIORITIES "
		                     "environment variable set, but we were built "
		                     "against an older GnuTLS that doesn't support "
		                     "this. :-(");
#else /* HAVE_GNUTLS_PRIORITY_FUNCS */
		char **entries = g_strsplit(host_priorities_str, ";", -1);
		char *default_priority_str = NULL;
		guint i;

		host_priorities = g_hash_table_new_full(g_str_hash, g_str_equal,
		                                        g_free, g_free);

		for (i = 0; entries[i]; ++i) {
			char *host = entries[i];
			char *equals = strchr(host, '=');
			char *prio_str;

			if (equals) {
				*equals = '\0';
				prio_str = equals + 1;

				/* Empty? */
				if (*prio_str == '\0') {
					purple_debug_warning("gnutls", "Ignoring empty priority "
					                               "string for %s\n", host);
				} else {
					/* TODO: Validate each of these and complain */
					if (g_str_equal(host, "*")) {
						/* Override the default priority */
						g_free(default_priority_str);
						default_priority_str = g_strdup(prio_str);
					} else
						g_hash_table_insert(host_priorities, g_strdup(host),
						                    g_strdup(prio_str));
				}
			}
		}

		if (default_priority_str) {
			if (gnutls_priority_init(&default_priority, default_priority_str, NULL)) {
				purple_debug_warning("gnutls", "Unable to set default priority to %s\n",
				                     default_priority_str);
				/* Versions of GnuTLS as of 2.8.6 (2010-03-31) don't free/NULL
				 * this on error.
				 */
				gnutls_free(default_priority);
				default_priority = NULL;
			}

			g_free(default_priority_str);
		}

		g_strfreev(entries);
#endif /* HAVE_GNUTLS_PRIORITY_FUNCS */
	}

#ifdef HAVE_GNUTLS_PRIORITY_FUNCS
	/* Make sure we set have a default priority! */
	if (!default_priority) {
		if (gnutls_priority_init(&default_priority, "NORMAL:%SSL3_RECORD_VERSION", NULL)) {
			/* See comment above about memory leak */
			gnutls_free(default_priority);
			gnutls_priority_init(&default_priority, "NORMAL", NULL);
		}
	}
#endif /* HAVE_GNUTLS_PRIORITY_FUNCS */

	gnutls_global_init();

	gnutls_certificate_allocate_credentials(&xcred);

	/* TODO: I can likely remove this */
	gnutls_certificate_set_x509_trust_file(xcred, "ca.pem",
		GNUTLS_X509_FMT_PEM);
}