summaryrefslogtreecommitdiff
path: root/lib/Config/ClawsMail/Password.pm
blob: ec6f8af1ca882eb779a8682799d9cefc851b5d9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package Config::ClawsMail::Password; 
use strict;
use warnings;
# VERSION 
use Config::ClawsMail::Password::Inline 'C';
use MIME::Base64;
use namespace::clean -except => [qw(decrypt_password)];
 
# ABSTRACT: Claws-Mail password decrypter 
 
sub cleartext_password {
    my ($password) = @_;
    return decrypt_password(decode_base64($password));
}
 
1;
 
__DATA__
__C__
#include <memory.h> 
 
#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);
}