0.8.10claws70
authorChristoph Hohmann <reboot@gmx.ch>
Sun, 2 Mar 2003 16:29:07 +0000 (16:29 +0000)
committerChristoph Hohmann <reboot@gmx.ch>
Sun, 2 Mar 2003 16:29:07 +0000 (16:29 +0000)
* configure.ac
* src/prefs_account.c
* src/prefs_gtk.[ch]
* src/common/.cvsignore
* src/common/Makefile.am
* src/common/passcrypt.c                ** NEW **
* src/common/passcrypt.h.in             ** NEW **
        Implement password encryption in config files
        using unix encrypt and setkey functions. The crypt
        key can be set as a configure parameter. Old
        passwords will be converted if they do not begin
        with '!'

ChangeLog.claws
configure.ac
src/common/.cvsignore
src/common/Makefile.am
src/common/passcrypt.c [new file with mode: 0644]
src/common/passcrypt.h.in [new file with mode: 0644]
src/prefs_account.c
src/prefs_gtk.c
src/prefs_gtk.h

index 17a788cb6a312f098905c34163df95645a4a6e3b..4ebdbd872163baa611c6c487d35492044d15977a 100644 (file)
@@ -1,3 +1,18 @@
+2003-03-02 [christoph] 0.8.10claws70
+
+       * configure.ac
+       * src/prefs_account.c
+       * src/prefs_gtk.[ch]
+       * src/common/.cvsignore
+       * src/common/Makefile.am
+       * src/common/passcrypt.c                ** NEW **
+       * src/common/passcrypt.h.in             ** NEW **
+               Implement password encryption in config files
+               using unix encrypt and setkey functions. The crypt
+               key can be set as a configure parameter. Old
+               passwords will be converted if they do not begin
+               with '!'
+
 2003-03-02 [paul]      0.8.10claws69
 
        * src/prefs_account.c
index 74f871535d2db7f74d77812c9cdab06e780dad53..91529b85517ae7a7c011d7be46ceb9a0f15b0f9e 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=8
 MICRO_VERSION=10
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=claws69
+EXTRA_VERSION=claws70
 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
 
 dnl set $target
@@ -196,6 +196,11 @@ fi
 dnl Check for OpenSSL
 AM_PATH_OPENSSL
 
+dnl Key for password encryption
+AC_ARG_WITH(passcrypt-key, [  --with-passcrypt-key=KEY     Key used to encode passwords (8 byte string)],
+           with_passcrypt_key="$withval", with_passcrypt_key="passkey0")
+AC_SUBST(PASSCRYPT_KEY, $with_passcrypt_key)
+
 dnl ************************
 dnl ** GTK user interface **
 dnl ************************
@@ -398,6 +403,7 @@ po/Makefile.in
 src/common/version.h
 src/Makefile
 src/common/Makefile
+src/common/passcrypt.h
 src/gtk/Makefile
 src/plugins/Makefile
 src/plugins/demo/Makefile
index 88c98773142dcb2caa5620d3d731a0ad236dbc5f..3b03e8470d069891e472c3834d97b18073b4bce6 100644 (file)
@@ -6,3 +6,4 @@ version.h
 *.o
 *.lo
 *.la
+passcrypt.h
index e9de206bf17880bdeea59d363b04cd3c7fafe808..0a494ed1a5c1407bcd005efb038a6a111721258a 100644 (file)
@@ -9,6 +9,7 @@ libsylpheedcommon_la_SOURCES = \
        md5.c md5.h \
        mgutils.c mgutils.h \
        nntp.c nntp.h \
+       passcrypt.c passcrypt.h \
        plugin.c plugin.h \
        prefs.c prefs.h \
        quoted-printable.c quoted-printable.h \
@@ -33,7 +34,8 @@ CPPFLAGS = \
 
 libsylpheedcommon_la_LIBADD = \
        $(GLIB_LIBS) \
-       $(OPENSSL_LIBS)
+       $(OPENSSL_LIBS) \
+       -lcrypt
 
 EXTRA_DIST = \
        version.h.in
diff --git a/src/common/passcrypt.c b/src/common/passcrypt.c
new file mode 100644 (file)
index 0000000..74a8f06
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto and the Sylpheed-Claws Team
+ *
+ * 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 of the License, 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.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <memory.h>
+#include <ctype.h>
+#include <unistd.h>
+#include "crypt.h"
+
+#include <glib.h>
+
+#include "passcrypt.h"
+
+void crypt_cfb_buf(const char key[8], void *buf, unsigned len,
+                  unsigned chunksize, int decrypt);
+static void crypt_cfb_shift(unsigned char *to,
+                           const unsigned char *from, unsigned len);
+static void crypt_cfb_xor(unsigned char *to, const unsigned char *from,
+                         unsigned len);
+static void crypt_unpack(unsigned char *a);
+
+void passcrypt_encrypt(gchar *password, guint len)
+{
+       crypt_cfb_buf(PASSCRYPT_KEY, password, len, 1, 0 );
+}
+
+void passcrypt_decrypt(gchar *password, guint len)
+{
+       crypt_cfb_buf(PASSCRYPT_KEY, password, len, 1, 1 );
+}
+
+/*
+* crypt_cfb_iv is the intermediate vector used for cypher feedback encryption
+*/
+unsigned char crypt_cfb_iv[64];
+int crypt_cfb_blocksize = 8;   /* 8 for DES */
+
+void
+crypt_cfb_buf(const char key[8], void *buf, unsigned len,
+             unsigned chunksize, int decrypt)
+{
+       unsigned char temp[64];
+
+       memcpy(temp, key, 8);
+       crypt_unpack(temp);
+       setkey((const char *) temp);
+       memset(temp, 0, sizeof(temp));
+
+       memset(crypt_cfb_iv, 0, sizeof(crypt_cfb_iv));
+
+       if (chunksize > crypt_cfb_blocksize)
+               chunksize = crypt_cfb_blocksize;
+
+       while (len) {
+               memcpy(temp, crypt_cfb_iv, sizeof(temp));
+               encrypt((char *) temp, 0);
+               if (chunksize > len)
+                       chunksize = len;
+               if (decrypt)
+                       crypt_cfb_shift(crypt_cfb_iv,
+                                       (unsigned char *) buf, chunksize);
+               crypt_cfb_xor((unsigned char *) buf, temp, chunksize);
+               if (!decrypt)
+                       crypt_cfb_shift(crypt_cfb_iv,
+                                       (unsigned char *) buf, chunksize);
+               len -= chunksize;
+               buf += chunksize;
+       }
+}
+
+/*
+* Shift len bytes from end of to buffer to beginning, then put len
+* bytes from from at the end.  Caution: the to buffer is unpacked,
+* but the from buffer is not.
+*/
+static void
+crypt_cfb_shift(unsigned char *to, const unsigned char *from, unsigned len)
+{
+       unsigned i;
+       unsigned j;
+       unsigned k;
+
+       if (len < crypt_cfb_blocksize) {
+               i = len * 8;
+               j = crypt_cfb_blocksize * 8;
+               for (k = i; k < j; k++) {
+                       to[0] = to[i];
+                       ++to;
+               }
+       }
+
+       for (i = 0; i < len; i++) {
+               j = *from++;
+               for (k = 0x80; k; k >>= 1)
+                       *to++ = ((j & k) != 0);
+       }
+}
+
+/*
+* XOR len bytes from from into the data at to.  Caution: the from buffer
+* is unpacked, but the to buffer is not.
+*/
+static void
+crypt_cfb_xor(unsigned char *to, const unsigned char *from, unsigned len)
+{
+       unsigned i;
+       unsigned j;
+       unsigned char c;
+
+       for (i = 0; i < len; i++) {
+               c = 0;
+               for (j = 0; j < 8; j++)
+                       c = (c << 1) | *from++;
+               *to++ ^= c;
+       }
+}
+
+/*
+* Take the 8-byte array at *a (must be able to hold 64 bytes!) and unpack
+* each bit into its own byte.
+*/
+static void crypt_unpack(unsigned char *a)
+{
+       int i, j;
+
+       for (i = 7; i >= 0; --i)
+               for (j = 7; j >= 0; --j)
+                       a[(i << 3) + j] = (a[i] & (0x80 >> j)) != 0;
+}
diff --git a/src/common/passcrypt.h.in b/src/common/passcrypt.h.in
new file mode 100644 (file)
index 0000000..74888c3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2003 Hiroyuki Yamamoto and the Sylpheed-Claws Team
+ *
+ * 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 of the License, 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.
+ */
+
+#define PASSCRYPT_KEY "@PASSCRYPT_KEY@"
+
+#include <glib.h>
+
+void passcrypt_encrypt(gchar *password, guint len);
+void passcrypt_decrypt(gchar *password, guint len);
index e3940bc50da966b3505236783498ee6aea0368c3..a4035c15a8243bfdc8e91d116998b87d5042b939 100644 (file)
@@ -274,7 +274,7 @@ static PrefParam param[] = {
        {"user_id", "ENV_USER", &tmp_ac_prefs.userid, P_STRING,
         &basic.uid_entry, prefs_set_data_from_entry, prefs_set_entry},
 
-       {"password", NULL, &tmp_ac_prefs.passwd, P_STRING,
+       {"password", NULL, &tmp_ac_prefs.passwd, P_PASSWORD,
         &basic.pass_entry, prefs_set_data_from_entry, prefs_set_entry},
 
        {"inbox", "inbox", &tmp_ac_prefs.inbox, P_STRING,
@@ -344,7 +344,7 @@ static PrefParam param[] = {
 
        {"smtp_user_id", NULL, &tmp_ac_prefs.smtp_userid, P_STRING,
         &p_send.smtp_uid_entry, prefs_set_data_from_entry, prefs_set_entry},
-       {"smtp_password", NULL, &tmp_ac_prefs.smtp_passwd, P_STRING,
+       {"smtp_password", NULL, &tmp_ac_prefs.smtp_passwd, P_PASSWORD,
         &p_send.smtp_pass_entry, prefs_set_data_from_entry, prefs_set_entry},
 
        {"pop_before_smtp", "FALSE", &tmp_ac_prefs.pop_before_smtp, P_BOOL,
index 0f6a8f5d3a6c8a00b6d31d6396ad67171d65fcfd..6047f09c58f98953218ed91764c4c010b10a6cfd 100644 (file)
@@ -34,6 +34,8 @@
 #include "prefs_gtk.h"
 #include "utils.h"
 #include "gtkutils.h"
+#include "passcrypt.h"
+#include "base64.h"
 
 #define CL(x)  (((gulong) (x) >> (gulong) 8) & 0xFFUL)
 #define RGB_FROM_GDK_COLOR(c) \
@@ -142,6 +144,22 @@ void prefs_config_parse_one_line(PrefParam *param, const gchar *buf)
                                /* be compatible and accept ints */
                                *((gulong *)param[i].data) = strtoul(value, 0, 10); 
                        break;
+               case P_PASSWORD:
+                       g_free(*((gchar **)param[i].data));
+                       if (value[0] == '!') {
+                               gchar tmp[1024];
+                               gint len;
+
+                               len = base64_decode(tmp, &value[1], strlen(value) - 1);
+                               passcrypt_decrypt(tmp, len);
+                               tmp[len] = '\0';
+                               *((gchar **)param[i].data) =
+                                       *tmp ? g_strdup(tmp) : NULL;
+                       } else {
+                               *((gchar **)param[i].data) =
+                                       *value ? g_strdup(value) : NULL;
+                       }
+                       break;
                default:
                        break;
                }
@@ -262,6 +280,26 @@ gint prefs_write_param(PrefParam *param, FILE *fp)
                        g_snprintf(buf, sizeof buf,  "%s=#%6.6lx\n", param[i].name,
                                   *((gulong *) param[i].data));
                        break;
+               case P_PASSWORD:
+                       {
+                               gchar *tmp = NULL, tmp2[1024] = {0};
+
+                               tmp = *((gchar **)param[i].data);
+                               if (tmp) {
+                                       gint len;
+
+                                       tmp = g_strdup(tmp);
+                                       len = strlen(tmp);
+                                       passcrypt_encrypt(tmp, len);
+                                       base64_encode(tmp2, tmp, len);
+                                       g_free(tmp);
+                                       tmp = tmp2;
+                               }
+                               g_snprintf(buf, sizeof(buf), "%s=!%s\n", param[i].name,
+                                          tmp ?
+                                          tmp : "");
+                       }
+                       break;
                default:
                        buf[0] = '\0';
                }
@@ -289,6 +327,7 @@ void prefs_set_default(PrefParam *param)
 
                switch (param[i].type) {
                case P_STRING:
+               case P_PASSWORD:
                        if (param[i].defval != NULL) {
                                if (!strncasecmp(param[i].defval, "ENV_", 4))
                                        *((gchar **)param[i].data) =
@@ -364,6 +403,7 @@ void prefs_free(PrefParam *param)
 
                switch (param[i].type) {
                case P_STRING:
+               case P_PASSWORD:
                        g_free(*((gchar **)param[i].data));
                        break;
                default:
@@ -474,6 +514,7 @@ void prefs_set_dialog_to_default(PrefParam *param)
 
                switch (tmpparam.type) {
                case P_STRING:
+               case P_PASSWORD:
                        if (tmpparam.defval) {
                                if (!strncasecmp(tmpparam.defval, "ENV_", 4)) {
                                        str_data = g_strdup(g_getenv(param[i].defval + 4));
@@ -542,6 +583,7 @@ void prefs_set_data_from_entry(PrefParam *pparam)
 
        switch (pparam->type) {
        case P_STRING:
+       case P_PASSWORD:
                str = (gchar **)pparam->data;
                g_free(*str);
                *str = entry_str[0] ? g_strdup(entry_str) : NULL;
@@ -566,6 +608,7 @@ void prefs_set_entry(PrefParam *pparam)
 
        switch (pparam->type) {
        case P_STRING:
+       case P_PASSWORD:
                str = (gchar **)pparam->data;
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
                                   *str ? *str : "");
@@ -594,6 +637,7 @@ void prefs_set_data_from_text(PrefParam *pparam)
 
        switch (pparam->type) {
        case P_STRING:
+       case P_PASSWORD:
                str = (gchar **)pparam->data;
                g_free(*str);
                tp = text = gtk_editable_get_chars
@@ -634,6 +678,7 @@ void prefs_set_text(PrefParam *pparam)
 
        switch (pparam->type) {
        case P_STRING:
+       case P_PASSWORD:
                str = (gchar **)pparam->data;
                if (*str) {
                        bufp = buf = alloca(strlen(*str) + 1);
index 4daf0e826096238fb3dc83bb9e9d204c6d4ea028..c64f5feb805b27ef2ac7212e5f87fa0a81e5b996 100644 (file)
@@ -51,6 +51,7 @@ typedef enum
        P_ENUM,
        P_USHORT,
        P_COLOR,
+       P_PASSWORD,
        P_OTHER
 } PrefType;