Line data Source code
1 : #include "../burp.h"
2 : #include "../asfd.h"
3 : #include "../async.h"
4 : #include "../cmd.h"
5 : #include "../cntr.h"
6 : #include "../iobuf.h"
7 : #include "../log.h"
8 : #include "../prepend.h"
9 : #include "../sbuf.h"
10 : #include "handy.h"
11 : #include "msg.h"
12 :
13 0 : static int do_write(struct asfd *asfd,
14 : BFILE *bfd, uint8_t *out, size_t outlen,
15 : char **metadata, uint64_t *sent)
16 : {
17 0 : int ret=0;
18 0 : if(metadata)
19 : {
20 : // Append it to our metadata.
21 0 : out[outlen]='\0';
22 : //printf("\nadd outlen: %lu\n", outlen);
23 0 : if(!(*metadata=prepend_len(*metadata, *sent,
24 : (const char *)out, outlen,
25 0 : "", 0, (size_t *)sent)))
26 : {
27 0 : logp("error when appending metadata\n");
28 : asfd->write_str(asfd, CMD_ERROR,
29 0 : "error when appending metadata");
30 0 : return -1;
31 : }
32 : }
33 : else
34 : {
35 0 : if((ret=bfd->write(bfd, out, outlen))<=0)
36 : {
37 0 : logp("error when appending %d: %d\n", outlen, ret);
38 0 : asfd->write_str(asfd, CMD_ERROR, "write failed");
39 0 : return -1;
40 : }
41 0 : *sent+=outlen;
42 : }
43 0 : return 0;
44 : }
45 :
46 0 : static int do_inflate(struct asfd *asfd,
47 : z_stream *zstrm, BFILE *bfd,
48 : uint8_t *out, uint8_t *buftouse, size_t lentouse,
49 : char **metadata, const char *encpassword, int enccompressed,
50 : uint64_t *sent)
51 : {
52 0 : int zret=Z_OK;
53 0 : unsigned have=0;
54 :
55 : // Do not want to inflate encrypted data that was not compressed.
56 : // Just write it straight out.
57 0 : if(encpassword && !enccompressed)
58 0 : return do_write(asfd, bfd, buftouse, lentouse, metadata, sent);
59 :
60 0 : zstrm->avail_in=lentouse;
61 0 : zstrm->next_in=buftouse;
62 :
63 0 : do
64 : {
65 0 : zstrm->avail_out=ZCHUNK;
66 0 : zstrm->next_out=out;
67 0 : zret=inflate(zstrm, Z_NO_FLUSH);
68 0 : switch(zret)
69 : {
70 : case Z_NEED_DICT:
71 0 : zret=Z_DATA_ERROR;
72 : case Z_DATA_ERROR:
73 : case Z_MEM_ERROR:
74 0 : logp("zstrm inflate error: %d\n", zret);
75 0 : return -1;
76 : break;
77 : }
78 0 : have=ZCHUNK-zstrm->avail_out;
79 0 : if(!have) continue;
80 :
81 0 : if(do_write(asfd, bfd, out, have, metadata, sent))
82 0 : return -1;
83 : /*
84 : if(md5)
85 : {
86 : if(!MD5_Update(md5, out, have))
87 : {
88 : logp("MD5 update error\n");
89 : return -1;
90 : }
91 : }
92 : */
93 0 : } while(!zstrm->avail_out);
94 0 : return 0;
95 : }
96 :
97 : #ifdef HAVE_WIN32
98 :
99 : struct winbuf
100 : {
101 : uint64_t *rcvd;
102 : uint64_t *sent;
103 : struct cntr *cntr;
104 : struct asfd *asfd;
105 : };
106 :
107 : static DWORD WINAPI read_efs(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength)
108 : {
109 : struct iobuf *rbuf;
110 : struct winbuf *mybuf=(struct winbuf *)pvCallbackContext;
111 : rbuf=mybuf->asfd->rbuf;
112 :
113 : while(1)
114 : {
115 : if(mybuf->asfd->read(mybuf->asfd))
116 : return ERROR_FUNCTION_FAILED;
117 : (*(mybuf->rcvd))+=rbuf->len;
118 :
119 : switch(rbuf->cmd)
120 : {
121 : case CMD_APPEND:
122 : memcpy(pbData, rbuf->buf, rbuf->len);
123 : *ulLength=(ULONG)rbuf->len;
124 : (*(mybuf->sent))+=rbuf->len;
125 : iobuf_free_content(rbuf);
126 : return ERROR_SUCCESS;
127 : case CMD_END_FILE:
128 : *ulLength=0;
129 : iobuf_free_content(rbuf);
130 : return ERROR_SUCCESS;
131 : case CMD_MESSAGE:
132 : logp("MESSAGE: %s\n", rbuf->buf);
133 : cntr_add(mybuf->cntr, rbuf->cmd, 0);
134 : iobuf_free_content(rbuf);
135 : continue;
136 : case CMD_WARNING:
137 : logp("WARNING: %s\n", rbuf->buf);
138 : cntr_add(mybuf->cntr, rbuf->cmd, 0);
139 : iobuf_free_content(rbuf);
140 : continue;
141 : default:
142 : iobuf_log_unexpected(rbuf, __func__);
143 : iobuf_free_content(rbuf);
144 : break;
145 : }
146 : }
147 : return ERROR_FUNCTION_FAILED;
148 : }
149 :
150 : static int transfer_efs_in(struct asfd *asfd,
151 : BFILE *bfd, uint64_t *rcvd,
152 : uint64_t *sent, struct cntr *cntr)
153 : {
154 : int ret=0;
155 : struct winbuf mybuf;
156 : mybuf.rcvd=rcvd;
157 : mybuf.sent=sent;
158 : mybuf.cntr=cntr;
159 : mybuf.asfd=asfd;
160 : if((ret=WriteEncryptedFileRaw((PFE_IMPORT_FUNC)read_efs,
161 : &mybuf, bfd->pvContext)))
162 : logp("WriteEncryptedFileRaw returned %d\n", ret);
163 : return ret;
164 : }
165 :
166 : #endif
167 :
168 0 : int transfer_gzfile_inl(struct asfd *asfd,
169 : struct sbuf *sb, const char *path, BFILE *bfd,
170 : uint64_t *rcvd, uint64_t *sent,
171 : const char *encpassword, int enccompressed,
172 : struct cntr *cntr, char **metadata)
173 : {
174 0 : int quit=0;
175 0 : int ret=-1;
176 : uint8_t out[ZCHUNK];
177 0 : int doutlen=0;
178 : //uint8_t doutbuf[1000+EVP_MAX_BLOCK_LENGTH];
179 : uint8_t doutbuf[ZCHUNK-EVP_MAX_BLOCK_LENGTH];
180 0 : struct iobuf *rbuf=asfd->rbuf;
181 :
182 : z_stream zstrm;
183 :
184 0 : EVP_CIPHER_CTX *enc_ctx=NULL;
185 :
186 : // Checksum stuff
187 : //MD5_CTX md5;
188 : //uint8_t checksum[MD5_DIGEST_LENGTH];
189 :
190 : #ifdef HAVE_WIN32
191 : if(sb && sb->path.cmd==CMD_EFS_FILE)
192 : return transfer_efs_in(asfd, bfd, rcvd, sent, cntr);
193 : #endif
194 :
195 : //if(!MD5_Init(&md5))
196 : //{
197 : // logp("MD5_Init() failed");
198 : // return -1;
199 : //}
200 :
201 0 : zstrm.zalloc=Z_NULL;
202 0 : zstrm.zfree=Z_NULL;
203 0 : zstrm.opaque=Z_NULL;
204 0 : zstrm.avail_in=0;
205 0 : zstrm.next_in=Z_NULL;
206 :
207 0 : if(inflateInit2(&zstrm, (15+16)))
208 : {
209 0 : logp("unable to init inflate\n");
210 0 : return -1;
211 : }
212 :
213 0 : if(encpassword && !(enc_ctx=enc_setup(0, encpassword)))
214 : {
215 0 : inflateEnd(&zstrm);
216 0 : return -1;
217 : }
218 :
219 0 : while(!quit)
220 : {
221 0 : iobuf_free_content(rbuf);
222 0 : if(asfd->read(asfd))
223 : {
224 0 : if(enc_ctx)
225 : {
226 0 : EVP_CIPHER_CTX_cleanup(enc_ctx);
227 0 : free(enc_ctx);
228 : }
229 0 : inflateEnd(&zstrm);
230 0 : return -1;
231 : }
232 0 : (*rcvd)+=rbuf->len;
233 :
234 : //logp("transfer in: %c:%s\n", rbuf->cmd, rbuf->buf);
235 0 : switch(rbuf->cmd)
236 : {
237 : case CMD_APPEND: // append
238 0 : if(!bfd && !metadata)
239 : {
240 0 : logp("given append, but no file or metadata to write to\n");
241 : asfd->write_str(asfd, CMD_ERROR,
242 0 : "append with no file or metadata");
243 0 : quit++; ret=-1;
244 : }
245 : else
246 : {
247 : size_t lentouse;
248 0 : uint8_t *buftouse=NULL;
249 : /*
250 : if(!MD5_Update(&md5, rbuf->buf, rbuf->len))
251 : {
252 : logp("MD5 update enc error\n");
253 : quit++; ret=-1;
254 : break;
255 : }
256 : */
257 : // If doing decryption, it needs
258 : // to be done before uncompressing.
259 0 : if(enc_ctx)
260 : {
261 : // updating our checksum needs to
262 : // be done first
263 : /*
264 : if(!MD5_Update(&md5, rbuf->buf, rbuf->len))
265 : {
266 : logp("MD5 update enc error\n");
267 : quit++; ret=-1;
268 : break;
269 : }
270 : else
271 : */
272 0 : if(!EVP_CipherUpdate(enc_ctx,
273 : doutbuf, &doutlen,
274 : (uint8_t *)rbuf->buf,
275 0 : rbuf->len))
276 : {
277 0 : logp("Decryption error\n");
278 0 : quit++; ret=-1;
279 0 : break;
280 : }
281 0 : if(!doutlen) break;
282 0 : lentouse=(size_t)doutlen;
283 0 : buftouse=doutbuf;
284 : }
285 : else
286 : {
287 0 : lentouse=rbuf->len;
288 0 : buftouse=(uint8_t *)rbuf->buf;
289 : }
290 : //logp("want to write: %d\n", zstrm.avail_in);
291 :
292 0 : if(do_inflate(asfd, &zstrm, bfd, out,
293 : buftouse, lentouse, metadata,
294 : encpassword,
295 : enccompressed,
296 0 : sent))
297 : {
298 0 : ret=-1; quit++;
299 0 : break;
300 : }
301 : }
302 0 : break;
303 : case CMD_END_FILE: // finish up
304 0 : if(enc_ctx)
305 : {
306 0 : if(!EVP_CipherFinal_ex(enc_ctx,
307 0 : doutbuf, &doutlen))
308 : {
309 0 : logp("Decryption failure at the end.\n");
310 0 : ret=-1; quit++;
311 0 : break;
312 : }
313 0 : if(doutlen && do_inflate(asfd,
314 : &zstrm, bfd,
315 : out, doutbuf, (size_t)doutlen,
316 : metadata, encpassword,
317 0 : enccompressed, sent))
318 : {
319 0 : ret=-1; quit++;
320 0 : break;
321 : }
322 : }
323 : /*
324 : if(MD5_Final(checksum, &md5))
325 : {
326 : char *oldsum=NULL;
327 : const char *newsum=NULL;
328 :
329 : if((oldsum=strchr(buf, ':')))
330 : {
331 : oldsum++;
332 : newsum=bytes_to_md5str(checksum);
333 : // log if the checksum differed
334 : if(strcmp(newsum, oldsum))
335 : logw(asfd, cntr, "md5sum for '%s' did not match! (%s!=%s)\n", path, newsum, oldsum);
336 : }
337 : }
338 : else
339 : {
340 : logp("MD5_Final() failed\n");
341 : }
342 : */
343 0 : quit++;
344 0 : ret=0;
345 0 : break;
346 : case CMD_MESSAGE:
347 : case CMD_WARNING:
348 0 : log_recvd(rbuf, cntr, 0);
349 0 : break;
350 : default:
351 0 : iobuf_log_unexpected(rbuf, __func__);
352 0 : quit++;
353 0 : ret=-1;
354 0 : break;
355 : }
356 : }
357 0 : inflateEnd(&zstrm);
358 0 : if(enc_ctx)
359 : {
360 0 : EVP_CIPHER_CTX_cleanup(enc_ctx);
361 0 : free(enc_ctx);
362 : }
363 :
364 0 : iobuf_free_content(rbuf);
365 0 : if(ret) logp("transfer file returning: %d\n", ret);
366 0 : return ret;
367 : }
|