From f25286a60b8ad26994c5c88c60b7c0ec998ae803 Mon Sep 17 00:00:00 2001 From: dakkar Date: Tue, 26 Jan 2016 18:12:37 +0000 Subject: first commit, it works already --- lib/Config/ClawsMail/Password.pm | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 lib/Config/ClawsMail/Password.pm (limited to 'lib/Config/ClawsMail/Password.pm') diff --git a/lib/Config/ClawsMail/Password.pm b/lib/Config/ClawsMail/Password.pm new file mode 100644 index 0000000..c3e1b19 --- /dev/null +++ b/lib/Config/ClawsMail/Password.pm @@ -0,0 +1,110 @@ +package Config::ClawsMail::Password; +use strict; +use warnings; +use Inline 'C'; +use MIME::Base64; +use namespace::clean -except => [qw(decrypt_password)]; + +sub cleartext_password { + my ($password) = @_; + return decrypt_password(decode_base64($password)); +} + +1; + +__DATA__ +__C__ +#include + +#define PASSCRYPT_KEY "passkey0" +unsigned char crypt_cfb_iv[64]; +int crypt_cfb_blocksize = 8; /* 8 for DES */ + +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; +} + +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; + } +} + +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); + } +} + +static void crypt_cfb_buf( + const char key[8], + unsigned char *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, buf, chunksize); + crypt_cfb_xor((unsigned char *) buf, temp, chunksize); + if (!decrypt) + crypt_cfb_shift(crypt_cfb_iv, buf, chunksize); + len -= chunksize; + buf += chunksize; + } +} + +SV* decrypt_password(SV* password) { + size_t len = sv_len(password); + char *tmp = (char*)malloc(len); + memcpy(tmp,SvPVbyte(password,len),len); + crypt_cfb_buf(PASSCRYPT_KEY, tmp, len, 1, 1 ); + return newSVpvn(tmp,len); +} -- cgit v1.2.3