comparison src/libpst.c @ 79:56fa05fd5271

Patch from Robert Simpson for encryption type 2. Fix the order of testing item types to avoid claiming there are multiple message stores.
author Carl Byington <carl@five-ten-sg.com>
date Fri, 13 Jun 2008 20:47:01 -0700
parents 987aa872294e
children 582e927756d3
comparison
equal deleted inserted replaced
78:535075b4d261 79:56fa05fd5271
92 uint16_t type; 92 uint16_t type;
93 uint32_t offset; 93 uint32_t offset;
94 } pst_block_hdr; 94 } pst_block_hdr;
95 95
96 96
97 // for "compressible" encryption, just a simple substitution cipher
97 // this is an array of the un-encrypted values. the un-encrypted value is in the position 98 // this is an array of the un-encrypted values. the un-encrypted value is in the position
98 // of the encrypted value. ie the encrypted value 0x13 represents 0x02 99 // of the encrypted value. ie the encrypted value 0x13 represents 0x02
99 // 0 1 2 3 4 5 6 7 100 static unsigned char comp_enc [] = {
100 // 8 9 a b c d e f 101 0x47, 0xf1, 0xb4, 0xe6, 0x0b, 0x6a, 0x72, 0x48, 0x85, 0x4e, 0x9e, 0xeb, 0xe2, 0xf8, 0x94, 0x53,
101 static unsigned char comp_enc [] = 102 0xe0, 0xbb, 0xa0, 0x02, 0xe8, 0x5a, 0x09, 0xab, 0xdb, 0xe3, 0xba, 0xc6, 0x7c, 0xc3, 0x10, 0xdd,
102 { 0x47, 0xf1, 0xb4, 0xe6, 0x0b, 0x6a, 0x72, 0x48, 103 0x39, 0x05, 0x96, 0x30, 0xf5, 0x37, 0x60, 0x82, 0x8c, 0xc9, 0x13, 0x4a, 0x6b, 0x1d, 0xf3, 0xfb,
103 0x85, 0x4e, 0x9e, 0xeb, 0xe2, 0xf8, 0x94, 0x53, /*0x0f*/ 104 0x8f, 0x26, 0x97, 0xca, 0x91, 0x17, 0x01, 0xc4, 0x32, 0x2d, 0x6e, 0x31, 0x95, 0xff, 0xd9, 0x23,
104 0xe0, 0xbb, 0xa0, 0x02, 0xe8, 0x5a, 0x09, 0xab, 105 0xd1, 0x00, 0x5e, 0x79, 0xdc, 0x44, 0x3b, 0x1a, 0x28, 0xc5, 0x61, 0x57, 0x20, 0x90, 0x3d, 0x83,
105 0xdb, 0xe3, 0xba, 0xc6, 0x7c, 0xc3, 0x10, 0xdd, /*0x1f*/ 106 0xb9, 0x43, 0xbe, 0x67, 0xd2, 0x46, 0x42, 0x76, 0xc0, 0x6d, 0x5b, 0x7e, 0xb2, 0x0f, 0x16, 0x29,
106 0x39, 0x05, 0x96, 0x30, 0xf5, 0x37, 0x60, 0x82, 107 0x3c, 0xa9, 0x03, 0x54, 0x0d, 0xda, 0x5d, 0xdf, 0xf6, 0xb7, 0xc7, 0x62, 0xcd, 0x8d, 0x06, 0xd3,
107 0x8c, 0xc9, 0x13, 0x4a, 0x6b, 0x1d, 0xf3, 0xfb, /*0x2f*/ 108 0x69, 0x5c, 0x86, 0xd6, 0x14, 0xf7, 0xa5, 0x66, 0x75, 0xac, 0xb1, 0xe9, 0x45, 0x21, 0x70, 0x0c,
108 0x8f, 0x26, 0x97, 0xca, 0x91, 0x17, 0x01, 0xc4, 109 0x87, 0x9f, 0x74, 0xa4, 0x22, 0x4c, 0x6f, 0xbf, 0x1f, 0x56, 0xaa, 0x2e, 0xb3, 0x78, 0x33, 0x50,
109 0x32, 0x2d, 0x6e, 0x31, 0x95, 0xff, 0xd9, 0x23, /*0x3f*/ 110 0xb0, 0xa3, 0x92, 0xbc, 0xcf, 0x19, 0x1c, 0xa7, 0x63, 0xcb, 0x1e, 0x4d, 0x3e, 0x4b, 0x1b, 0x9b,
110 0xd1, 0x00, 0x5e, 0x79, 0xdc, 0x44, 0x3b, 0x1a, 111 0x4f, 0xe7, 0xf0, 0xee, 0xad, 0x3a, 0xb5, 0x59, 0x04, 0xea, 0x40, 0x55, 0x25, 0x51, 0xe5, 0x7a,
111 0x28, 0xc5, 0x61, 0x57, 0x20, 0x90, 0x3d, 0x83, /*0x4f*/ 112 0x89, 0x38, 0x68, 0x52, 0x7b, 0xfc, 0x27, 0xae, 0xd7, 0xbd, 0xfa, 0x07, 0xf4, 0xcc, 0x8e, 0x5f,
112 0xb9, 0x43, 0xbe, 0x67, 0xd2, 0x46, 0x42, 0x76, 113 0xef, 0x35, 0x9c, 0x84, 0x2b, 0x15, 0xd5, 0x77, 0x34, 0x49, 0xb6, 0x12, 0x0a, 0x7f, 0x71, 0x88,
113 0xc0, 0x6d, 0x5b, 0x7e, 0xb2, 0x0f, 0x16, 0x29, /*0x5f*/ 114 0xfd, 0x9d, 0x18, 0x41, 0x7d, 0x93, 0xd8, 0x58, 0x2c, 0xce, 0xfe, 0x24, 0xaf, 0xde, 0xb8, 0x36,
114 0x3c, 0xa9, 0x03, 0x54, 0x0d, 0xda, 0x5d, 0xdf, 115 0xc8, 0xa1, 0x80, 0xa6, 0x99, 0x98, 0xa8, 0x2f, 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a,
115 0xf6, 0xb7, 0xc7, 0x62, 0xcd, 0x8d, 0x06, 0xd3, /*0x6f*/ 116 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec
116 0x69, 0x5c, 0x86, 0xd6, 0x14, 0xf7, 0xa5, 0x66, 117 };
117 0x75, 0xac, 0xb1, 0xe9, 0x45, 0x21, 0x70, 0x0c, /*0x7f*/ 118
118 0x87, 0x9f, 0x74, 0xa4, 0x22, 0x4c, 0x6f, 0xbf, 119 // for "strong" encryption, we have the two additional tables
119 0x1f, 0x56, 0xaa, 0x2e, 0xb3, 0x78, 0x33, 0x50, /*0x8f*/ 120 static unsigned char comp_high1 [] = {
120 0xb0, 0xa3, 0x92, 0xbc, 0xcf, 0x19, 0x1c, 0xa7, 121 0x41, 0x36, 0x13, 0x62, 0xa8, 0x21, 0x6e, 0xbb, 0xf4, 0x16, 0xcc, 0x04, 0x7f, 0x64, 0xe8, 0x5d,
121 0x63, 0xcb, 0x1e, 0x4d, 0x3e, 0x4b, 0x1b, 0x9b, /*0x9f*/ 122 0x1e, 0xf2, 0xcb, 0x2a, 0x74, 0xc5, 0x5e, 0x35, 0xd2, 0x95, 0x47, 0x9e, 0x96, 0x2d, 0x9a, 0x88,
122 0x4f, 0xe7, 0xf0, 0xee, 0xad, 0x3a, 0xb5, 0x59, 123 0x4c, 0x7d, 0x84, 0x3f, 0xdb, 0xac, 0x31, 0xb6, 0x48, 0x5f, 0xf6, 0xc4, 0xd8, 0x39, 0x8b, 0xe7,
123 0x04, 0xea, 0x40, 0x55, 0x25, 0x51, 0xe5, 0x7a, /*0xaf*/ 124 0x23, 0x3b, 0x38, 0x8e, 0xc8, 0xc1, 0xdf, 0x25, 0xb1, 0x20, 0xa5, 0x46, 0x60, 0x4e, 0x9c, 0xfb,
124 0x89, 0x38, 0x68, 0x52, 0x7b, 0xfc, 0x27, 0xae, 125 0xaa, 0xd3, 0x56, 0x51, 0x45, 0x7c, 0x55, 0x00, 0x07, 0xc9, 0x2b, 0x9d, 0x85, 0x9b, 0x09, 0xa0,
125 0xd7, 0xbd, 0xfa, 0x07, 0xf4, 0xcc, 0x8e, 0x5f, /*0xbf*/ 126 0x8f, 0xad, 0xb3, 0x0f, 0x63, 0xab, 0x89, 0x4b, 0xd7, 0xa7, 0x15, 0x5a, 0x71, 0x66, 0x42, 0xbf,
126 0xef, 0x35, 0x9c, 0x84, 0x2b, 0x15, 0xd5, 0x77, 127 0x26, 0x4a, 0x6b, 0x98, 0xfa, 0xea, 0x77, 0x53, 0xb2, 0x70, 0x05, 0x2c, 0xfd, 0x59, 0x3a, 0x86,
127 0x34, 0x49, 0xb6, 0x12, 0x0a, 0x7f, 0x71, 0x88, /*0xcf*/ 128 0x7e, 0xce, 0x06, 0xeb, 0x82, 0x78, 0x57, 0xc7, 0x8d, 0x43, 0xaf, 0xb4, 0x1c, 0xd4, 0x5b, 0xcd,
128 0xfd, 0x9d, 0x18, 0x41, 0x7d, 0x93, 0xd8, 0x58, 129 0xe2, 0xe9, 0x27, 0x4f, 0xc3, 0x08, 0x72, 0x80, 0xcf, 0xb0, 0xef, 0xf5, 0x28, 0x6d, 0xbe, 0x30,
129 0x2c, 0xce, 0xfe, 0x24, 0xaf, 0xde, 0xb8, 0x36, /*0xdf*/ 130 0x4d, 0x34, 0x92, 0xd5, 0x0e, 0x3c, 0x22, 0x32, 0xe5, 0xe4, 0xf9, 0x9f, 0xc2, 0xd1, 0x0a, 0x81,
130 0xc8, 0xa1, 0x80, 0xa6, 0x99, 0x98, 0xa8, 0x2f, 131 0x12, 0xe1, 0xee, 0x91, 0x83, 0x76, 0xe3, 0x97, 0xe6, 0x61, 0x8a, 0x17, 0x79, 0xa4, 0xb7, 0xdc,
131 0x0e, 0x81, 0x65, 0x73, 0xe4, 0xc2, 0xa2, 0x8a, /*0xef*/ 132 0x90, 0x7a, 0x5c, 0x8c, 0x02, 0xa6, 0xca, 0x69, 0xde, 0x50, 0x1a, 0x11, 0x93, 0xb9, 0x52, 0x87,
132 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, 133 0x58, 0xfc, 0xed, 0x1d, 0x37, 0x49, 0x1b, 0x6a, 0xe0, 0x29, 0x33, 0x99, 0xbd, 0x6c, 0xd9, 0x94,
133 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/ 134 0xf3, 0x40, 0x54, 0x6f, 0xf0, 0xc6, 0x73, 0xb8, 0xd6, 0x3e, 0x65, 0x18, 0x44, 0x1f, 0xdd, 0x67,
134 135 0x10, 0xf1, 0x0c, 0x19, 0xec, 0xae, 0x03, 0xa1, 0x14, 0x7b, 0xa9, 0x0b, 0xff, 0xf8, 0xa3, 0xc0,
136 0xa2, 0x01, 0xf7, 0x2e, 0xbc, 0x24, 0x68, 0x75, 0x0d, 0xfe, 0xba, 0x2f, 0xb5, 0xd0, 0xda, 0x3d
137 };
138
139 static unsigned char comp_high2 [] = {
140 0x14, 0x53, 0x0f, 0x56, 0xb3, 0xc8, 0x7a, 0x9c, 0xeb, 0x65, 0x48, 0x17, 0x16, 0x15, 0x9f, 0x02,
141 0xcc, 0x54, 0x7c, 0x83, 0x00, 0x0d, 0x0c, 0x0b, 0xa2, 0x62, 0xa8, 0x76, 0xdb, 0xd9, 0xed, 0xc7,
142 0xc5, 0xa4, 0xdc, 0xac, 0x85, 0x74, 0xd6, 0xd0, 0xa7, 0x9b, 0xae, 0x9a, 0x96, 0x71, 0x66, 0xc3,
143 0x63, 0x99, 0xb8, 0xdd, 0x73, 0x92, 0x8e, 0x84, 0x7d, 0xa5, 0x5e, 0xd1, 0x5d, 0x93, 0xb1, 0x57,
144 0x51, 0x50, 0x80, 0x89, 0x52, 0x94, 0x4f, 0x4e, 0x0a, 0x6b, 0xbc, 0x8d, 0x7f, 0x6e, 0x47, 0x46,
145 0x41, 0x40, 0x44, 0x01, 0x11, 0xcb, 0x03, 0x3f, 0xf7, 0xf4, 0xe1, 0xa9, 0x8f, 0x3c, 0x3a, 0xf9,
146 0xfb, 0xf0, 0x19, 0x30, 0x82, 0x09, 0x2e, 0xc9, 0x9d, 0xa0, 0x86, 0x49, 0xee, 0x6f, 0x4d, 0x6d,
147 0xc4, 0x2d, 0x81, 0x34, 0x25, 0x87, 0x1b, 0x88, 0xaa, 0xfc, 0x06, 0xa1, 0x12, 0x38, 0xfd, 0x4c,
148 0x42, 0x72, 0x64, 0x13, 0x37, 0x24, 0x6a, 0x75, 0x77, 0x43, 0xff, 0xe6, 0xb4, 0x4b, 0x36, 0x5c,
149 0xe4, 0xd8, 0x35, 0x3d, 0x45, 0xb9, 0x2c, 0xec, 0xb7, 0x31, 0x2b, 0x29, 0x07, 0x68, 0xa3, 0x0e,
150 0x69, 0x7b, 0x18, 0x9e, 0x21, 0x39, 0xbe, 0x28, 0x1a, 0x5b, 0x78, 0xf5, 0x23, 0xca, 0x2a, 0xb0,
151 0xaf, 0x3e, 0xfe, 0x04, 0x8c, 0xe7, 0xe5, 0x98, 0x32, 0x95, 0xd3, 0xf6, 0x4a, 0xe8, 0xa6, 0xea,
152 0xe9, 0xf3, 0xd5, 0x2f, 0x70, 0x20, 0xf2, 0x1f, 0x05, 0x67, 0xad, 0x55, 0x10, 0xce, 0xcd, 0xe3,
153 0x27, 0x3b, 0xda, 0xba, 0xd7, 0xc2, 0x26, 0xd4, 0x91, 0x1d, 0xd2, 0x1c, 0x22, 0x33, 0xf8, 0xfa,
154 0xf1, 0x5a, 0xef, 0xcf, 0x90, 0xb6, 0x8b, 0xb5, 0xbd, 0xc0, 0xbf, 0x08, 0x97, 0x1e, 0x6c, 0xe2,
155 0x61, 0xe0, 0xc6, 0xc1, 0x59, 0xab, 0xbb, 0x58, 0xde, 0x5f, 0xdf, 0x60, 0x79, 0x7e, 0xb2, 0x8a
156 };
135 157
136 int pst_open(pst_file *pf, char *name) { 158 int pst_open(pst_file *pf, char *name) {
137 int32_t sig; 159 int32_t sig;
138 160
139 unicode_init(); 161 unicode_init();
2314 MALLOC_EMAIL(item); 2336 MALLOC_EMAIL(item);
2315 LIST_COPY(item->email->rtf_body_tag, (char*)); 2337 LIST_COPY(item->email->rtf_body_tag, (char*));
2316 DEBUG_EMAIL(("%s\n", item->email->rtf_body_tag)); 2338 DEBUG_EMAIL(("%s\n", item->email->rtf_body_tag));
2317 break; 2339 break;
2318 case 0x1009: // PR_RTF_COMPRESSED 2340 case 0x1009: // PR_RTF_COMPRESSED
2319 // some compression algorithm has been applied to this. At present 2341 // rtf data is lzw compressed
2320 // it is unknown
2321 DEBUG_EMAIL(("RTF Compressed body - ")); 2342 DEBUG_EMAIL(("RTF Compressed body - "));
2322 MALLOC_EMAIL(item); 2343 MALLOC_EMAIL(item);
2323 LIST_COPY_SIZE(item->email->rtf_compressed, (char*), item->email->rtf_compressed_size); 2344 LIST_COPY_SIZE(item->email->rtf_compressed, (char*), item->email->rtf_compressed_size);
2324 DEBUG_EMAIL(("NOT PRINTED\n")); 2345 //DEBUG_EMAIL_HEXPRINT((char*)item->email->rtf_compressed, item->email->rtf_compressed_size);
2325 break; 2346 break;
2326 case 0x1010: // PR_RTF_SYNC_PREFIX_COUNT 2347 case 0x1010: // PR_RTF_SYNC_PREFIX_COUNT
2327 // a count of the ignored characters before the first significant character 2348 // a count of the ignored characters before the first significant character
2328 DEBUG_EMAIL(("RTF whitespace prefix count - ")); 2349 DEBUG_EMAIL(("RTF whitespace prefix count - "));
2329 MALLOC_EMAIL(item); 2350 MALLOC_EMAIL(item);
3127 MALLOC_MESSAGESTORE(item); 3148 MALLOC_MESSAGESTORE(item);
3128 item->message_store->top_of_folder = (pst_entryid*) xmalloc(sizeof(pst_entryid)); 3149 item->message_store->top_of_folder = (pst_entryid*) xmalloc(sizeof(pst_entryid));
3129 memcpy(item->message_store->top_of_folder, list->items[x]->data, sizeof(pst_entryid)); 3150 memcpy(item->message_store->top_of_folder, list->items[x]->data, sizeof(pst_entryid));
3130 LE32_CPU(item->message_store->top_of_folder->u1); 3151 LE32_CPU(item->message_store->top_of_folder->u1);
3131 LE32_CPU(item->message_store->top_of_folder->id); 3152 LE32_CPU(item->message_store->top_of_folder->id);
3153 DEBUG_EMAIL(("u1 %#x id %#x\n", item->message_store->top_of_folder->u1, item->message_store->top_of_folder->id));
3132 DEBUG_EMAIL_HEXPRINT((char*)item->message_store->top_of_folder->entryid, 16); 3154 DEBUG_EMAIL_HEXPRINT((char*)item->message_store->top_of_folder->entryid, 16);
3133 break; 3155 break;
3134 case 0x8005: // Contact's Fullname 3156 case 0x8005: // Contact's Fullname
3135 DEBUG_EMAIL(("Contact Fullname - ")); 3157 DEBUG_EMAIL(("Contact Fullname - "));
3136 MALLOC_CONTACT(item); 3158 MALLOC_CONTACT(item);
4192 DEBUG_RET(); 4214 DEBUG_RET();
4193 return rsize; 4215 return rsize;
4194 } 4216 }
4195 4217
4196 4218
4197 int pst_decrypt(char *buf, size_t size, unsigned char type) { 4219 int pst_decrypt(uint64_t id, char *buf, size_t size, unsigned char type) {
4198 size_t x = 0; 4220 size_t x = 0;
4199 unsigned char y; 4221 unsigned char y;
4200 DEBUG_ENT("pst_decrypt"); 4222 DEBUG_ENT("pst_decrypt");
4201 if (!buf) { 4223 if (!buf) {
4202 DEBUG_RET(); 4224 DEBUG_RET();
4205 4227
4206 if (type == PST_COMP_ENCRYPT) { 4228 if (type == PST_COMP_ENCRYPT) {
4207 x = 0; 4229 x = 0;
4208 while (x < size) { 4230 while (x < size) {
4209 y = (unsigned char)(buf[x]); 4231 y = (unsigned char)(buf[x]);
4210 DEBUG_DECRYPT(("Transposing %#hhx to %#hhx [%#x]\n", buf[x], comp_enc[y], y));
4211 buf[x] = (char)comp_enc[y]; // transpose from encrypt array 4232 buf[x] = (char)comp_enc[y]; // transpose from encrypt array
4212 x++; 4233 x++;
4213 } 4234 }
4235
4236 } else if (type == PST_ENCRYPT) {
4237 // The following code was based on the information at
4238 // http://www.passcape.com/outlook_passwords.htm
4239 uint16_t salt = (uint16_t) (((id & 0x00000000ffff0000) >> 16) ^ (id & 0x000000000000ffff));
4240 x = 0;
4241 while (x < size) {
4242 uint8_t losalt = (salt & 0x00ff);
4243 uint8_t hisalt = (salt & 0xff00) >> 8;
4244 y = (unsigned char)buf[x];
4245 y += losalt;
4246 y = comp_high1[y];
4247 y += hisalt;
4248 y = comp_high2[y];
4249 y -= hisalt;
4250 y = comp_enc[y];
4251 y -= losalt;
4252 buf[x] = (char)y;
4253 x++;
4254 salt++;
4255 }
4256
4214 } else { 4257 } else {
4215 WARN(("Unknown encryption: %i. Cannot decrypt\n", type)); 4258 WARN(("Unknown encryption: %i. Cannot decrypt\n", type));
4216 DEBUG_RET(); 4259 DEBUG_RET();
4217 return -1; 4260 return -1;
4218 } 4261 }
4311 int noenc = (int)(id & 2); // disable encryption 4354 int noenc = (int)(id & 2); // disable encryption
4312 DEBUG_ENT("pst_ff_getIDblock_dec"); 4355 DEBUG_ENT("pst_ff_getIDblock_dec");
4313 DEBUG_INDEX(("for id %#x\n", id)); 4356 DEBUG_INDEX(("for id %#x\n", id));
4314 r = pst_ff_getIDblock(pf, id, buf); 4357 r = pst_ff_getIDblock(pf, id, buf);
4315 if ((pf->encryption) && !(noenc)) { 4358 if ((pf->encryption) && !(noenc)) {
4316 (void)pst_decrypt(*buf, r, pf->encryption); 4359 (void)pst_decrypt(id, *buf, r, pf->encryption);
4317 } 4360 }
4318 DEBUG_HEXDUMPC(*buf, r, 16); 4361 DEBUG_HEXDUMPC(*buf, r, 16);
4319 DEBUG_RET(); 4362 DEBUG_RET();
4320 return r; 4363 return r;
4321 } 4364 }
4421 LE32_CPU(block_hdr.offset); 4464 LE32_CPU(block_hdr.offset);
4422 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset)); 4465 DEBUG_EMAIL(("block header (index_offset=%#hx, type=%#hx, offset=%#x)\n", block_hdr.index_offset, block_hdr.type, block_hdr.offset));
4423 4466
4424 if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3 4467 if (block_hdr.index_offset != (uint16_t)0x0101) { //type 3
4425 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n")); 4468 DEBUG_WARN(("WARNING: not a type 0x0101 buffer, Treating as normal buffer\n"));
4426 if (pf->encryption) (void)pst_decrypt(buf3, a, pf->encryption); 4469 if (pf->encryption) (void)pst_decrypt(id, buf3, a, pf->encryption);
4427 if (h->buf) 4470 if (h->buf)
4428 *(h->buf) = buf3; 4471 *(h->buf) = buf3;
4429 else if (h->base64 == 1 && h->fp) { 4472 else if (h->base64 == 1 && h->fp) {
4430 t = base64_encode(buf3, a); 4473 t = base64_encode(buf3, a);
4431 if (t) { 4474 if (t) {