1 /***************************************************************************
2 begin : Wed Jun 22 2011
3 copyright : (C) 2011 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28
29
30 #include "sar_p.h"
31 #include "gwen_sar_fileheader_l.h"
32 #include "i18n_l.h"
33
34 #include <gwenhywfar/misc.h>
35 #include <gwenhywfar/debug.h>
36 #include <gwenhywfar/tlv.h>
37 #include <gwenhywfar/gui.h>
38 #include <gwenhywfar/text.h>
39 #include <gwenhywfar/cryptmgrkeys.h>
40
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44
45 #include <errno.h>
46 #include <string.h>
47
48
49
GWEN_Sar_new(void)50 GWEN_SAR *GWEN_Sar_new(void)
51 {
52 GWEN_SAR *sr;
53
54 GWEN_NEW_OBJECT(GWEN_SAR, sr);
55 sr->refCount=1;
56
57 sr->headers=GWEN_SarFileHeader_List_new();
58
59 return sr;
60 }
61
62
63
GWEN_Sar_Attach(GWEN_SAR * sr)64 void GWEN_Sar_Attach(GWEN_SAR *sr)
65 {
66 assert(sr);
67 assert(sr->refCount);
68 sr->refCount++;
69 }
70
71
72
GWEN_Sar_free(GWEN_SAR * sr)73 void GWEN_Sar_free(GWEN_SAR *sr)
74 {
75 if (sr) {
76 assert(sr->refCount);
77 if (sr->refCount==1) {
78 free(sr->archiveName);
79 GWEN_SarFileHeader_List_free(sr->headers);
80 GWEN_SyncIo_free(sr->archiveSio);
81 sr->refCount=0;
82 GWEN_FREE_OBJECT(sr);
83 }
84 else {
85 sr->refCount--;
86 }
87 }
88 }
89
90
91
GWEN_Sar_CreateArchive(GWEN_SAR * sr,const char * aname)92 int GWEN_Sar_CreateArchive(GWEN_SAR *sr, const char *aname)
93 {
94 GWEN_SYNCIO *sio;
95 int rv;
96
97 assert(sr);
98 assert(sr->refCount);
99
100 assert(aname);
101 if (sr->openMode!=GWEN_Sar_OpenMode_Closed) {
102 DBG_ERROR(GWEN_LOGDOMAIN, "Archive already open");
103 return GWEN_ERROR_OPEN;
104 }
105
106 free(sr->archiveName);
107 sr->archiveName=strdup(aname);
108 sio=GWEN_SyncIo_File_new(aname, GWEN_SyncIo_File_CreationMode_CreateAlways);
109 GWEN_SyncIo_AddFlags(sio,
110 GWEN_SYNCIO_FILE_FLAGS_READ |
111 GWEN_SYNCIO_FILE_FLAGS_WRITE |
112 GWEN_SYNCIO_FILE_FLAGS_UREAD |
113 GWEN_SYNCIO_FILE_FLAGS_UWRITE |
114 GWEN_SYNCIO_FILE_FLAGS_GREAD |
115 GWEN_SYNCIO_FILE_FLAGS_GWRITE);
116 rv=GWEN_SyncIo_Connect(sio);
117 if (rv<0) {
118 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
119 GWEN_SyncIo_free(sio);
120 return rv;
121 }
122
123 sr->archiveSio=sio;
124 sr->openMode=GWEN_Sar_OpenMode_Created;
125
126 sr->signaturePos=0;
127 sr->signatureSize=0;
128
129 return 0;
130 }
131
132
133
GWEN_Sar_OpenArchive(GWEN_SAR * sr,const char * aname,GWEN_SYNCIO_FILE_CREATIONMODE cm,uint32_t acc)134 int GWEN_Sar_OpenArchive(GWEN_SAR *sr, const char *aname,
135 GWEN_SYNCIO_FILE_CREATIONMODE cm,
136 uint32_t acc)
137 {
138 GWEN_SYNCIO *sio;
139 int rv;
140
141 assert(sr);
142 assert(sr->refCount);
143
144 assert(aname);
145 if (sr->openMode!=GWEN_Sar_OpenMode_Closed) {
146 DBG_ERROR(GWEN_LOGDOMAIN, "Archive already open");
147 return GWEN_ERROR_OPEN;
148 }
149
150 free(sr->archiveName);
151 sr->archiveName=strdup(aname);
152 sio=GWEN_SyncIo_File_new(aname, cm);
153 GWEN_SyncIo_AddFlags(sio, acc);
154 rv=GWEN_SyncIo_Connect(sio);
155 if (rv<0) {
156 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
157 GWEN_SyncIo_free(sio);
158 return rv;
159 }
160
161 sr->archiveSio=sio;
162 sr->openMode=GWEN_Sar_OpenMode_Opened;
163
164 sr->signaturePos=0;
165 sr->signatureSize=0;
166
167 rv=GWEN_Sar_ScanFile(sr);
168 if (rv<0) {
169 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
170 sr->archiveSio=NULL;
171 sr->openMode=GWEN_Sar_OpenMode_Closed;
172 GWEN_SyncIo_free(sio);
173 return rv;
174 }
175
176 return 0;
177 }
178
179
180
GWEN_Sar_CloseArchive(GWEN_SAR * sr,int abandon)181 int GWEN_Sar_CloseArchive(GWEN_SAR *sr, int abandon)
182 {
183 int rv;
184
185 assert(sr);
186 assert(sr->refCount);
187
188 if (sr->openMode!=GWEN_Sar_OpenMode_Opened &&
189 sr->openMode!=GWEN_Sar_OpenMode_Created) {
190 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open");
191 return GWEN_ERROR_NOT_OPEN;
192 }
193
194 if (!abandon) {
195 /* flush */
196 rv=GWEN_SyncIo_Flush(sr->archiveSio);
197 if (rv<0) {
198 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
199 GWEN_SyncIo_Disconnect(sr->archiveSio);
200 GWEN_SyncIo_free(sr->archiveSio);
201 sr->archiveSio=NULL;
202 free(sr->archiveName);
203 sr->archiveName=NULL;
204 sr->openMode=GWEN_Sar_OpenMode_Closed;
205 return rv;
206 }
207 }
208
209 /* disconnect */
210 rv=GWEN_SyncIo_Disconnect(sr->archiveSio);
211 if (rv<0) {
212 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
213 GWEN_SyncIo_free(sr->archiveSio);
214 sr->archiveSio=NULL;
215 free(sr->archiveName);
216 sr->archiveName=NULL;
217 sr->openMode=GWEN_Sar_OpenMode_Closed;
218 return rv;
219 }
220
221 GWEN_SyncIo_free(sr->archiveSio);
222 sr->archiveSio=NULL;
223 free(sr->archiveName);
224 sr->archiveName=NULL;
225 sr->openMode=GWEN_Sar_OpenMode_Closed;
226 return 0;
227 }
228
229
230
GWEN_Sar_FileHeaderToTlv(const GWEN_SAR_FILEHEADER * fh,GWEN_BUFFER * tbuf)231 int GWEN_Sar_FileHeaderToTlv(const GWEN_SAR_FILEHEADER *fh, GWEN_BUFFER *tbuf)
232 {
233 const char *s;
234 uint16_t v8;
235 uint32_t v32;
236 uint64_t v64;
237 uint8_t hbuf[8];
238 const GWEN_TIME *ti;
239 int rv;
240
241 /* header version */
242 v32=GWEN_SAR_HEADER_VERSION;
243 hbuf[0]=(v32>>24) & 0xff;
244 hbuf[1]=(v32>>16) & 0xff;
245 hbuf[2]=(v32>>8) & 0xff;
246 hbuf[3]=v32 & 0xff;
247 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_VERSION, 0x00, hbuf, 4, 1, tbuf);
248
249 /* status */
250 v8=GWEN_SarFileHeader_GetStatus(fh) & 0xff;
251 hbuf[0]=v8;
252 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_STATUS, 0x00, hbuf, 1, 1, tbuf);
253
254 /* flags */
255 v32=GWEN_SarFileHeader_GetFlags(fh);
256 hbuf[0]=(v32>>24) & 0xff;
257 hbuf[1]=(v32>>16) & 0xff;
258 hbuf[2]=(v32>>8) & 0xff;
259 hbuf[3]=v32 & 0xff;
260 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_FLAGS, 0x00, hbuf, 4, 1, tbuf);
261
262 /* path */
263 s=GWEN_SarFileHeader_GetPath(fh);
264 if (s && *s)
265 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_PATH, 0x00, s, strlen(s)+1, 1, tbuf);
266
267 /* file type */
268 v8=GWEN_SarFileHeader_GetFileType(fh) & 0xff;
269 hbuf[0]=v8;
270 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_TYPE, 0x00, hbuf, 1, 1, tbuf);
271
272 /* permissions */
273 v32=GWEN_SarFileHeader_GetPermissions(fh);
274 hbuf[0]=(v32>>24) & 0xff;
275 hbuf[1]=(v32>>16) & 0xff;
276 hbuf[2]=(v32>>8) & 0xff;
277 hbuf[3]=v32 & 0xff;
278 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_PERM, 0x00, hbuf, 4, 1, tbuf);
279
280 /* atime */
281 ti=GWEN_SarFileHeader_GetAtime(fh);
282 if (ti) {
283 GWEN_BUFFER *xbuf;
284
285 xbuf=GWEN_Buffer_new(0, 32, 0, 1);
286 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf);
287 if (rv>=0)
288 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_ATIME, 0x00,
289 GWEN_Buffer_GetStart(xbuf),
290 GWEN_Buffer_GetUsedBytes(xbuf),
291 1,
292 tbuf);
293 GWEN_Buffer_free(xbuf);
294 }
295
296 /* mtime */
297 ti=GWEN_SarFileHeader_GetMtime(fh);
298 if (ti) {
299 GWEN_BUFFER *xbuf;
300
301 xbuf=GWEN_Buffer_new(0, 32, 0, 1);
302 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf);
303 if (rv>=0)
304 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_MTIME, 0x00,
305 GWEN_Buffer_GetStart(xbuf),
306 GWEN_Buffer_GetUsedBytes(xbuf),
307 1,
308 tbuf);
309 GWEN_Buffer_free(xbuf);
310 }
311
312 /* ctime */
313 ti=GWEN_SarFileHeader_GetCtime(fh);
314 if (ti) {
315 GWEN_BUFFER *xbuf;
316
317 xbuf=GWEN_Buffer_new(0, 32, 0, 1);
318 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf);
319 if (rv>=0)
320 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_CTIME, 0x00,
321 GWEN_Buffer_GetStart(xbuf),
322 GWEN_Buffer_GetUsedBytes(xbuf),
323 1,
324 tbuf);
325 GWEN_Buffer_free(xbuf);
326 }
327
328 /* file size */
329 v64=GWEN_SarFileHeader_GetFileSize(fh);
330 hbuf[0]=(v64>>56) & 0xff;
331 hbuf[1]=(v64>>48) & 0xff;
332 hbuf[2]=(v64>>40) & 0xff;
333 hbuf[3]=(v64>>32) & 0xff;
334 hbuf[4]=(v64>>24) & 0xff;
335 hbuf[5]=(v64>>16) & 0xff;
336 hbuf[6]=(v64>>8) & 0xff;
337 hbuf[7]=v64 & 0xff;
338 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_SIZE, 0x00, hbuf, 8, 1, tbuf);
339
340 return 0;
341 }
342
343
344
GWEN_Sar_ReadUint64(const uint8_t * p,uint32_t bs)345 uint64_t GWEN_Sar_ReadUint64(const uint8_t *p, uint32_t bs)
346 {
347 uint64_t v=0;
348
349 switch (bs) {
350 case 8:
351 v=(((uint64_t)(p[0]))<<56)+
352 (((uint64_t)(p[1]))<<48)+
353 (((uint64_t)(p[2]))<<40)+
354 (((uint64_t)(p[3]))<<32)+
355 (((uint64_t)(p[4]))<<24)+
356 (((uint64_t)(p[5]))<<16)+
357 (((uint64_t)(p[6]))<<8)+
358 ((uint64_t)(p[7]));
359 break;
360 case 7:
361 v=(((uint64_t)(p[0]))<<48)+
362 (((uint64_t)(p[1]))<<40)+
363 (((uint64_t)(p[2]))<<32)+
364 (((uint64_t)(p[3]))<<24)+
365 (((uint64_t)(p[4]))<<16)+
366 (((uint64_t)(p[5]))<<8)+
367 ((uint64_t)(p[6]));
368 break;
369 case 6:
370 v=(((uint64_t)(p[0]))<<40)+
371 (((uint64_t)(p[1]))<<32)+
372 (((uint64_t)(p[2]))<<24)+
373 (((uint64_t)(p[3]))<<16)+
374 (((uint64_t)(p[4]))<<8)+
375 ((uint64_t)(p[5]));
376 break;
377 case 5:
378 v=(((uint64_t)(p[0]))<<32)+
379 (((uint64_t)(p[1]))<<24)+
380 (((uint64_t)(p[2]))<<16)+
381 (((uint64_t)(p[3]))<<8)+
382 ((uint64_t)(p[4]));
383 break;
384 case 4:
385 v=(((uint64_t)(p[0]))<<24)+
386 (((uint64_t)(p[1]))<<16)+
387 (((uint64_t)(p[2]))<<8)+
388 ((uint64_t)(p[3]));
389 break;
390 case 3:
391 v=(((uint64_t)(p[0]))<<16)+
392 (((uint64_t)(p[1]))<<8)+
393 ((uint64_t)(p[2]));
394 break;
395 case 2:
396 v=(((uint64_t)(p[0]))<<8)+
397 ((uint64_t)(p[1]));
398 break;
399 case 1:
400 v=((uint64_t)(p[0]));
401 break;
402
403 default:
404 DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported size of %d for uint32", bs);
405 break;
406 }
407
408 return v;
409 }
410
411
412
GWEN_Sar_TlvToFileHeader(GWEN_BUFFER * mbuf,GWEN_SAR_FILEHEADER * fh)413 int GWEN_Sar_TlvToFileHeader(GWEN_BUFFER *mbuf, GWEN_SAR_FILEHEADER *fh)
414 {
415 while (GWEN_Buffer_GetBytesLeft(mbuf)) {
416 GWEN_TLV *tlv;
417
418 tlv=GWEN_TLV_fromBuffer(mbuf, 1);
419 if (tlv) {
420 const uint8_t *p;
421 uint32_t bs;
422 uint64_t v;
423 GWEN_TIME *ti;
424
425 p=GWEN_TLV_GetTagData(tlv);
426 bs=GWEN_TLV_GetTagLength(tlv);
427 switch (GWEN_TLV_GetTagType(tlv)) {
428 case GWEN_SAR_TAG_HEADER_VERSION:
429 v=GWEN_Sar_ReadUint64(p, bs);
430 DBG_DEBUG(GWEN_LOGDOMAIN, "File Header Version: %08x", (unsigned int)(v & 0xffffffff));
431 break;
432
433 case GWEN_SAR_TAG_HEADER_STATUS:
434 v=GWEN_Sar_ReadUint64(p, bs);
435 GWEN_SarFileHeader_SetStatus(fh, v & 0xffffffff);
436 break;
437
438 case GWEN_SAR_TAG_HEADER_FLAGS:
439 v=GWEN_Sar_ReadUint64(p, bs);
440 GWEN_SarFileHeader_SetFlags(fh, v & 0xffffffff);
441 break;
442
443 case GWEN_SAR_TAG_HEADER_PATH:
444 GWEN_SarFileHeader_SetPath(fh, (const char *)p);
445 break;
446
447 case GWEN_SAR_TAG_HEADER_TYPE:
448 v=GWEN_Sar_ReadUint64(p, bs);
449 GWEN_SarFileHeader_SetFileType(fh, v & 0xffffffff);
450 break;
451
452 case GWEN_SAR_TAG_HEADER_PERM:
453 v=GWEN_Sar_ReadUint64(p, bs);
454 GWEN_SarFileHeader_SetPermissions(fh, v & 0xffffffff);
455 break;
456
457 case GWEN_SAR_TAG_HEADER_ATIME:
458 ti=GWEN_Time_fromUtcString((const char *) p, "YYYYMMDDhhmmss");
459 GWEN_SarFileHeader_SetAtime(fh, ti);
460 break;
461
462 case GWEN_SAR_TAG_HEADER_MTIME:
463 ti=GWEN_Time_fromUtcString((const char *) p, "YYYYMMDDhhmmss");
464 GWEN_SarFileHeader_SetMtime(fh, ti);
465 break;
466
467 case GWEN_SAR_TAG_HEADER_CTIME:
468 ti=GWEN_Time_fromUtcString((const char *) p, "YYYYMMDDhhmmss");
469 GWEN_SarFileHeader_SetCtime(fh, ti);
470 break;
471
472 case GWEN_SAR_TAG_HEADER_SIZE:
473 v=GWEN_Sar_ReadUint64(p, bs);
474 GWEN_SarFileHeader_SetFileSize(fh, v);
475 break;
476 default:
477 DBG_WARN(GWEN_LOGDOMAIN, "Ignoring unknown tag %d", GWEN_TLV_GetTagType(tlv));
478 break;
479 }
480
481 }
482 else {
483 DBG_ERROR(GWEN_LOGDOMAIN, "No TLV in buffer");
484 return GWEN_ERROR_BAD_DATA;
485 }
486 }
487 return 0;
488 }
489
490
491
GWEN_Sar_AddAndDigestFileReg(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,GWEN_MDIGEST * md)492 int GWEN_Sar_AddAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
493 {
494 int rv;
495 const char *fname;
496 uint64_t fsize;
497 uint64_t bytesDone;
498 GWEN_BUFFER *hbuf;
499
500 assert(sr);
501 assert(sr->refCount);
502
503 fname=GWEN_SarFileHeader_GetPath(fh);
504 assert(fname);
505 fsize=GWEN_SarFileHeader_GetFileSize(fh);
506
507 /* create TLV header */
508 hbuf=GWEN_Buffer_new(0, 32, 0, 1);
509 rv=GWEN_TLV_WriteHeader(GWEN_SAR_TAG_FILE, 0x00, fsize, 1, hbuf);
510 if (rv<0) {
511 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
512 GWEN_Buffer_free(hbuf);
513 return rv;
514 }
515
516 /* write TLV header */
517 rv=GWEN_SyncIo_WriteForced(sr->archiveSio,
518 (const uint8_t *) GWEN_Buffer_GetStart(hbuf),
519 GWEN_Buffer_GetUsedBytes(hbuf));
520 if (rv<0) {
521 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
522 GWEN_Buffer_free(hbuf);
523 return rv;
524 }
525
526 GWEN_Buffer_free(hbuf);
527
528 /* copy file if fsize>0 */
529 if (fsize>0) {
530 GWEN_SYNCIO *sio;
531 uint32_t pid;
532
533 /* open input file */
534 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting);
535 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ);
536 rv=GWEN_SyncIo_Connect(sio);
537 if (rv<0) {
538 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
539 GWEN_SyncIo_free(sio);
540 return rv;
541 }
542
543 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
544 GWEN_GUI_PROGRESS_SHOW_ABORT |
545 GWEN_GUI_PROGRESS_ALLOW_EMBED |
546 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
547 I18N("File Operation"),
548 I18N("Copying file into archive"),
549 fsize,
550 0);
551 bytesDone=0;
552 while (fsize) {
553 uint8_t fbuf[10240];
554 uint64_t bs;
555
556 bs=fsize;
557 if (bs>sizeof(fbuf))
558 bs=sizeof(fbuf);
559
560 /* read from input */
561 rv=GWEN_SyncIo_Read(sio, fbuf, bs);
562 if (rv<0) {
563 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
564 GWEN_Gui_ProgressEnd(pid);
565 GWEN_SyncIo_Disconnect(sio);
566 GWEN_SyncIo_free(sio);
567 return rv;
568 }
569 bs=rv;
570
571 /* digest data */
572 rv=GWEN_MDigest_Update(md, fbuf, bs);
573 if (rv<0) {
574 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
575 GWEN_Gui_ProgressEnd(pid);
576 GWEN_SyncIo_Disconnect(sio);
577 GWEN_SyncIo_free(sio);
578 return rv;
579 }
580
581 /* write to archive */
582 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, fbuf, bs);
583 if (rv<0) {
584 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
585 GWEN_Gui_ProgressEnd(pid);
586 GWEN_SyncIo_Disconnect(sio);
587 GWEN_SyncIo_free(sio);
588 return rv;
589 }
590
591 if (bs>fsize) {
592 DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: bs>fsize (%lu>%lu)",
593 (unsigned long int)bs, (unsigned long int) fsize);
594 GWEN_Gui_ProgressEnd(pid);
595 GWEN_SyncIo_Disconnect(sio);
596 GWEN_SyncIo_free(sio);
597 return rv;
598 }
599
600 bytesDone+=bs;
601 fsize-=bs;
602
603 /* advance progress bar */
604 rv=GWEN_Gui_ProgressAdvance(pid, bytesDone);
605 if (rv<0) {
606 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
607 GWEN_Gui_ProgressEnd(pid);
608 GWEN_SyncIo_Disconnect(sio);
609 GWEN_SyncIo_free(sio);
610 return rv;
611 }
612
613 } /* while */
614 GWEN_Gui_ProgressEnd(pid);
615
616 /* close input file */
617 GWEN_SyncIo_Disconnect(sio);
618 GWEN_SyncIo_free(sio);
619 }
620
621 return 0;
622 }
623
624
625
GWEN_Sar_AddAndDigestFileLink(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,GWEN_MDIGEST * md)626 int GWEN_Sar_AddAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
627 {
628 #if ((_BSD_SOURCE || _XOPEN_SOURCE >= 500 || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) || _POSIX_C_SOURCE >= 200112L) && !defined(__MINGW32__)) || defined(OS_DARWIN)
629
630 int rv;
631 const char *fname;
632 GWEN_BUFFER *hbuf;
633 char lbuf[300];
634 int len;
635
636 assert(sr);
637 assert(sr->refCount);
638
639 fname=GWEN_SarFileHeader_GetPath(fh);
640 assert(fname);
641
642 /* read link content */
643 rv=readlink(fname, lbuf, sizeof(lbuf)-1);
644 if (rv<0) {
645 DBG_ERROR(GWEN_LOGDOMAIN, "readlink(%s): %d (%s)",
646 fname, errno, strerror(errno));
647 return GWEN_ERROR_IO;
648 }
649 len=rv;
650 lbuf[len]=0;
651
652 /* create TLV header */
653 hbuf=GWEN_Buffer_new(0, rv+8, 0, 1);
654 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_FILE, 0x00,
655 lbuf, len+1,
656 1, hbuf);
657
658
659 /* write TLV */
660 rv=GWEN_SyncIo_WriteForced(sr->archiveSio,
661 (const uint8_t *) GWEN_Buffer_GetStart(hbuf),
662 GWEN_Buffer_GetUsedBytes(hbuf));
663 if (rv<0) {
664 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
665 GWEN_Buffer_free(hbuf);
666 return rv;
667 }
668 GWEN_Buffer_free(hbuf);
669
670 /* digest data */
671 rv=GWEN_MDigest_Update(md, (const uint8_t *) lbuf, len+1);
672 if (rv<0) {
673 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
674 return rv;
675 }
676
677 return 0;
678 #else
679 /*# warning "Function readlink() is not available"*/
680 DBG_ERROR(GWEN_LOGDOMAIN, "Function readlink() is not available");
681 return GWEN_ERROR_IO;
682 #endif
683 }
684
685
686
GWEN_Sar_AddAndDigestFile(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,GWEN_MDIGEST * md)687 int GWEN_Sar_AddAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
688 {
689 int rv;
690
691 switch (GWEN_SarFileHeader_GetFileType(fh)) {
692 case GWEN_SarFileHeader_FType_File:
693 rv=GWEN_Sar_AddAndDigestFileReg(sr, fh, md);
694 break;
695 case GWEN_SarFileHeader_FType_Dir:
696 rv=0;
697 break;
698 case GWEN_SarFileHeader_FType_SymLink:
699 rv=GWEN_Sar_AddAndDigestFileLink(sr, fh, md);
700 break;
701 default:
702 DBG_ERROR(GWEN_LOGDOMAIN, "File type %d not supported", GWEN_SarFileHeader_GetFileType(fh));
703 return GWEN_ERROR_INVALID;
704 }
705
706 if (rv<0) {
707 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
708 return rv;
709 }
710
711 return 0;
712 }
713
714
715
GWEN_Sar_AddFile(GWEN_SAR * sr,const char * fname)716 int GWEN_Sar_AddFile(GWEN_SAR *sr, const char *fname)
717 {
718 struct stat st;
719 int rv;
720 GWEN_SAR_FILEHEADER *fh;
721 GWEN_TIME *ti;
722 GWEN_BUFFER *hbuf;
723 GWEN_BUFFER *xbuf;
724 GWEN_MDIGEST *md;
725 int64_t pos;
726
727 assert(sr);
728 assert(sr->refCount);
729
730 /* stat file to be added */
731 #if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
732 rv=lstat(fname, &st);
733 #else
734 rv=stat(fname, &st);
735 #endif
736 if (rv) {
737 DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %d (%s)",
738 fname, errno, strerror(errno));
739 return GWEN_ERROR_IO;
740 }
741
742 /* create and setup file header */
743 fh=GWEN_SarFileHeader_new();
744
745 /* path */
746 GWEN_SarFileHeader_SetPath(fh, fname);
747
748 /* file type */
749 switch (st.st_mode & S_IFMT) {
750 #ifdef S_IFLNK
751 case S_IFLNK:
752 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_SymLink);
753 break;
754 #endif
755 case S_IFREG:
756 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_File);
757 break;
758 case S_IFDIR:
759 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_Dir);
760 break;
761 default:
762 GWEN_SarFileHeader_free(fh);
763 return GWEN_ERROR_INVALID;
764 }
765
766 /* permissions */
767 if (st.st_mode & S_IRUSR)
768 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UREAD);
769 if (st.st_mode & S_IWUSR)
770 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UWRITE);
771 if (st.st_mode & S_IXUSR)
772 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UEXEC);
773
774 #ifdef S_IRGRP
775 if (st.st_mode & S_IRGRP)
776 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GREAD);
777 #endif
778 #ifdef S_IWGRP
779 if (st.st_mode & S_IWGRP)
780 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GWRITE);
781 #endif
782 #ifdef S_IXGRP
783 if (st.st_mode & S_IXGRP)
784 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GEXEC);
785 #endif
786
787 #ifdef S_IROTH
788 if (st.st_mode & S_IROTH)
789 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OREAD);
790 #endif
791 #ifdef S_IWOTH
792 if (st.st_mode & S_IWOTH)
793 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OWRITE);
794 #endif
795 #ifdef S_IXOTH
796 if (st.st_mode & S_IXOTH)
797 GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OEXEC);
798 #endif
799
800 /* atime */
801 ti=GWEN_Time_fromSeconds(st.st_atime);
802 GWEN_SarFileHeader_SetAtime(fh, ti);
803
804 /* mtime */
805 ti=GWEN_Time_fromSeconds(st.st_mtime);
806 GWEN_SarFileHeader_SetMtime(fh, ti);
807
808 /* ctime */
809 ti=GWEN_Time_fromSeconds(st.st_ctime);
810 GWEN_SarFileHeader_SetCtime(fh, ti);
811
812 /* file size */
813 GWEN_SarFileHeader_SetFileSize(fh, st.st_size);
814
815
816 /* prepare header */
817 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
818 GWEN_Buffer_ReserveBytes(hbuf, 16);
819 rv=GWEN_Sar_FileHeaderToTlv(fh, hbuf);
820 if (rv<0) {
821 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
822 GWEN_Buffer_free(hbuf);
823 GWEN_SarFileHeader_free(fh);
824 return rv;
825 }
826
827 /* create TLV header for file header */
828 xbuf=GWEN_Buffer_new(0, 16, 0, 1);
829 rv=GWEN_TLV_WriteHeader(GWEN_SAR_TAG_HEADER, 0xe0,
830 GWEN_Buffer_GetUsedBytes(hbuf), 1, xbuf);
831 if (rv<0) {
832 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
833 GWEN_Buffer_free(xbuf);
834 GWEN_Buffer_free(hbuf);
835 GWEN_SarFileHeader_free(fh);
836 return rv;
837 }
838
839 /* insert TLV header into file header buffer */
840 GWEN_Buffer_SetPos(hbuf, 0);
841 GWEN_Buffer_InsertBytes(hbuf,
842 GWEN_Buffer_GetStart(xbuf),
843 GWEN_Buffer_GetUsedBytes(xbuf));
844 GWEN_Buffer_SetPos(hbuf, GWEN_Buffer_GetUsedBytes(hbuf));
845 GWEN_Buffer_free(xbuf);
846
847 /* seek to end of file */
848 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, 0, GWEN_SyncIo_File_Whence_End);
849 if (pos<0) {
850 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
851 GWEN_Buffer_free(hbuf);
852 GWEN_SarFileHeader_free(fh);
853 return (int) pos;
854 }
855
856 /* write header into archive file */
857 rv=GWEN_SyncIo_WriteForced(sr->archiveSio,
858 (const uint8_t *) GWEN_Buffer_GetStart(hbuf),
859 GWEN_Buffer_GetUsedBytes(hbuf));
860 if (rv<0) {
861 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
862 GWEN_Buffer_free(hbuf);
863 GWEN_SarFileHeader_free(fh);
864 return rv;
865 }
866
867 /* prepare digest */
868 md=GWEN_MDigest_Rmd160_new();
869 rv=GWEN_MDigest_Begin(md);
870 if (rv<0) {
871 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
872 GWEN_MDigest_free(md);
873 GWEN_Buffer_free(hbuf);
874 GWEN_SarFileHeader_free(fh);
875 return rv;
876 }
877
878 /* digest header */
879 rv=GWEN_MDigest_Update(md, (const uint8_t *) GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf));
880 if (rv<0) {
881 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
882 GWEN_MDigest_free(md);
883 GWEN_Buffer_free(hbuf);
884 GWEN_SarFileHeader_free(fh);
885 return rv;
886 }
887
888 GWEN_Buffer_Reset(hbuf);
889
890 /* copy file into archive */
891 rv=GWEN_Sar_AddAndDigestFile(sr, fh, md);
892 if (rv<0) {
893 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
894 GWEN_MDigest_free(md);
895 GWEN_Buffer_free(hbuf);
896 GWEN_SarFileHeader_free(fh);
897 return rv;
898 }
899
900 /* finish hash */
901 rv=GWEN_MDigest_End(md);
902 if (rv<0) {
903 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
904 GWEN_MDigest_free(md);
905 GWEN_Buffer_free(hbuf);
906 GWEN_SarFileHeader_free(fh);
907 return rv;
908 }
909
910 /* create hash TLV */
911 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HASH, 0x00,
912 GWEN_MDigest_GetDigestPtr(md),
913 GWEN_MDigest_GetDigestSize(md),
914 1, hbuf);
915 GWEN_MDigest_free(md);
916
917 /* write hash into archive file */
918 rv=GWEN_SyncIo_WriteForced(sr->archiveSio,
919 (const uint8_t *) GWEN_Buffer_GetStart(hbuf),
920 GWEN_Buffer_GetUsedBytes(hbuf));
921 if (rv<0) {
922 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
923 GWEN_Buffer_free(hbuf);
924 GWEN_SarFileHeader_free(fh);
925 return rv;
926 }
927
928 /* done */
929 GWEN_Buffer_free(hbuf);
930 GWEN_SarFileHeader_free(fh);
931 return 0;
932 }
933
934
935
936
GWEN_Sar_ScanFile(GWEN_SAR * sr)937 int GWEN_Sar_ScanFile(GWEN_SAR *sr)
938 {
939 int rv;
940 int64_t pos;
941 GWEN_BUFFER *mbuf;
942 GWEN_SAR_FILEHEADER *lastHeader=NULL;
943
944 assert(sr);
945 assert(sr->refCount);
946
947 sr->signaturePos=0;
948 sr->signatureSize=0;
949
950 /* scan all TLV elements */
951 pos=0;
952 mbuf=GWEN_Buffer_new(0, 1024, 0, 1);
953 for (;;) {
954 int64_t startOfTagHeader;
955 int64_t startOfTagData;
956 unsigned int tagType;
957 uint32_t tagLength;
958 uint32_t fullTagSize;
959 uint32_t bs;
960 GWEN_TLV *tlv;
961 uint8_t buffer[32];
962
963 startOfTagHeader=pos;
964 rv=GWEN_SyncIo_Read(sr->archiveSio, buffer, sizeof(buffer));
965 if (rv<0) {
966 if (rv==GWEN_ERROR_EOF)
967 break;
968 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
969 GWEN_Buffer_free(mbuf);
970 return rv;
971 }
972 else if (rv==0) {
973 DBG_VERBOUS(GWEN_LOGDOMAIN, "EOF met");
974 break;
975 }
976 bs=rv;
977
978 /* read start of fileheader TLV */
979 tlv=GWEN_TLV_new();
980 rv=GWEN_TLV_ReadHeader(tlv, buffer, bs, 1);
981 if (rv<2) {
982 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
983 GWEN_TLV_free(tlv);
984 GWEN_Buffer_free(mbuf);
985 return rv;
986 }
987 /* got it, now calculate start of tag data */
988 startOfTagData=pos+rv;
989 tagLength=GWEN_TLV_GetTagLength(tlv);
990 tagType=GWEN_TLV_GetTagType(tlv);
991 fullTagSize=GWEN_TLV_GetTagSize(tlv);
992 GWEN_TLV_free(tlv);
993
994 /* seek to start of header data */
995 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, startOfTagData, GWEN_SyncIo_File_Whence_Set);
996 if (pos<0) {
997 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
998 GWEN_Buffer_free(mbuf);
999 return (int) pos;
1000 }
1001
1002 /* now read or skip info */
1003 if (tagType==GWEN_SAR_TAG_HEADER) {
1004 GWEN_SAR_FILEHEADER *fh;
1005 const char *s;
1006
1007 /* alloc memory for data */
1008 GWEN_Buffer_AllocRoom(mbuf, tagLength);
1009
1010 /* read header data */
1011 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, (uint8_t *) GWEN_Buffer_GetStart(mbuf), tagLength);
1012 if (rv<0) {
1013 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1014 GWEN_Buffer_free(mbuf);
1015 return rv;
1016 }
1017 GWEN_Buffer_IncrementPos(mbuf, tagLength);
1018 GWEN_Buffer_AdjustUsedBytes(mbuf);
1019 GWEN_Buffer_Rewind(mbuf);
1020
1021 /* now parse header */
1022 fh=GWEN_SarFileHeader_new();
1023 rv=GWEN_Sar_TlvToFileHeader(mbuf, fh);
1024 if (rv<0) {
1025 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1026 GWEN_SarFileHeader_free(fh);
1027 GWEN_Buffer_free(mbuf);
1028 return rv;
1029 }
1030
1031 GWEN_SarFileHeader_SetHeaderStartPos(fh, startOfTagHeader);
1032 GWEN_SarFileHeader_SetHeaderSize(fh, fullTagSize);
1033
1034 s=GWEN_SarFileHeader_GetPath(fh);
1035 DBG_DEBUG(GWEN_LOGDOMAIN, "Got entry [%s]", s?s:"(empty)");
1036
1037 GWEN_SarFileHeader_List_Add(fh, sr->headers);
1038 lastHeader=fh;
1039 }
1040 else if (tagType==GWEN_SAR_TAG_FILE) {
1041 if (lastHeader==NULL) {
1042 DBG_ERROR(GWEN_LOGDOMAIN, "Bad file structure: No file header before data");
1043 GWEN_Buffer_free(mbuf);
1044 return GWEN_ERROR_BAD_DATA;
1045 }
1046 if (GWEN_SarFileHeader_GetFileType(lastHeader)!=GWEN_SarFileHeader_FType_SymLink &&
1047 GWEN_SarFileHeader_GetFileSize(lastHeader)!=tagLength) {
1048 DBG_ERROR(GWEN_LOGDOMAIN, "File size in header and in archive differ (%s: hs=%lu, ts=%lu)",
1049 GWEN_SarFileHeader_GetPath(lastHeader),
1050 (unsigned long int) GWEN_SarFileHeader_GetFileSize(lastHeader),
1051 (unsigned long int) tagLength);
1052 GWEN_Buffer_free(mbuf);
1053 return GWEN_ERROR_BAD_DATA;
1054 }
1055 /* only store position of file data */
1056 GWEN_SarFileHeader_SetDataPos(lastHeader, startOfTagData);
1057 GWEN_SarFileHeader_SetDataSize(lastHeader, tagLength);
1058
1059 /* skip data */
1060 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current);
1061 if (pos<0) {
1062 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1063 GWEN_Buffer_free(mbuf);
1064 return (int) pos;
1065 }
1066 }
1067 else if (tagType==GWEN_SAR_TAG_HASH) {
1068 if (lastHeader==NULL) {
1069 DBG_ERROR(GWEN_LOGDOMAIN, "Bad file structure: No file header before data");
1070 GWEN_Buffer_free(mbuf);
1071 return GWEN_ERROR_BAD_DATA;
1072 }
1073 /* only store position of file data */
1074 GWEN_SarFileHeader_SetHashPos(lastHeader, startOfTagData);
1075
1076 /* skip data */
1077 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current);
1078 if (pos<0) {
1079 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1080 GWEN_Buffer_free(mbuf);
1081 return (int) pos;
1082 }
1083 }
1084 else if (tagType==GWEN_SAR_TAG_SIGNATURE) {
1085 /* only store position of file data */
1086 DBG_INFO(GWEN_LOGDOMAIN, "Signature found");
1087 sr->signaturePos=startOfTagData;
1088 sr->signatureSize=tagLength;
1089
1090 /* skip data */
1091 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current);
1092 if (pos<0) {
1093 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1094 GWEN_Buffer_free(mbuf);
1095 return (int) pos;
1096 }
1097 }
1098 else {
1099 DBG_WARN(GWEN_LOGDOMAIN, "Unknown TAG %d, ignoring", (int) tagType);
1100 /* just skip data */
1101 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current);
1102 if (pos<0) {
1103 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1104 GWEN_Buffer_free(mbuf);
1105 return (int) pos;
1106 }
1107 }
1108
1109 GWEN_Buffer_Reset(mbuf);
1110 pos=startOfTagData+tagLength;
1111 } /* for */
1112
1113 /* done */
1114 GWEN_Buffer_free(mbuf);
1115 return 0;
1116 }
1117
1118
1119
GWEN_Sar_ExtractAndDigestFileReg(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,int checkOnly)1120 int GWEN_Sar_ExtractAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
1121 {
1122 int rv;
1123 const char *fname;
1124 uint32_t perms;
1125 uint64_t dpos;
1126 uint64_t fsize;
1127 uint64_t bytesDone;
1128 uint64_t hsize;
1129 uint64_t hpos;
1130 uint64_t mpos;
1131 int64_t pos;
1132 GWEN_MDIGEST *md;
1133
1134 assert(sr);
1135 assert(sr->refCount);
1136
1137 md=GWEN_MDigest_Rmd160_new();
1138 rv=GWEN_MDigest_Begin(md);
1139 if (rv<0) {
1140 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1141 GWEN_MDigest_free(md);
1142 return rv;
1143 }
1144
1145 fname=GWEN_SarFileHeader_GetPath(fh);
1146 assert(fname);
1147 perms=GWEN_SarFileHeader_GetPermissions(fh);
1148 fsize=GWEN_SarFileHeader_GetFileSize(fh);
1149 dpos=GWEN_SarFileHeader_GetDataPos(fh);
1150
1151 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh);
1152 hsize=GWEN_SarFileHeader_GetHeaderSize(fh);
1153 if (hsize>0) {
1154 GWEN_BUFFER *mbuf;
1155
1156 /* seek to start of header */
1157 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set);
1158 if (pos<0) {
1159 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1160 GWEN_MDigest_free(md);
1161 return (int) pos;
1162 }
1163
1164 mbuf=GWEN_Buffer_new(0, hsize, 0, 1);
1165 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1166 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1167 hsize);
1168 if (rv<0) {
1169 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1170 GWEN_Buffer_free(mbuf);
1171 GWEN_MDigest_free(md);
1172 return rv;
1173 }
1174 GWEN_Buffer_IncrementPos(mbuf, hsize);
1175 GWEN_Buffer_AdjustUsedBytes(mbuf);
1176
1177 /* digest TLV */
1178 rv=GWEN_MDigest_Update(md, (const uint8_t *) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf));
1179 if (rv<0) {
1180 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1181 GWEN_Buffer_free(mbuf);
1182 GWEN_MDigest_free(md);
1183 return rv;
1184 }
1185 GWEN_Buffer_free(mbuf);
1186 }
1187
1188 /* copy file if fsize>0 */
1189 if (1) {
1190 GWEN_SYNCIO *sio=NULL;
1191 uint32_t pid;
1192
1193 /* open input file */
1194 if (!checkOnly) {
1195 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateNew);
1196 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ | GWEN_SYNCIO_FILE_FLAGS_WRITE);
1197 GWEN_SyncIo_AddFlags(sio, perms);
1198 rv=GWEN_SyncIo_Connect(sio);
1199 if (rv<0) {
1200 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1201 GWEN_SyncIo_free(sio);
1202 GWEN_MDigest_free(md);
1203 return rv;
1204 }
1205 }
1206
1207 if (fsize>0) {
1208 /* seek to start of data */
1209 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, dpos, GWEN_SyncIo_File_Whence_Set);
1210 if (pos<0) {
1211 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1212 if (!checkOnly) {
1213 GWEN_SyncIo_Disconnect(sio);
1214 GWEN_SyncIo_free(sio);
1215 }
1216 GWEN_MDigest_free(md);
1217 return (int) pos;
1218 }
1219
1220 /* start extracting */
1221 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
1222 GWEN_GUI_PROGRESS_SHOW_ABORT |
1223 GWEN_GUI_PROGRESS_ALLOW_EMBED |
1224 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
1225 I18N("File Operation"),
1226 I18N("Extracting file from archive"),
1227 fsize,
1228 0);
1229 bytesDone=0;
1230 while (fsize) {
1231 uint8_t fbuf[10240];
1232 uint64_t bs;
1233
1234 bs=fsize;
1235 if (bs>sizeof(fbuf))
1236 bs=sizeof(fbuf);
1237
1238 /* read from input */
1239 rv=GWEN_SyncIo_Read(sr->archiveSio, fbuf, bs);
1240 if (rv<0) {
1241 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1242 GWEN_Gui_ProgressEnd(pid);
1243 if (!checkOnly) {
1244 GWEN_SyncIo_Disconnect(sio);
1245 GWEN_SyncIo_free(sio);
1246 }
1247 GWEN_MDigest_free(md);
1248 return rv;
1249 }
1250 bs=rv;
1251
1252 /* digest data */
1253 rv=GWEN_MDigest_Update(md, fbuf, bs);
1254 if (rv<0) {
1255 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1256 GWEN_Gui_ProgressEnd(pid);
1257 if (!checkOnly) {
1258 GWEN_SyncIo_Disconnect(sio);
1259 GWEN_SyncIo_free(sio);
1260 }
1261 GWEN_MDigest_free(md);
1262 return rv;
1263 }
1264
1265 if (!checkOnly) {
1266 /* write to archive */
1267 rv=GWEN_SyncIo_WriteForced(sio, fbuf, bs);
1268 if (rv<0) {
1269 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1270 GWEN_Gui_ProgressEnd(pid);
1271 if (!checkOnly) {
1272 GWEN_SyncIo_Disconnect(sio);
1273 GWEN_SyncIo_free(sio);
1274 }
1275 GWEN_MDigest_free(md);
1276 return rv;
1277 }
1278 }
1279
1280 if (bs>fsize) {
1281 DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: bs>fsize (%lu>%lu)",
1282 (unsigned long int)bs, (unsigned long int) fsize);
1283 GWEN_Gui_ProgressEnd(pid);
1284 if (!checkOnly) {
1285 GWEN_SyncIo_Disconnect(sio);
1286 GWEN_SyncIo_free(sio);
1287 }
1288 GWEN_MDigest_free(md);
1289 return rv;
1290 }
1291
1292 bytesDone+=bs;
1293 fsize-=bs;
1294
1295 /* advance progress bar */
1296 rv=GWEN_Gui_ProgressAdvance(pid, bytesDone);
1297 if (rv<0) {
1298 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1299 GWEN_Gui_ProgressEnd(pid);
1300 if (!checkOnly) {
1301 GWEN_SyncIo_Disconnect(sio);
1302 GWEN_SyncIo_free(sio);
1303 }
1304 GWEN_MDigest_free(md);
1305 return rv;
1306 }
1307
1308 } /* while */
1309 GWEN_Gui_ProgressEnd(pid);
1310 }
1311
1312 if (!checkOnly) {
1313 /* close output file */
1314 GWEN_SyncIo_Disconnect(sio);
1315 GWEN_SyncIo_free(sio);
1316 }
1317
1318 /* finish hash */
1319 rv=GWEN_MDigest_End(md);
1320 if (rv<0) {
1321 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1322 GWEN_MDigest_free(md);
1323 return rv;
1324 }
1325
1326 /* read and check hash */
1327 mpos=GWEN_SarFileHeader_GetHashPos(fh);
1328 if (mpos) {
1329 GWEN_BUFFER *mbuf;
1330
1331 /* seek to end of file */
1332 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set);
1333 if (pos<0) {
1334 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1335 GWEN_MDigest_free(md);
1336 return (int) pos;
1337 }
1338
1339 /* read 20 bytes of hash */
1340 mbuf=GWEN_Buffer_new(0, 20, 0, 1);
1341 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1342 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1343 20);
1344 if (rv<0) {
1345 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1346 GWEN_Buffer_free(mbuf);
1347 GWEN_MDigest_free(md);
1348 return rv;
1349 }
1350 GWEN_Buffer_IncrementPos(mbuf, 20);
1351 GWEN_Buffer_AdjustUsedBytes(mbuf);
1352
1353 if (memcmp(GWEN_MDigest_GetDigestPtr(md),
1354 GWEN_Buffer_GetStart(mbuf),
1355 20)!=0) {
1356 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1357 DBG_ERROR(0, "Hash don't match:");
1358 GWEN_Text_LogString((const char *) GWEN_MDigest_GetDigestPtr(md), 20,
1359 GWEN_LOGDOMAIN, GWEN_LoggerLevel_Error);
1360
1361 GWEN_Text_LogString(GWEN_Buffer_GetStart(mbuf), 20,
1362 GWEN_LOGDOMAIN, GWEN_LoggerLevel_Error);
1363 GWEN_Buffer_free(mbuf);
1364 GWEN_MDigest_free(md);
1365 return GWEN_ERROR_BAD_DATA;
1366 }
1367
1368 GWEN_Buffer_free(mbuf);
1369 }
1370
1371 GWEN_MDigest_free(md);
1372 }
1373
1374 return 0;
1375 }
1376
1377
1378
GWEN_Sar_ExtractAndDigestFileLink(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,int checkOnly)1379 int GWEN_Sar_ExtractAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
1380 {
1381 #if ((_BSD_SOURCE || _XOPEN_SOURCE >= 500 || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) || _POSIX_C_SOURCE >= 200112L) && !defined(__MINGW32__)) || defined(OS_DARWIN)
1382 int rv;
1383 const char *fname;
1384 uint32_t perms;
1385 uint64_t dpos;
1386 uint64_t fsize;
1387 uint64_t hsize;
1388 uint64_t hpos;
1389 uint64_t mpos;
1390 int64_t pos;
1391 GWEN_MDIGEST *md;
1392
1393 assert(sr);
1394 assert(sr->refCount);
1395
1396 md=GWEN_MDigest_Rmd160_new();
1397 rv=GWEN_MDigest_Begin(md);
1398 if (rv<0) {
1399 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1400 GWEN_MDigest_free(md);
1401 return rv;
1402 }
1403
1404 fname=GWEN_SarFileHeader_GetPath(fh);
1405 perms=GWEN_SarFileHeader_GetPermissions(fh);
1406 assert(fname);
1407 fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */
1408 dpos=GWEN_SarFileHeader_GetDataPos(fh);
1409
1410 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh);
1411 hsize=GWEN_SarFileHeader_GetHeaderSize(fh);
1412 if (hsize>0) {
1413 GWEN_BUFFER *mbuf;
1414
1415 /* seek to header pos */
1416 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set);
1417 if (pos<0) {
1418 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1419 GWEN_MDigest_free(md);
1420 return (int) pos;
1421 }
1422
1423 mbuf=GWEN_Buffer_new(0, hsize, 0, 1);
1424 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1425 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1426 hsize);
1427 if (rv<0) {
1428 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1429 GWEN_Buffer_free(mbuf);
1430 GWEN_MDigest_free(md);
1431 return rv;
1432 }
1433 GWEN_Buffer_IncrementPos(mbuf, hsize);
1434 GWEN_Buffer_AdjustUsedBytes(mbuf);
1435
1436 /* digest header TLV */
1437 rv=GWEN_MDigest_Update(md, (const uint8_t *) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf));
1438 if (rv<0) {
1439 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1440 GWEN_Buffer_free(mbuf);
1441 GWEN_MDigest_free(md);
1442 return rv;
1443 }
1444 GWEN_Buffer_free(mbuf);
1445 }
1446
1447 /* seek to data pos */
1448 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, dpos, GWEN_SyncIo_File_Whence_Set);
1449 if (pos<0) {
1450 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1451 GWEN_MDigest_free(md);
1452 return (int) pos;
1453 }
1454
1455 /* copy file if fsize>0 */
1456 if (fsize>0) { /* fsize is the size of the file tag data */
1457 GWEN_BUFFER *mbuf;
1458
1459 mbuf=GWEN_Buffer_new(0, fsize, 0, 1);
1460 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1461 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1462 fsize);
1463 if (rv<0) {
1464 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1465 GWEN_Buffer_free(mbuf);
1466 GWEN_MDigest_free(md);
1467 return rv;
1468 }
1469 GWEN_Buffer_IncrementPos(mbuf, fsize);
1470 GWEN_Buffer_AdjustUsedBytes(mbuf);
1471
1472 /* digest TLV */
1473 rv=GWEN_MDigest_Update(md, (const uint8_t *) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf));
1474 if (rv<0) {
1475 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1476 GWEN_Buffer_free(mbuf);
1477 GWEN_MDigest_free(md);
1478 return rv;
1479 }
1480
1481 if (!checkOnly) {
1482 mode_t mode=0;
1483
1484 if (symlink(GWEN_Buffer_GetStart(mbuf), fname)) {
1485 DBG_ERROR(GWEN_LOGDOMAIN, "symlink(%s, %s): %d (%s)",
1486 GWEN_Buffer_GetStart(mbuf),
1487 fname, errno, strerror(errno));
1488 GWEN_Buffer_free(mbuf);
1489 GWEN_MDigest_free(md);
1490 return GWEN_ERROR_IO;
1491 }
1492 /* owner perms */
1493 if (perms & GWEN_SYNCIO_FILE_FLAGS_UREAD)
1494 mode|=S_IRUSR;
1495 if (perms & GWEN_SYNCIO_FILE_FLAGS_UWRITE)
1496 mode|=S_IWUSR;
1497 if (perms & GWEN_SYNCIO_FILE_FLAGS_UEXEC)
1498 mode|=S_IXUSR;
1499
1500 #if 0 /* CHMOD on symlinks doesn't work */
1501
1502 /* group perms */
1503 #ifdef S_IRGRP
1504 if (perms & GWEN_SYNCIO_FILE_FLAGS_GREAD)
1505 mode|=S_IRGRP;
1506 #endif
1507 #ifdef S_IWGRP
1508 if (perms & GWEN_SYNCIO_FILE_FLAGS_GWRITE)
1509 mode|=S_IWGRP;
1510 #endif
1511 #ifdef S_IXGRP
1512 if (perms & GWEN_SYNCIO_FILE_FLAGS_GEXEC)
1513 mode|=S_IXGRP;
1514 #endif
1515
1516 /* other perms */
1517 #ifdef S_IROTH
1518 if (perms & GWEN_SYNCIO_FILE_FLAGS_OREAD)
1519 mode|=S_IROTH;
1520 #endif
1521 #ifdef S_IWOTH
1522 if (perms & GWEN_SYNCIO_FILE_FLAGS_OWRITE)
1523 mode|=S_IWOTH;
1524 #endif
1525 #ifdef S_IXOTH
1526 if (perms & GWEN_SYNCIO_FILE_FLAGS_OEXEC)
1527 mode|=S_IXOTH;
1528 #endif
1529
1530 rv=chmod(fname, mode);
1531 if (rv<0) {
1532 DBG_WARN(GWEN_LOGDOMAIN, "chmod(%s): %d (%s), ignoring",
1533 fname, errno, strerror(errno));
1534 }
1535
1536 #endif
1537 }
1538 GWEN_Buffer_free(mbuf);
1539 }
1540
1541 /* finish hash */
1542 rv=GWEN_MDigest_End(md);
1543 if (rv<0) {
1544 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1545 GWEN_MDigest_free(md);
1546 return rv;
1547 }
1548
1549 /* read and check hash */
1550 mpos=GWEN_SarFileHeader_GetHashPos(fh);
1551 if (mpos) {
1552 GWEN_BUFFER *mbuf;
1553
1554 /* seek to end of file */
1555 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set);
1556 if (pos<0) {
1557 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1558 GWEN_MDigest_free(md);
1559 return (int) pos;
1560 }
1561
1562 /* read 20 bytes of hash */
1563 mbuf=GWEN_Buffer_new(0, 20, 0, 1);
1564 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1565 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1566 20);
1567 if (rv<0) {
1568 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1569 GWEN_Buffer_free(mbuf);
1570 GWEN_MDigest_free(md);
1571 if (!checkOnly)
1572 unlink(fname);
1573 return rv;
1574 }
1575 GWEN_Buffer_IncrementPos(mbuf, 20);
1576 GWEN_Buffer_AdjustUsedBytes(mbuf);
1577
1578 if (memcmp(GWEN_MDigest_GetDigestPtr(md),
1579 GWEN_Buffer_GetStart(mbuf),
1580 20)!=0) {
1581 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1582 GWEN_Buffer_free(mbuf);
1583 GWEN_MDigest_free(md);
1584 if (!checkOnly)
1585 unlink(fname);
1586 return GWEN_ERROR_BAD_DATA;
1587 }
1588
1589 GWEN_Buffer_free(mbuf);
1590 }
1591
1592 GWEN_MDigest_free(md);
1593
1594 return 0;
1595 #else
1596 /*# warning "Function symlink() is not available"*/
1597 DBG_ERROR(GWEN_LOGDOMAIN, "Function symlink() is not available");
1598 return GWEN_ERROR_IO;
1599 #endif
1600 }
1601
1602
1603
GWEN_Sar_ExtractAndDigestFileDir(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,int checkOnly)1604 int GWEN_Sar_ExtractAndDigestFileDir(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
1605 {
1606 int rv;
1607 const char *fname;
1608 //uint64_t dpos;
1609 //uint64_t fsize;
1610 uint64_t hsize;
1611 uint64_t hpos;
1612 uint64_t mpos;
1613 int64_t pos;
1614 GWEN_MDIGEST *md;
1615 GWEN_BUFFER *mbuf;
1616 uint32_t perms;
1617
1618 assert(sr);
1619 assert(sr->refCount);
1620
1621 md=GWEN_MDigest_Rmd160_new();
1622 rv=GWEN_MDigest_Begin(md);
1623 if (rv<0) {
1624 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1625 GWEN_MDigest_free(md);
1626 return rv;
1627 }
1628
1629 fname=GWEN_SarFileHeader_GetPath(fh);
1630 assert(fname);
1631 perms=GWEN_SarFileHeader_GetPermissions(fh);
1632 //fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */
1633 //dpos=GWEN_SarFileHeader_GetDataPos(fh);
1634
1635 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh);
1636 hsize=GWEN_SarFileHeader_GetHeaderSize(fh);
1637 assert(hsize);
1638
1639 /* seek to end of file */
1640 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set);
1641 if (pos<0) {
1642 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1643 GWEN_MDigest_free(md);
1644 return (int) pos;
1645 }
1646
1647 mbuf=GWEN_Buffer_new(0, hsize, 0, 1);
1648 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1649 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1650 hsize);
1651 if (rv<0) {
1652 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1653 GWEN_Buffer_free(mbuf);
1654 GWEN_MDigest_free(md);
1655 return rv;
1656 }
1657 GWEN_Buffer_IncrementPos(mbuf, hsize);
1658 GWEN_Buffer_AdjustUsedBytes(mbuf);
1659
1660 /* digest TLV */
1661 rv=GWEN_MDigest_Update(md, (const uint8_t *) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf));
1662 if (rv<0) {
1663 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1664 GWEN_Buffer_free(mbuf);
1665 GWEN_MDigest_free(md);
1666 return rv;
1667 }
1668 GWEN_Buffer_free(mbuf);
1669
1670 /* finish hash */
1671 rv=GWEN_MDigest_End(md);
1672 if (rv<0) {
1673 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1674 GWEN_MDigest_free(md);
1675 return rv;
1676 }
1677
1678 /* read and check hash */
1679 mpos=GWEN_SarFileHeader_GetHashPos(fh);
1680 if (mpos) {
1681 GWEN_BUFFER *mbuf;
1682
1683 /* seek to end of file */
1684 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set);
1685 if (pos<0) {
1686 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
1687 GWEN_MDigest_free(md);
1688 return (int) pos;
1689 }
1690
1691 /* read 20 bytes of hash */
1692 mbuf=GWEN_Buffer_new(0, 20, 0, 1);
1693 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
1694 (uint8_t *) GWEN_Buffer_GetStart(mbuf),
1695 20);
1696 if (rv<0) {
1697 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1698 GWEN_Buffer_free(mbuf);
1699 GWEN_MDigest_free(md);
1700 unlink(fname);
1701 return rv;
1702 }
1703 GWEN_Buffer_IncrementPos(mbuf, 20);
1704 GWEN_Buffer_AdjustUsedBytes(mbuf);
1705
1706 if (memcmp(GWEN_MDigest_GetDigestPtr(md),
1707 GWEN_Buffer_GetStart(mbuf),
1708 20)!=0) {
1709 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1710 GWEN_Buffer_free(mbuf);
1711 GWEN_MDigest_free(md);
1712 unlink(fname);
1713 return GWEN_ERROR_BAD_DATA;
1714 }
1715
1716 GWEN_Buffer_free(mbuf);
1717 }
1718
1719 GWEN_MDigest_free(md);
1720
1721 if (!checkOnly) {
1722 mode_t mode=0;
1723
1724 /* owner perms */
1725 if (perms & GWEN_SYNCIO_FILE_FLAGS_UREAD)
1726 mode|=S_IRUSR;
1727 if (perms & GWEN_SYNCIO_FILE_FLAGS_UWRITE)
1728 mode|=S_IWUSR;
1729 if (perms & GWEN_SYNCIO_FILE_FLAGS_UEXEC)
1730 mode|=S_IXUSR;
1731
1732 /* group perms */
1733 #ifdef S_IRGRP
1734 if (perms & GWEN_SYNCIO_FILE_FLAGS_GREAD)
1735 mode|=S_IRGRP;
1736 #endif
1737 #ifdef S_IWGRP
1738 if (perms & GWEN_SYNCIO_FILE_FLAGS_GWRITE)
1739 mode|=S_IWGRP;
1740 #endif
1741 #ifdef S_IXGRP
1742 if (perms & GWEN_SYNCIO_FILE_FLAGS_GEXEC)
1743 mode|=S_IXGRP;
1744 #endif
1745
1746 /* other perms */
1747 #ifdef S_IROTH
1748 if (perms & GWEN_SYNCIO_FILE_FLAGS_OREAD)
1749 mode|=S_IROTH;
1750 #endif
1751 #ifdef S_IWOTH
1752 if (perms & GWEN_SYNCIO_FILE_FLAGS_OWRITE)
1753 mode|=S_IWOTH;
1754 #endif
1755 #ifdef S_IXOTH
1756 if (perms & GWEN_SYNCIO_FILE_FLAGS_OEXEC)
1757 mode|=S_IXOTH;
1758 #endif
1759
1760 /* create folder */
1761 #ifndef OS_WIN32
1762 rv=mkdir(fname, mode);
1763 #else
1764 rv=mkdir(fname);
1765 #endif
1766 if (rv) {
1767 DBG_ERROR(GWEN_LOGDOMAIN, "mkdir(%s): %d (%s)",
1768 fname, errno, strerror(errno));
1769 return GWEN_ERROR_IO;
1770 }
1771 }
1772
1773 return 0;
1774 }
1775
1776
1777
GWEN_Sar_ExtractAndDigestFile(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh,int checkOnly)1778 int GWEN_Sar_ExtractAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
1779 {
1780 int rv;
1781
1782 switch (GWEN_SarFileHeader_GetFileType(fh)) {
1783 case GWEN_SarFileHeader_FType_File:
1784 rv=GWEN_Sar_ExtractAndDigestFileReg(sr, fh, checkOnly);
1785 break;
1786 case GWEN_SarFileHeader_FType_Dir:
1787 rv=GWEN_Sar_ExtractAndDigestFileDir(sr, fh, checkOnly);
1788 break;
1789 case GWEN_SarFileHeader_FType_SymLink:
1790 rv=GWEN_Sar_ExtractAndDigestFileLink(sr, fh, checkOnly);
1791 break;
1792 default:
1793 DBG_ERROR(GWEN_LOGDOMAIN, "File type %d not supported", GWEN_SarFileHeader_GetFileType(fh));
1794 return GWEN_ERROR_INVALID;
1795 }
1796
1797 if (rv<0) {
1798 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1799 return rv;
1800 }
1801
1802 return 0;
1803 }
1804
1805
1806
GWEN_Sar_ExtractFile(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh)1807 int GWEN_Sar_ExtractFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh)
1808 {
1809 int rv;
1810
1811 rv=GWEN_Sar_ExtractAndDigestFile(sr, fh, 0);
1812 if (rv<0) {
1813 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1814 return rv;
1815 }
1816
1817 return rv;
1818 }
1819
1820
1821
GWEN_Sar_CheckFile(GWEN_SAR * sr,const GWEN_SAR_FILEHEADER * fh)1822 int GWEN_Sar_CheckFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh)
1823 {
1824 int rv;
1825
1826 rv=GWEN_Sar_ExtractAndDigestFile(sr, fh, 1);
1827 if (rv<0) {
1828 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1829 return rv;
1830 }
1831
1832 return rv;
1833 }
1834
1835
1836
GWEN_Sar_GetHeaders(GWEN_SAR * sr)1837 const GWEN_SAR_FILEHEADER_LIST *GWEN_Sar_GetHeaders(GWEN_SAR *sr)
1838 {
1839 assert(sr);
1840 assert(sr->refCount);
1841 return sr->headers;
1842 }
1843
1844
1845
GWEN_Sar__UnpackArchive(const char * inFile,const char * where)1846 int GWEN_Sar__UnpackArchive(const char *inFile, const char *where)
1847 {
1848 GWEN_SAR *sr;
1849 int rv;
1850 const GWEN_SAR_FILEHEADER_LIST *fhl;
1851
1852 /* open archive file */
1853 sr=GWEN_Sar_new();
1854 rv=GWEN_Sar_OpenArchive(sr, inFile,
1855 GWEN_SyncIo_File_CreationMode_OpenExisting,
1856 GWEN_SYNCIO_FILE_FLAGS_READ);
1857 if (rv<0) {
1858 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1859 return rv;
1860 }
1861
1862 /* change to "where" */
1863 if (chdir(where)) {
1864 DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", where, strerror(errno));
1865 GWEN_Sar_CloseArchive(sr, 1);
1866 GWEN_Sar_free(sr);
1867 return GWEN_ERROR_IO;
1868 }
1869
1870 fhl=GWEN_Sar_GetHeaders(sr);
1871 if (fhl) {
1872 const GWEN_SAR_FILEHEADER *fh;
1873 uint32_t pid;
1874
1875 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
1876 GWEN_GUI_PROGRESS_SHOW_ABORT |
1877 GWEN_GUI_PROGRESS_ALLOW_EMBED |
1878 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
1879 I18N("File Operation"),
1880 I18N("Unpacking archive file"),
1881 GWEN_SarFileHeader_List_GetCount(fhl),
1882 0);
1883
1884 fh=GWEN_SarFileHeader_List_First(fhl);
1885 while (fh) {
1886 //const char *s;
1887
1888 //s=GWEN_SarFileHeader_GetPath(fh);
1889 rv=GWEN_Sar_ExtractFile(sr, fh);
1890 if (rv<0) {
1891 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1892 GWEN_Gui_ProgressEnd(pid);
1893 GWEN_Sar_CloseArchive(sr, 1);
1894 GWEN_Sar_free(sr);
1895 }
1896
1897 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE);
1898 if (rv<0) {
1899 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1900 GWEN_Gui_ProgressEnd(pid);
1901 GWEN_Sar_CloseArchive(sr, 1);
1902 GWEN_Sar_free(sr);
1903 return rv;
1904 }
1905
1906 fh=GWEN_SarFileHeader_List_Next(fh);
1907 }
1908 GWEN_Gui_ProgressEnd(pid);
1909 }
1910
1911 rv=GWEN_Sar_CloseArchive(sr, 0);
1912 if (rv<0) {
1913 fprintf(stderr, "Error closing archive (%d)\n", rv);
1914 return 2;
1915 }
1916
1917 return 0;
1918 }
1919
1920
1921
GWEN_Sar_UnpackArchive(const char * inFile,const char * where)1922 int GWEN_Sar_UnpackArchive(const char *inFile, const char *where)
1923 {
1924 char savedPwd[300];
1925 int rv;
1926
1927 /* get current working dir */
1928 if (getcwd(savedPwd, sizeof(savedPwd)-1)==NULL) {
1929 DBG_ERROR(GWEN_LOGDOMAIN, "getcwd(): %s", strerror(errno));
1930 return GWEN_ERROR_IO;
1931 }
1932 savedPwd[sizeof(savedPwd)-1]=0;
1933
1934 rv=GWEN_Sar__UnpackArchive(inFile, where);
1935 if (rv<0) {
1936 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1937 }
1938
1939 /* change back to previous pwd */
1940 if (chdir(savedPwd)) {
1941 DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", savedPwd, strerror(errno));
1942 return GWEN_ERROR_IO;
1943 }
1944
1945 return rv;
1946 }
1947
1948
1949
GWEN_Sar_Sign(GWEN_SAR * sr,GWEN_CRYPTMGR * cm)1950 int GWEN_Sar_Sign(GWEN_SAR *sr, GWEN_CRYPTMGR *cm)
1951 {
1952 int rv;
1953 GWEN_SAR_FILEHEADER_LIST *fhl;
1954
1955 assert(sr);
1956 assert(sr->refCount);
1957
1958 if (sr->openMode!=GWEN_Sar_OpenMode_Opened &&
1959 sr->openMode!=GWEN_Sar_OpenMode_Created) {
1960 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open");
1961 return GWEN_ERROR_NOT_OPEN;
1962 }
1963
1964 if (sr->signaturePos!=0 || sr->signatureSize!=0) {
1965 DBG_ERROR(GWEN_LOGDOMAIN, "There already is a signature in the archive file");
1966 return GWEN_ERROR_INVALID;
1967 }
1968
1969 fhl=sr->headers;
1970 if (fhl) {
1971 GWEN_SAR_FILEHEADER *fh;
1972 uint32_t pid;
1973 GWEN_MDIGEST *md;
1974 uint8_t hashBuf[21];
1975 GWEN_BUFFER *sbuf;
1976 GWEN_BUFFER *tbuf;
1977 int64_t pos;
1978
1979 md=GWEN_MDigest_Rmd160_new();
1980 rv=GWEN_MDigest_Begin(md);
1981 if (rv<0) {
1982 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1983 GWEN_MDigest_free(md);
1984 return rv;
1985 }
1986
1987 /* clear SIGNED flags */
1988 fh=GWEN_SarFileHeader_List_First(fhl);
1989 while (fh) {
1990 GWEN_SarFileHeader_SubFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED);
1991 fh=GWEN_SarFileHeader_List_Next(fh);
1992 }
1993
1994 /* calculate hash over all file hashes */
1995 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
1996 GWEN_GUI_PROGRESS_SHOW_ABORT |
1997 GWEN_GUI_PROGRESS_ALLOW_EMBED |
1998 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
1999 I18N("File Operation"),
2000 I18N("Signing archive file"),
2001 GWEN_SarFileHeader_List_GetCount(fhl),
2002 0);
2003 fh=GWEN_SarFileHeader_List_First(fhl);
2004 while (fh) {
2005 const char *s;
2006 uint64_t hpos;
2007
2008 s=GWEN_SarFileHeader_GetPath(fh);
2009 hpos=GWEN_SarFileHeader_GetHashPos(fh);
2010 if (hpos==0) {
2011 DBG_WARN(GWEN_LOGDOMAIN, "File %s has no valid hash", s?s:"(unnamed)");
2012 }
2013 else {
2014 /* seek to start of hash */
2015 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set);
2016 if (pos<0) {
2017 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
2018 GWEN_Gui_ProgressEnd(pid);
2019 GWEN_MDigest_free(md);
2020 return (int) pos;
2021 }
2022
2023 /* read hash */
2024 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, hashBuf, 20);
2025 if (rv<0) {
2026 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2027 GWEN_Gui_ProgressEnd(pid);
2028 GWEN_MDigest_free(md);
2029 return rv;
2030 }
2031
2032 /* digest hash */
2033 rv=GWEN_MDigest_Update(md, hashBuf, 20);
2034 if (rv<0) {
2035 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2036 GWEN_Gui_ProgressEnd(pid);
2037 GWEN_MDigest_free(md);
2038 return rv;
2039 }
2040
2041
2042 GWEN_SarFileHeader_AddFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED);
2043 }
2044
2045 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE);
2046 if (rv<0) {
2047 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2048 GWEN_Gui_ProgressEnd(pid);
2049 GWEN_MDigest_free(md);
2050 return rv;
2051 }
2052
2053 fh=GWEN_SarFileHeader_List_Next(fh);
2054 }
2055
2056 /* finish hash */
2057 rv=GWEN_MDigest_End(md);
2058 if (rv<0) {
2059 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2060 GWEN_Gui_ProgressEnd(pid);
2061 GWEN_MDigest_free(md);
2062 return rv;
2063 }
2064
2065 /* sign hash */
2066 sbuf=GWEN_Buffer_new(0, 256, 0, 1);
2067 rv=GWEN_CryptMgr_Sign(cm,
2068 GWEN_MDigest_GetDigestPtr(md),
2069 GWEN_MDigest_GetDigestSize(md),
2070 sbuf);
2071 if (rv<0) {
2072 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2073 GWEN_Buffer_free(sbuf);
2074 GWEN_Gui_ProgressEnd(pid);
2075 GWEN_MDigest_free(md);
2076 return rv;
2077 }
2078 GWEN_MDigest_free(md);
2079
2080 /* create signature TLV */
2081 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
2082 rv=GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_SIGNATURE, 0x00,
2083 GWEN_Buffer_GetStart(sbuf),
2084 GWEN_Buffer_GetUsedBytes(sbuf),
2085 1, tbuf);
2086 if (rv<0) {
2087 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2088 GWEN_Buffer_free(tbuf);
2089 GWEN_Buffer_free(sbuf);
2090 GWEN_Gui_ProgressEnd(pid);
2091 return rv;
2092 }
2093
2094 /* seek to end of file */
2095 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, 0, GWEN_SyncIo_File_Whence_End);
2096 if (pos<0) {
2097 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
2098 GWEN_Buffer_free(tbuf);
2099 GWEN_Buffer_free(sbuf);
2100 GWEN_Gui_ProgressEnd(pid);
2101 return (int) pos;
2102 }
2103
2104 /* write TLV into archive file */
2105 rv=GWEN_SyncIo_WriteForced(sr->archiveSio,
2106 (const uint8_t *) GWEN_Buffer_GetStart(tbuf),
2107 GWEN_Buffer_GetUsedBytes(tbuf));
2108 if (rv<0) {
2109 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2110 GWEN_Buffer_free(tbuf);
2111 GWEN_Buffer_free(sbuf);
2112 GWEN_Gui_ProgressEnd(pid);
2113 return rv;
2114 }
2115
2116
2117 GWEN_Buffer_free(tbuf);
2118 GWEN_Buffer_free(sbuf);
2119
2120 GWEN_Gui_ProgressEnd(pid);
2121 }
2122
2123 return 0;
2124 }
2125
2126
2127
GWEN_Sar_Verify(GWEN_SAR * sr,GWEN_CRYPTMGR * cm)2128 int GWEN_Sar_Verify(GWEN_SAR *sr, GWEN_CRYPTMGR *cm)
2129 {
2130 int rv;
2131 GWEN_SAR_FILEHEADER_LIST *fhl;
2132
2133 assert(sr);
2134 assert(sr->refCount);
2135
2136 if (sr->openMode!=GWEN_Sar_OpenMode_Opened &&
2137 sr->openMode!=GWEN_Sar_OpenMode_Created) {
2138 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open");
2139 return GWEN_ERROR_NOT_OPEN;
2140 }
2141
2142 if (sr->signaturePos==0 || sr->signatureSize==0) {
2143 DBG_ERROR(GWEN_LOGDOMAIN, "No valid signature data in the archive file");
2144 return GWEN_ERROR_INVALID;
2145 }
2146
2147 fhl=sr->headers;
2148 if (fhl) {
2149 GWEN_SAR_FILEHEADER *fh;
2150 uint32_t pid;
2151 GWEN_MDIGEST *md;
2152 uint8_t hashBuf[21];
2153 GWEN_BUFFER *sbuf;
2154 GWEN_BUFFER *hbuf;
2155 int64_t pos;
2156
2157 md=GWEN_MDigest_Rmd160_new();
2158 rv=GWEN_MDigest_Begin(md);
2159 if (rv<0) {
2160 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2161 GWEN_MDigest_free(md);
2162 return rv;
2163 }
2164
2165 /* clear SIGNED flags */
2166 fh=GWEN_SarFileHeader_List_First(fhl);
2167 while (fh) {
2168 GWEN_SarFileHeader_SubFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED);
2169 fh=GWEN_SarFileHeader_List_Next(fh);
2170 }
2171
2172 /* calculate hash over all file hashes */
2173 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
2174 GWEN_GUI_PROGRESS_SHOW_ABORT |
2175 GWEN_GUI_PROGRESS_ALLOW_EMBED |
2176 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
2177 I18N("File Operation"),
2178 I18N("Signing archive file"),
2179 GWEN_SarFileHeader_List_GetCount(fhl),
2180 0);
2181 fh=GWEN_SarFileHeader_List_First(fhl);
2182 while (fh) {
2183 const char *s;
2184 uint64_t hpos;
2185
2186 s=GWEN_SarFileHeader_GetPath(fh);
2187 hpos=GWEN_SarFileHeader_GetHashPos(fh);
2188 if (hpos==0) {
2189 DBG_WARN(GWEN_LOGDOMAIN, "File %s has no valid hash", s?s:"(unnamed)");
2190 }
2191 else {
2192 /* seek to start of hash */
2193 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set);
2194 if (pos<0) {
2195 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
2196 GWEN_Gui_ProgressEnd(pid);
2197 GWEN_MDigest_free(md);
2198 return (int) pos;
2199 }
2200
2201 /* read hash */
2202 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, hashBuf, 20);
2203 if (rv<0) {
2204 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2205 GWEN_Gui_ProgressEnd(pid);
2206 GWEN_MDigest_free(md);
2207 return rv;
2208 }
2209
2210 /* digest hash */
2211 rv=GWEN_MDigest_Update(md, hashBuf, 20);
2212 if (rv<0) {
2213 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2214 GWEN_Gui_ProgressEnd(pid);
2215 GWEN_MDigest_free(md);
2216 return rv;
2217 }
2218
2219
2220 GWEN_SarFileHeader_AddFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED);
2221 }
2222
2223 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE);
2224 if (rv<0) {
2225 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2226 GWEN_Gui_ProgressEnd(pid);
2227 GWEN_MDigest_free(md);
2228 return rv;
2229 }
2230
2231 fh=GWEN_SarFileHeader_List_Next(fh);
2232 }
2233
2234 /* finish hash */
2235 rv=GWEN_MDigest_End(md);
2236 if (rv<0) {
2237 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2238 GWEN_Gui_ProgressEnd(pid);
2239 GWEN_MDigest_free(md);
2240 return rv;
2241 }
2242
2243 /* seek to start of signature data */
2244 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, sr->signaturePos, GWEN_SyncIo_File_Whence_Set);
2245 if (pos<0) {
2246 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos);
2247 GWEN_Gui_ProgressEnd(pid);
2248 GWEN_MDigest_free(md);
2249 return (int) pos;
2250 }
2251
2252 /* read signature data */
2253 sbuf=GWEN_Buffer_new(0, sr->signatureSize, 0, 1);
2254 rv=GWEN_SyncIo_ReadForced(sr->archiveSio,
2255 (uint8_t *) GWEN_Buffer_GetStart(sbuf),
2256 sr->signatureSize);
2257 if (rv<0) {
2258 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2259 GWEN_Buffer_free(sbuf);
2260 GWEN_Gui_ProgressEnd(pid);
2261 GWEN_MDigest_free(md);
2262 return rv;
2263 }
2264 GWEN_Buffer_IncrementPos(sbuf, sr->signatureSize);
2265 GWEN_Buffer_AdjustUsedBytes(sbuf);
2266
2267 /* verify signature */
2268 hbuf=GWEN_Buffer_new(0, 256, 0, 1);
2269 rv=GWEN_CryptMgr_Verify(cm,
2270 (const uint8_t *) GWEN_Buffer_GetStart(sbuf),
2271 GWEN_Buffer_GetUsedBytes(sbuf),
2272 hbuf);
2273 if (rv<0) {
2274 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2275 GWEN_Buffer_free(hbuf);
2276 GWEN_Buffer_free(sbuf);
2277 GWEN_Gui_ProgressEnd(pid);
2278 GWEN_MDigest_free(md);
2279 return rv;
2280 }
2281 GWEN_Buffer_free(sbuf);
2282
2283 /* verify hash */
2284 if (GWEN_Buffer_GetUsedBytes(hbuf)!=20) {
2285 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid size of signed hash (%d)", GWEN_Buffer_GetUsedBytes(hbuf));
2286 GWEN_Buffer_free(hbuf);
2287 GWEN_Gui_ProgressEnd(pid);
2288 GWEN_MDigest_free(md);
2289 return GWEN_ERROR_BAD_DATA;
2290 }
2291 if (memcmp(GWEN_Buffer_GetStart(hbuf), GWEN_MDigest_GetDigestPtr(md), 20)!=0) {
2292 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid hash, data is invalid!");
2293 GWEN_Buffer_free(hbuf);
2294 GWEN_Gui_ProgressEnd(pid);
2295 GWEN_MDigest_free(md);
2296 return GWEN_ERROR_VERIFY;
2297 }
2298 DBG_INFO(GWEN_LOGDOMAIN, "Signature is valid");
2299
2300 GWEN_MDigest_free(md);
2301 GWEN_Buffer_free(hbuf);
2302
2303 GWEN_Gui_ProgressEnd(pid);
2304 }
2305
2306 return 0;
2307 }
2308
2309
2310
GWEN_Sar_VerifyArchive(const char * inFile,const char * signer,GWEN_CRYPT_KEY * key)2311 int GWEN_Sar_VerifyArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key)
2312 {
2313 GWEN_SAR *sr;
2314 int rv;
2315
2316 /* open archive file */
2317 sr=GWEN_Sar_new();
2318 rv=GWEN_Sar_OpenArchive(sr, inFile,
2319 GWEN_SyncIo_File_CreationMode_OpenExisting,
2320 GWEN_SYNCIO_FILE_FLAGS_READ);
2321 if (rv<0) {
2322 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2323 GWEN_Sar_free(sr);
2324 return rv;
2325 }
2326 else {
2327 GWEN_CRYPTMGR *cm;
2328
2329 cm=GWEN_CryptMgrKeys_new(NULL, NULL, signer, key, 0);
2330
2331 /* verify */
2332 rv=GWEN_Sar_Verify(sr, cm);
2333 if (rv<0) {
2334 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2335 GWEN_CryptMgr_free(cm);
2336 GWEN_Sar_CloseArchive(sr, 1);
2337 GWEN_Sar_free(sr);
2338 return rv;
2339 }
2340 GWEN_CryptMgr_free(cm);
2341
2342 /* close archive */
2343 rv=GWEN_Sar_CloseArchive(sr, 0);
2344 if (rv<0) {
2345 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2346 GWEN_Sar_CloseArchive(sr, 1);
2347 GWEN_Sar_free(sr);
2348 return rv;
2349 }
2350 GWEN_Sar_free(sr);
2351 return 0;
2352 }
2353 }
2354
2355
2356
GWEN_Sar_SignArchive(const char * inFile,const char * signer,GWEN_CRYPT_KEY * key)2357 int GWEN_Sar_SignArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key)
2358 {
2359 GWEN_SAR *sr;
2360 int rv;
2361
2362 /* open archive file */
2363 sr=GWEN_Sar_new();
2364 rv=GWEN_Sar_OpenArchive(sr, inFile,
2365 GWEN_SyncIo_File_CreationMode_OpenExisting,
2366 GWEN_SYNCIO_FILE_FLAGS_READ);
2367 if (rv<0) {
2368 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2369 GWEN_Sar_free(sr);
2370 return rv;
2371 }
2372 else {
2373 GWEN_CRYPTMGR *cm;
2374
2375 cm=GWEN_CryptMgrKeys_new(NULL, NULL, signer, key, 0);
2376
2377 /* verify */
2378 rv=GWEN_Sar_Sign(sr, cm);
2379 if (rv<0) {
2380 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2381 GWEN_CryptMgr_free(cm);
2382 GWEN_Sar_CloseArchive(sr, 1);
2383 GWEN_Sar_free(sr);
2384 return rv;
2385 }
2386 GWEN_CryptMgr_free(cm);
2387
2388 /* close archive */
2389 rv=GWEN_Sar_CloseArchive(sr, 0);
2390 if (rv<0) {
2391 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2392 GWEN_Sar_CloseArchive(sr, 1);
2393 GWEN_Sar_free(sr);
2394 return rv;
2395 }
2396 GWEN_Sar_free(sr);
2397 return 0;
2398 }
2399 }
2400
2401
2402
GWEN_Sar_CheckArchive(const char * inFile)2403 int GWEN_Sar_CheckArchive(const char *inFile)
2404 {
2405 GWEN_SAR *sr;
2406 int rv;
2407 const GWEN_SAR_FILEHEADER_LIST *fhl;
2408
2409 /* open archive file */
2410 sr=GWEN_Sar_new();
2411 rv=GWEN_Sar_OpenArchive(sr, inFile,
2412 GWEN_SyncIo_File_CreationMode_OpenExisting,
2413 GWEN_SYNCIO_FILE_FLAGS_READ);
2414 if (rv<0) {
2415 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2416 return rv;
2417 }
2418
2419 fhl=GWEN_Sar_GetHeaders(sr);
2420 if (fhl) {
2421 const GWEN_SAR_FILEHEADER *fh;
2422 uint32_t pid;
2423
2424 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
2425 GWEN_GUI_PROGRESS_SHOW_ABORT |
2426 GWEN_GUI_PROGRESS_ALLOW_EMBED |
2427 GWEN_GUI_PROGRESS_SHOW_PROGRESS,
2428 I18N("File Operation"),
2429 I18N("Checking archive file"),
2430 GWEN_SarFileHeader_List_GetCount(fhl),
2431 0);
2432
2433 fh=GWEN_SarFileHeader_List_First(fhl);
2434 while (fh) {
2435 //const char *s;
2436
2437 //s=GWEN_SarFileHeader_GetPath(fh);
2438 rv=GWEN_Sar_CheckFile(sr, fh);
2439 if (rv<0) {
2440 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2441 GWEN_Gui_ProgressEnd(pid);
2442 GWEN_Sar_CloseArchive(sr, 1);
2443 GWEN_Sar_free(sr);
2444 }
2445
2446 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE);
2447 if (rv<0) {
2448 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
2449 GWEN_Gui_ProgressEnd(pid);
2450 GWEN_Sar_CloseArchive(sr, 1);
2451 GWEN_Sar_free(sr);
2452 return rv;
2453 }
2454
2455 fh=GWEN_SarFileHeader_List_Next(fh);
2456 }
2457 GWEN_Gui_ProgressEnd(pid);
2458 }
2459
2460 rv=GWEN_Sar_CloseArchive(sr, 0);
2461 if (rv<0) {
2462 fprintf(stderr, "Error closing archive (%d)\n", rv);
2463 return 2;
2464 }
2465 GWEN_Sar_free(sr);
2466
2467 return 0;
2468 }
2469
2470
2471
2472