krista@3630
|
1 |
// This file is under GNU General Public License 3.0
|
krista@3630
|
2 |
// see LICENSE.txt
|
krista@3630
|
3 |
|
krista@3630
|
4 |
#ifdef ENIGMAIL_MAY_USE_THIS
|
krista@3630
|
5 |
|
krista@3630
|
6 |
#include "pEp_internal.h"
|
krista@3630
|
7 |
#include "message_api.h"
|
krista@3630
|
8 |
#include "mime.h"
|
krista@3630
|
9 |
|
krista@3630
|
10 |
#include <assert.h>
|
krista@3630
|
11 |
#include <string.h>
|
krista@3630
|
12 |
#include <stdlib.h>
|
krista@3630
|
13 |
|
krista@3630
|
14 |
#include "aux_mime_msg.h"
|
krista@3630
|
15 |
|
krista@3630
|
16 |
|
krista@3630
|
17 |
static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
|
krista@3630
|
18 |
identity_list* list) {
|
krista@3630
|
19 |
|
krista@3630
|
20 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@3630
|
21 |
|
krista@3630
|
22 |
if (!session)
|
krista@3630
|
23 |
return PEP_UNKNOWN_ERROR;
|
krista@3630
|
24 |
|
krista@3630
|
25 |
identity_list* id_list_ptr = NULL;
|
krista@3630
|
26 |
|
krista@3630
|
27 |
for (id_list_ptr = list; id_list_ptr; id_list_ptr = id_list_ptr->next) {
|
krista@3630
|
28 |
pEp_identity* curr_identity = id_list_ptr->ident;
|
krista@3630
|
29 |
if (curr_identity) {
|
krista@3630
|
30 |
if (!is_me(session, curr_identity)) {
|
krista@3630
|
31 |
char* name_bak = curr_identity->username;
|
krista@3630
|
32 |
curr_identity->username = NULL;
|
krista@3630
|
33 |
status = update_identity(session, curr_identity);
|
krista@3630
|
34 |
if (name_bak &&
|
krista@3630
|
35 |
(EMPTYSTR(curr_identity->username) || strcmp(name_bak, curr_identity->username) != 0)) {
|
krista@3630
|
36 |
free(curr_identity->username);
|
krista@3630
|
37 |
curr_identity->username = name_bak;
|
krista@3630
|
38 |
}
|
krista@3630
|
39 |
}
|
krista@3630
|
40 |
else
|
krista@3630
|
41 |
status = _myself(session, curr_identity, false, false, true);
|
krista@3630
|
42 |
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
|
krista@3630
|
43 |
return status;
|
krista@3630
|
44 |
}
|
krista@3630
|
45 |
}
|
krista@3630
|
46 |
|
krista@3630
|
47 |
return PEP_STATUS_OK;
|
krista@3630
|
48 |
}
|
krista@3630
|
49 |
|
krista@3630
|
50 |
DYNAMIC_API PEP_STATUS MIME_decrypt_message(
|
krista@3630
|
51 |
PEP_SESSION session,
|
krista@3630
|
52 |
const char *mimetext,
|
krista@3630
|
53 |
size_t size,
|
krista@3630
|
54 |
char** mime_plaintext,
|
krista@3630
|
55 |
stringlist_t **keylist,
|
krista@3630
|
56 |
PEP_rating *rating,
|
krista@3630
|
57 |
PEP_decrypt_flags_t *flags,
|
krista@3630
|
58 |
char** modified_src
|
krista@3630
|
59 |
)
|
krista@3630
|
60 |
{
|
krista@3630
|
61 |
assert(mimetext);
|
krista@3630
|
62 |
assert(mime_plaintext);
|
krista@3630
|
63 |
assert(keylist);
|
krista@3630
|
64 |
assert(rating);
|
krista@3630
|
65 |
assert(flags);
|
krista@3630
|
66 |
assert(modified_src);
|
krista@3630
|
67 |
|
krista@3630
|
68 |
if (!(mimetext && mime_plaintext && keylist && rating && flags && modified_src))
|
krista@3630
|
69 |
return PEP_ILLEGAL_VALUE;
|
krista@3630
|
70 |
|
krista@3630
|
71 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@3630
|
72 |
message* tmp_msg = NULL;
|
krista@3630
|
73 |
message* dec_msg = NULL;
|
krista@3630
|
74 |
*mime_plaintext = NULL;
|
krista@3630
|
75 |
|
krista@3630
|
76 |
status = mime_decode_message(mimetext, size, &tmp_msg);
|
krista@3630
|
77 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
78 |
goto pEp_error;
|
krista@3630
|
79 |
|
krista@3630
|
80 |
tmp_msg->dir = PEP_dir_incoming;
|
krista@3630
|
81 |
// MIME decode message delivers only addresses. We need more.
|
krista@3630
|
82 |
if (tmp_msg->from) {
|
krista@3630
|
83 |
if (!is_me(session, tmp_msg->from))
|
krista@3630
|
84 |
status = update_identity(session, (tmp_msg->from));
|
krista@3630
|
85 |
else
|
krista@3630
|
86 |
status = _myself(session, tmp_msg->from, false, false, true);
|
krista@3630
|
87 |
|
krista@3630
|
88 |
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
|
krista@3630
|
89 |
goto pEp_error;
|
krista@3630
|
90 |
}
|
krista@3630
|
91 |
|
krista@3630
|
92 |
status = update_identity_recip_list(session, tmp_msg->to);
|
krista@3630
|
93 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
94 |
goto pEp_error;
|
krista@3630
|
95 |
|
krista@3630
|
96 |
status = update_identity_recip_list(session, tmp_msg->cc);
|
krista@3630
|
97 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
98 |
goto pEp_error;
|
krista@3630
|
99 |
|
krista@3630
|
100 |
status = update_identity_recip_list(session, tmp_msg->bcc);
|
krista@3630
|
101 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
102 |
goto pEp_error;
|
krista@3630
|
103 |
|
krista@3630
|
104 |
PEP_STATUS decrypt_status = decrypt_message(session,
|
krista@3630
|
105 |
tmp_msg,
|
krista@3630
|
106 |
&dec_msg,
|
krista@3630
|
107 |
keylist,
|
krista@3630
|
108 |
rating,
|
krista@3630
|
109 |
flags);
|
krista@3630
|
110 |
|
krista@3630
|
111 |
|
krista@3630
|
112 |
if (!dec_msg && (decrypt_status == PEP_UNENCRYPTED || decrypt_status == PEP_VERIFIED)) {
|
krista@3630
|
113 |
dec_msg = message_dup(tmp_msg);
|
krista@3630
|
114 |
}
|
krista@3630
|
115 |
|
krista@3630
|
116 |
if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN || !dec_msg)
|
krista@3630
|
117 |
{
|
krista@3630
|
118 |
status = decrypt_status;
|
krista@3630
|
119 |
goto pEp_error;
|
krista@3630
|
120 |
}
|
krista@3630
|
121 |
|
krista@3630
|
122 |
if (*flags & PEP_decrypt_flag_src_modified) {
|
krista@3630
|
123 |
_mime_encode_message_internal(tmp_msg, false, modified_src, true);
|
krista@3630
|
124 |
if (!modified_src) {
|
krista@3630
|
125 |
*flags &= (~PEP_decrypt_flag_src_modified);
|
krista@3630
|
126 |
decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
|
krista@3630
|
127 |
}
|
krista@3630
|
128 |
}
|
krista@3630
|
129 |
|
krista@3630
|
130 |
// FIXME: test with att
|
krista@3630
|
131 |
status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true);
|
krista@3630
|
132 |
|
krista@3630
|
133 |
if (status == PEP_STATUS_OK)
|
krista@3630
|
134 |
{
|
krista@3630
|
135 |
free(tmp_msg);
|
krista@3630
|
136 |
free(dec_msg);
|
krista@3630
|
137 |
return decrypt_status;
|
krista@3630
|
138 |
}
|
krista@3630
|
139 |
|
krista@3630
|
140 |
pEp_error:
|
krista@3630
|
141 |
free_message(tmp_msg);
|
krista@3630
|
142 |
free_message(dec_msg);
|
krista@3630
|
143 |
|
krista@3630
|
144 |
return status;
|
krista@3630
|
145 |
}
|
krista@3630
|
146 |
|
krista@3630
|
147 |
|
krista@3630
|
148 |
DYNAMIC_API PEP_STATUS MIME_encrypt_message(
|
krista@3630
|
149 |
PEP_SESSION session,
|
krista@3630
|
150 |
const char *mimetext,
|
krista@3630
|
151 |
size_t size,
|
krista@3630
|
152 |
stringlist_t* extra,
|
krista@3630
|
153 |
char** mime_ciphertext,
|
krista@3630
|
154 |
PEP_enc_format enc_format,
|
krista@3630
|
155 |
PEP_encrypt_flags_t flags
|
krista@3630
|
156 |
)
|
krista@3630
|
157 |
{
|
krista@3630
|
158 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@3630
|
159 |
message* tmp_msg = NULL;
|
krista@3630
|
160 |
message* enc_msg = NULL;
|
krista@3630
|
161 |
|
krista@3630
|
162 |
status = mime_decode_message(mimetext, size, &tmp_msg);
|
krista@3630
|
163 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
164 |
goto pEp_error;
|
krista@3630
|
165 |
|
krista@3630
|
166 |
// MIME decode message delivers only addresses. We need more.
|
krista@3630
|
167 |
if (tmp_msg->from) {
|
krista@3630
|
168 |
char* own_id = NULL;
|
krista@3630
|
169 |
status = get_default_own_userid(session, &own_id);
|
krista@3630
|
170 |
free(tmp_msg->from->user_id);
|
krista@3630
|
171 |
|
krista@3630
|
172 |
if (status != PEP_STATUS_OK || !own_id) {
|
krista@3630
|
173 |
tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
|
krista@3630
|
174 |
}
|
krista@3630
|
175 |
else {
|
krista@3630
|
176 |
tmp_msg->from->user_id = own_id; // ownership transfer
|
krista@3630
|
177 |
}
|
krista@3630
|
178 |
|
krista@3630
|
179 |
status = myself(session, tmp_msg->from);
|
krista@3630
|
180 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
181 |
goto pEp_error;
|
krista@3630
|
182 |
}
|
krista@3630
|
183 |
|
krista@3630
|
184 |
// Own identities can be retrieved here where they would otherwise
|
krista@3630
|
185 |
// fail because we lack all other information. This is ok and even
|
krista@3630
|
186 |
// desired. FIXME: IS it?
|
krista@3630
|
187 |
status = update_identity_recip_list(session, tmp_msg->to);
|
krista@3630
|
188 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
189 |
goto pEp_error;
|
krista@3630
|
190 |
|
krista@3630
|
191 |
status = update_identity_recip_list(session, tmp_msg->cc);
|
krista@3630
|
192 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
193 |
goto pEp_error;
|
krista@3630
|
194 |
|
krista@3630
|
195 |
status = update_identity_recip_list(session, tmp_msg->bcc);
|
krista@3630
|
196 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
197 |
goto pEp_error;
|
krista@3630
|
198 |
|
krista@3630
|
199 |
// This isn't incoming, though... so we need to reverse the direction
|
krista@3630
|
200 |
tmp_msg->dir = PEP_dir_outgoing;
|
krista@3630
|
201 |
status = encrypt_message(session,
|
krista@3630
|
202 |
tmp_msg,
|
krista@3630
|
203 |
extra,
|
krista@3630
|
204 |
&enc_msg,
|
krista@3630
|
205 |
enc_format,
|
krista@3630
|
206 |
flags);
|
krista@3630
|
207 |
|
krista@3630
|
208 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
209 |
goto pEp_error;
|
krista@3630
|
210 |
|
krista@3630
|
211 |
|
krista@3630
|
212 |
if (!enc_msg) {
|
krista@3630
|
213 |
status = PEP_UNKNOWN_ERROR;
|
krista@3630
|
214 |
goto pEp_error;
|
krista@3630
|
215 |
}
|
krista@3630
|
216 |
|
krista@3630
|
217 |
status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false);
|
krista@3630
|
218 |
|
krista@3630
|
219 |
pEp_error:
|
krista@3630
|
220 |
free_message(tmp_msg);
|
krista@3630
|
221 |
free_message(enc_msg);
|
krista@3630
|
222 |
|
krista@3630
|
223 |
return status;
|
krista@3630
|
224 |
|
krista@3630
|
225 |
}
|
krista@3630
|
226 |
|
krista@3630
|
227 |
DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
|
krista@3630
|
228 |
PEP_SESSION session,
|
krista@3630
|
229 |
pEp_identity* target_id,
|
krista@3630
|
230 |
const char *mimetext,
|
krista@3630
|
231 |
size_t size,
|
krista@3630
|
232 |
stringlist_t* extra,
|
krista@3630
|
233 |
char** mime_ciphertext,
|
krista@3630
|
234 |
PEP_enc_format enc_format,
|
krista@3630
|
235 |
PEP_encrypt_flags_t flags
|
krista@3630
|
236 |
)
|
krista@3630
|
237 |
{
|
krista@3630
|
238 |
PEP_STATUS status = PEP_STATUS_OK;
|
krista@3630
|
239 |
message* tmp_msg = NULL;
|
krista@3630
|
240 |
message* enc_msg = NULL;
|
krista@3630
|
241 |
|
krista@3630
|
242 |
status = mime_decode_message(mimetext, size, &tmp_msg);
|
krista@3630
|
243 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
244 |
goto pEp_error;
|
krista@3630
|
245 |
|
krista@3630
|
246 |
// This isn't incoming, though... so we need to reverse the direction
|
krista@3630
|
247 |
tmp_msg->dir = PEP_dir_outgoing;
|
krista@3630
|
248 |
status = encrypt_message_for_self(session,
|
krista@3630
|
249 |
target_id,
|
krista@3630
|
250 |
tmp_msg,
|
krista@3630
|
251 |
extra,
|
krista@3630
|
252 |
&enc_msg,
|
krista@3630
|
253 |
enc_format,
|
krista@3630
|
254 |
flags);
|
krista@3630
|
255 |
if (status != PEP_STATUS_OK)
|
krista@3630
|
256 |
goto pEp_error;
|
krista@3630
|
257 |
|
krista@3630
|
258 |
if (!enc_msg) {
|
krista@3630
|
259 |
status = PEP_UNKNOWN_ERROR;
|
krista@3630
|
260 |
goto pEp_error;
|
krista@3630
|
261 |
}
|
krista@3630
|
262 |
|
krista@3630
|
263 |
status = mime_encode_message(enc_msg, false, mime_ciphertext);
|
krista@3630
|
264 |
|
krista@3630
|
265 |
pEp_error:
|
krista@3630
|
266 |
free_message(tmp_msg);
|
krista@3630
|
267 |
free_message(enc_msg);
|
krista@3630
|
268 |
|
krista@3630
|
269 |
return status;
|
krista@3630
|
270 |
}
|
krista@3630
|
271 |
|
krista@3630
|
272 |
#endif
|