Made the gnutls password encryption work on Win32.
authorAndrej Kacian <ticho@claws-mail.org>
Fri, 19 Feb 2016 23:27:47 +0000 (00:27 +0100)
committerAndrej Kacian <ticho@claws-mail.org>
Fri, 19 Feb 2016 23:28:40 +0000 (00:28 +0100)
src/mh.c
src/password.c
src/password_gtk.c

index 0736e58e08b903a59d76a21e63f4b2ac787f83ea..913a41c9a6c0e3c88e0d86e4ef9240b845c8dda1 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -791,7 +791,7 @@ static gint mh_create_tree(Folder *folder)
        rootpath = LOCAL_FOLDER(folder)->rootpath;
 #ifdef G_OS_UNIX
        if (*rootpath == '/') {
-#elif G_OS_WIN32
+#elif defined G_OS_WIN32
        if (g_ascii_isalpha(*rootpath) && !strncmp(rootpath + 1, "\:", 2)) {
 #endif
                /* Folder path is absolute. */
index 4f9ee16e38646d9aa7bc690bd04b97a5fc5da1fd..7e37e28750b92a7a98c899ab70799775dce60a35 100644 (file)
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
 #include <fcntl.h>
 #include <unistd.h>
+#elif defined G_OS_WIN32
+#include <windows.h>
+#include <wincrypt.h>
 #endif
 
 #include "common/passcrypt.h"
@@ -271,8 +274,10 @@ gchar *password_encrypt_gnutls(const gchar *password,
        gnutls_datum_t key, iv;
        int ivlen, keylen, digestlen, blocklen, ret, i;
        unsigned char hashbuf[BUFSIZE], *buf, *encbuf, *base, *output;
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
        int rnd;
+#elif defined G_OS_WIN32
+       HCRYPTPROV rnd;
 #endif
 
        g_return_val_if_fail(password != NULL, NULL);
@@ -299,38 +304,48 @@ gchar *password_encrypt_gnutls(const gchar *password,
        memcpy(key.data, &hashbuf, keylen);
        key.size = keylen;
 
-#ifdef G_OS_UNIX
        /* Prepare our source of random data. */
+#if defined G_OS_UNIX
        rnd = open("/dev/urandom", O_RDONLY);
        if (rnd == -1) {
                perror("fopen on /dev/urandom");
+#elif defined G_OS_WIN32
+       if (!CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, 0) &&
+                       !CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
+               debug_print("Could not acquire a CSP handle.\n");
+#endif
                g_free(key.data);
                g_free(iv.data);
                return NULL;
        }
-#endif
 
        /* Prepare random IV for cipher */
        iv.data = malloc(ivlen);
        iv.size = ivlen;
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
        ret = read(rnd, iv.data, ivlen);
        if (ret != ivlen) {
                perror("read into iv");
+               close(rnd);
+#elif defined G_OS_WIN32
+       if (!CryptGenRandom(rnd, ivlen, iv.data)) {
+               debug_print("Could not read random data for IV\n");
+               CryptReleaseContext(rnd, 0);
+#endif
                g_free(key.data);
                g_free(iv.data);
-               close(rnd);
                return NULL;
        }
-#endif
 
        /* Initialize the encryption */
        ret = gnutls_cipher_init(&handle, algo, &key, &iv);
        if (ret < 0) {
                g_free(key.data);
                g_free(iv.data);
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
                close(rnd);
+#elif defined G_OS_WIN32
+               CryptReleaseContext(rnd, 0);
 #endif
                return NULL;
        }
@@ -339,20 +354,28 @@ gchar *password_encrypt_gnutls(const gchar *password,
         * rest with zero bytes. */
        buf = malloc(BUFSIZE + blocklen);
        memset(buf, 0, BUFSIZE);
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
        ret = read(rnd, buf, blocklen);
        if (ret != blocklen) {
                perror("read into buffer");
+               close(rnd);
+#elif defined G_OS_WIN32
+       if (!CryptGenRandom(rnd, blocklen, buf)) {
+               debug_print("Could not read random data for IV\n");
+               CryptReleaseContext(rnd, 0);
+#endif
                g_free(buf);
                g_free(key.data);
                g_free(iv.data);
-               close(rnd);
                gnutls_cipher_deinit(handle);
                return NULL;
        }
 
        /* We don't need any more random data. */
+#if defined G_OS_UNIX
        close(rnd);
+#elif defined G_OS_WIN32
+       CryptReleaseContext(rnd, 0);
 #endif
 
        memcpy(buf + blocklen, password, strlen(password));
@@ -398,8 +421,10 @@ gchar *password_decrypt_gnutls(const gchar *password,
        int ivlen, keylen, digestlen, blocklen, ret, i;
        gsize len;
        unsigned char hashbuf[BUFSIZE], *buf;
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
        int rnd;
+#elif defined G_OS_WIN32
+       HCRYPTPROV rnd;
 #endif
 
        g_return_val_if_fail(password != NULL, NULL);
@@ -452,34 +477,46 @@ gchar *password_decrypt_gnutls(const gchar *password,
        memcpy(key.data, &hashbuf, keylen);
        key.size = keylen;
 
-#ifdef G_OS_UNIX
        /* Prepare our source of random data. */
+#if defined G_OS_UNIX
        rnd = open("/dev/urandom", O_RDONLY);
        if (rnd == -1) {
                perror("fopen on /dev/urandom");
+#elif defined G_OS_WIN32
+       if (!CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, 0) &&
+                       !CryptAcquireContext(&rnd, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
+               debug_print("Could not acquire a CSP handle.\n");
+#endif
                g_free(key.data);
                g_free(iv.data);
                g_strfreev(tokens);
                return NULL;
        }
-#endif
 
        /* Prepare random IV for cipher */
        iv.data = malloc(ivlen);
        iv.size = ivlen;
-#ifdef G_OS_UNIX
+#if defined G_OS_UNIX
        ret = read(rnd, iv.data, ivlen);
        if (ret != ivlen) {
                perror("read into iv");
+               close(rnd);
+#elif defined G_OS_WIN32
+       if (!CryptGenRandom(rnd, ivlen, iv.data)) {
+               debug_print("Could not read random data for IV\n");
+               CryptReleaseContext(rnd, 0);
+#endif
                g_free(key.data);
                g_free(iv.data);
                g_strfreev(tokens);
-               close(rnd);
                return NULL;
        }
 
        /* We don't need any more random data. */
+#if defined G_OS_UNIX
        close(rnd);
+#elif defined G_OS_WIN32
+       CryptReleaseContext(rnd, 0);
 #endif
 
        /* Prepare encrypted password string for decryption. */
index 683acbe215cccebb0a92bce08235592fa6b34e79..41bb7f5661ec71393bbf20ee39fb55cabc96edce 100644 (file)
@@ -218,8 +218,6 @@ void master_password_change_dialog()
        while (!ctx->done)
                gtk_main_iteration();
 
-       manage_window_focus_out(dialog, NULL, NULL);
-
        if (ctx->dialog != NULL)
                gtk_widget_destroy(ctx->dialog);