gwenhywfar  5.10.1
sar.c
Go to the documentation of this file.
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 
51 {
52  GWEN_SAR *sr;
53 
55  sr->refCount=1;
56 
57  sr->headers=GWEN_SarFileHeader_List_new();
58 
59  return sr;
60 }
61 
62 
63 
65 {
66  assert(sr);
67  assert(sr->refCount);
68  sr->refCount++;
69 }
70 
71 
72 
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 
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);
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 
134 int GWEN_Sar_OpenArchive(GWEN_SAR *sr, const char *aname,
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 
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 
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 */
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 */
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 */
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 */
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),
291  1,
292  tbuf);
293  GWEN_Buffer_free(xbuf);
294  }
295 
296  /* mtime */
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),
307  1,
308  tbuf);
309  GWEN_Buffer_free(xbuf);
310  }
311 
312  /* ctime */
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),
323  1,
324  tbuf);
325  GWEN_Buffer_free(xbuf);
326  }
327 
328  /* file size */
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 
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 
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");
460  break;
461 
462  case GWEN_SAR_TAG_HEADER_MTIME:
463  ti=GWEN_Time_fromUtcString((const char *) p, "YYYYMMDDhhmmss");
465  break;
466 
467  case GWEN_SAR_TAG_HEADER_CTIME:
468  ti=GWEN_Time_fromUtcString((const char *) p, "YYYYMMDDhhmmss");
470  break;
471 
472  case GWEN_SAR_TAG_HEADER_SIZE:
473  v=GWEN_Sar_ReadUint64(p, bs);
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 
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);
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),
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 */
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 
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);
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);
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);
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);
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);
609  GWEN_SyncIo_free(sio);
610  return rv;
611  }
612 
613  } /* while */
615 
616  /* close input file */
618  GWEN_SyncIo_free(sio);
619  }
620 
621  return 0;
622 }
623 
624 
625 
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),
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 
688 {
689  int rv;
690 
691  switch (GWEN_SarFileHeader_GetFileType(fh)) {
693  rv=GWEN_Sar_AddAndDigestFileReg(sr, fh, md);
694  break;
696  rv=0;
697  break;
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 
716 int GWEN_Sar_AddFile(GWEN_SAR *sr, const char *fname)
717 {
718  struct stat st;
719  int rv;
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 */
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:
753  break;
754 #endif
755  case S_IFREG:
757  break;
758  case S_IFDIR:
760  break;
761  default:
763  return GWEN_ERROR_INVALID;
764  }
765 
766  /* permissions */
767  if (st.st_mode & S_IRUSR)
769  if (st.st_mode & S_IWUSR)
771  if (st.st_mode & S_IXUSR)
773 
774 #ifdef S_IRGRP
775  if (st.st_mode & S_IRGRP)
777 #endif
778 #ifdef S_IWGRP
779  if (st.st_mode & S_IWGRP)
781 #endif
782 #ifdef S_IXGRP
783  if (st.st_mode & S_IXGRP)
785 #endif
786 
787 #ifdef S_IROTH
788  if (st.st_mode & S_IROTH)
790 #endif
791 #ifdef S_IWOTH
792  if (st.st_mode & S_IWOTH)
794 #endif
795 #ifdef S_IXOTH
796  if (st.st_mode & S_IXOTH)
798 #endif
799 
800  /* atime */
801  ti=GWEN_Time_fromSeconds(st.st_atime);
803 
804  /* mtime */
805  ti=GWEN_Time_fromSeconds(st.st_mtime);
807 
808  /* ctime */
809  ti=GWEN_Time_fromSeconds(st.st_ctime);
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);
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);
836  return rv;
837  }
838 
839  /* insert TLV header into file header buffer */
840  GWEN_Buffer_SetPos(hbuf, 0);
842  GWEN_Buffer_GetStart(xbuf),
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);
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),
860  if (rv<0) {
861  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
862  GWEN_Buffer_free(hbuf);
864  return rv;
865  }
866 
867  /* prepare digest */
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);
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);
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);
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);
907  return rv;
908  }
909 
910  /* create hash TLV */
911  GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HASH, 0x00,
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),
921  if (rv<0) {
922  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
923  GWEN_Buffer_free(hbuf);
925  return rv;
926  }
927 
928  /* done */
929  GWEN_Buffer_free(hbuf);
931  return 0;
932 }
933 
934 
935 
936 
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);
1019  GWEN_Buffer_Rewind(mbuf);
1020 
1021  /* now parse header */
1023  rv=GWEN_Sar_TlvToFileHeader(mbuf, fh);
1024  if (rv<0) {
1025  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
1027  GWEN_Buffer_free(mbuf);
1028  return rv;
1029  }
1030 
1031  GWEN_SarFileHeader_SetHeaderStartPos(fh, startOfTagHeader);
1032  GWEN_SarFileHeader_SetHeaderSize(fh, fullTagSize);
1033 
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  }
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 
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 
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);
1150 
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);
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) {
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) {
1214  GWEN_SyncIo_free(sio);
1215  }
1216  GWEN_MDigest_free(md);
1217  return (int) pos;
1218  }
1219 
1220  /* start extracting */
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) {
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) {
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) {
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) {
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) {
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 */
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 */
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);
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,
1360 
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 
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 
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);
1406  assert(fname);
1407  fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */
1409 
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);
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);
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 */
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);
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 
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 
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);
1632  //fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */
1633  //dpos=GWEN_SarFileHeader_GetDataPos(fh);
1634 
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);
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 */
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);
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 
1779 {
1780  int rv;
1781 
1782  switch (GWEN_SarFileHeader_GetFileType(fh)) {
1784  rv=GWEN_Sar_ExtractAndDigestFileReg(sr, fh, checkOnly);
1785  break;
1787  rv=GWEN_Sar_ExtractAndDigestFileDir(sr, fh, checkOnly);
1788  break;
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 
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 
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 
1838 {
1839  assert(sr);
1840  assert(sr->refCount);
1841  return sr->headers;
1842 }
1843 
1844 
1845 
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,
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 
1879  I18N("File Operation"),
1880  I18N("Unpacking archive file"),
1882  0);
1883 
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 
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 
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 
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 
1951 {
1952  int rv;
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 
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 */
1989  while (fh) {
1992  }
1993 
1994  /* calculate hash over all file hashes */
1999  I18N("File Operation"),
2000  I18N("Signing archive file"),
2002  0);
2004  while (fh) {
2005  const char *s;
2006  uint64_t hpos;
2007 
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 
2043  }
2044 
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 
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,
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),
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 
2129 {
2130  int rv;
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 
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 */
2167  while (fh) {
2170  }
2171 
2172  /* calculate hash over all file hashes */
2177  I18N("File Operation"),
2178  I18N("Signing archive file"),
2180  0);
2182  while (fh) {
2183  const char *s;
2184  uint64_t hpos;
2185 
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 
2221  }
2222 
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 
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);
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),
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 
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,
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 
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,
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 
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,
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 
2428  I18N("File Operation"),
2429  I18N("Checking archive file"),
2431  0);
2432 
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 
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 
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 
struct GWEN_TLV GWEN_TLV
Definition: tlv.h:19
const GWEN_TIME * GWEN_SarFileHeader_GetAtime(const GWEN_SAR_FILEHEADER *p_struct)
int GWEN_SyncIo_WriteForced(GWEN_SYNCIO *sio, const uint8_t *buffer, uint32_t size)
Definition: syncio.c:317
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition: buffer.c:537
int GWEN_Sar_Sign(GWEN_SAR *sr, GWEN_CRYPTMGR *cm)
Definition: sar.c:1950
int GWEN_SarFileHeader_GetFileType(const GWEN_SAR_FILEHEADER *p_struct)
GWENHYWFAR_API int64_t GWEN_SyncIo_File_Seek(GWEN_SYNCIO *sio, int64_t pos, GWEN_SYNCIO_FILE_WHENCE whence)
struct GWEN_TIME GWEN_TIME
Definition: gwentime.h:43
int GWEN_Sar_ExtractAndDigestFileDir(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
Definition: sar.c:1604
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
#define I18N(m)
Definition: error.c:42
int GWEN_SyncIo_Connect(GWEN_SYNCIO *sio)
Definition: syncio.c:97
#define GWEN_SAR_FILEHEADER_FLAGS_SIGNED
GWENHYWFAR_API int GWEN_Gui_ProgressAdvance(uint32_t id, uint32_t progress)
Definition: gui_virtual.c:420
int GWEN_Sar_ScanFile(GWEN_SAR *sr)
Definition: sar.c:937
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition: mdigest.c:54
void GWEN_SarFileHeader_SetHeaderSize(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
int GWEN_CryptMgr_Sign(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
Definition: cryptmgr.c:298
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:285
#define GWEN_ERROR_INVALID
Definition: error.h:67
int GWEN_Sar_FileHeaderToTlv(const GWEN_SAR_FILEHEADER *fh, GWEN_BUFFER *tbuf)
Definition: sar.c:231
#define GWEN_SYNCIO_FILE_FLAGS_WRITE
Definition: syncio_file.h:54
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
#define GWEN_GUI_PROGRESS_ALLOW_EMBED
Definition: gui.h:196
#define GWEN_SYNCIO_FILE_FLAGS_READ
Definition: syncio_file.h:53
void GWEN_TLV_free(GWEN_TLV *tlv)
Definition: tlv.c:47
#define GWEN_SYNCIO_FILE_FLAGS_GEXEC
Definition: syncio_file.h:64
GWEN_SAR * GWEN_Sar_new(void)
Definition: sar.c:50
int GWEN_SyncIo_Read(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:133
void GWEN_SarFileHeader_free(GWEN_SAR_FILEHEADER *p_struct)
int GWEN_Sar_AddFile(GWEN_SAR *sr, const char *fname)
Definition: sar.c:716
void GWEN_SarFileHeader_SetMtime(GWEN_SAR_FILEHEADER *p_struct, GWEN_TIME *p_src)
void GWEN_SarFileHeader_SetAtime(GWEN_SAR_FILEHEADER *p_struct, GWEN_TIME *p_src)
int GWEN_Sar_CloseArchive(GWEN_SAR *sr, int abandon)
Definition: sar.c:181
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
int GWEN_Sar_UnpackArchive(const char *inFile, const char *where)
Definition: sar.c:1922
#define GWEN_SYNCIO_FILE_FLAGS_UREAD
Definition: syncio_file.h:58
#define DBG_VERBOUS(dbg_logger, format, args...)
Definition: debug.h:224
const GWEN_SAR_FILEHEADER_LIST * GWEN_Sar_GetHeaders(GWEN_SAR *sr)
Definition: sar.c:1837
#define GWEN_GUI_PROGRESS_DELAY
Definition: gui.h:192
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:469
#define DBG_WARN(dbg_logger, format, args...)
Definition: debug.h:125
void GWEN_SarFileHeader_SetStatus(GWEN_SAR_FILEHEADER *p_struct, int p_src)
GWEN_SAR_FILEHEADER * GWEN_SarFileHeader_List_Next(const GWEN_SAR_FILEHEADER *element)
int GWEN_Sar_ExtractAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
Definition: sar.c:1379
int GWEN_TLV_ReadHeader(GWEN_TLV *tlv, const uint8_t *p, uint32_t size, int isBerTlv)
Definition: tlv.c:356
#define GWEN_LOGDOMAIN
Definition: logger.h:35
int GWEN_MDigest_Update(GWEN_MDIGEST *md, const uint8_t *buf, unsigned int l)
Definition: mdigest.c:153
uint64_t GWEN_SarFileHeader_GetHeaderStartPos(const GWEN_SAR_FILEHEADER *p_struct)
int GWEN_Buffer_ReserveBytes(GWEN_BUFFER *bf, uint32_t res)
Definition: buffer.c:157
void GWEN_Sar_Attach(GWEN_SAR *sr)
Definition: sar.c:64
int GWEN_Sar_ExtractFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh)
Definition: sar.c:1807
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWEN_SarFileHeader_GetStatus(const GWEN_SAR_FILEHEADER *p_struct)
void GWEN_SarFileHeader_SubFlags(GWEN_SAR_FILEHEADER *p_struct, uint32_t p_src)
int GWEN_TLV_DirectlyToBuffer(unsigned int tagType, unsigned int tagMode, const void *tagData, int tagLength, int isBerTlv, GWEN_BUFFER *mbuf)
Definition: tlv.c:294
GWEN_SYNCIO_FILE_CREATIONMODE
Definition: syncio_file.h:36
uint64_t GWEN_SarFileHeader_GetFileSize(const GWEN_SAR_FILEHEADER *p_struct)
#define GWEN_ERROR_IO
Definition: error.h:123
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
const GWEN_TIME * GWEN_SarFileHeader_GetCtime(const GWEN_SAR_FILEHEADER *p_struct)
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:452
#define GWEN_SYNCIO_FILE_FLAGS_GREAD
Definition: syncio_file.h:62
void GWEN_SarFileHeader_SetCtime(GWEN_SAR_FILEHEADER *p_struct, GWEN_TIME *p_src)
uint8_t * GWEN_MDigest_GetDigestPtr(GWEN_MDIGEST *md)
Definition: mdigest.c:81
unsigned int GWEN_TLV_GetTagType(const GWEN_TLV *tlv)
Definition: tlv.c:110
#define GWEN_ERROR_BAD_DATA
Definition: error.h:121
int GWEN_MDigest_Begin(GWEN_MDIGEST *md)
Definition: mdigest.c:129
int GWEN_Sar_AddAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
Definition: sar.c:626
#define GWEN_GUI_PROGRESS_ONE
Definition: gui.h:376
#define GWEN_SYNCIO_FILE_FLAGS_OEXEC
Definition: syncio_file.h:68
const GWEN_TIME * GWEN_SarFileHeader_GetMtime(const GWEN_SAR_FILEHEADER *p_struct)
uint32_t GWEN_SarFileHeader_GetPermissions(const GWEN_SAR_FILEHEADER *p_struct)
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_SarFileHeader_SetDataPos(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
struct GWEN_SYNCIO GWEN_SYNCIO
Definition: syncio.h:40
void GWEN_SarFileHeader_List_Add(GWEN_SAR_FILEHEADER *element, GWEN_SAR_FILEHEADER_LIST *list)
GWENHYWFAR_API int GWEN_Time_toUtcString(const GWEN_TIME *t, const char *tmpl, GWEN_BUFFER *buf)
Definition: gwentime_all.c:838
void GWEN_SarFileHeader_SetFileType(GWEN_SAR_FILEHEADER *p_struct, int p_src)
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition: mdigestgc.c:158
uint64_t GWEN_Sar_ReadUint64(const uint8_t *p, uint32_t bs)
Definition: sar.c:345
GWEN_SAR_FILEHEADER * GWEN_SarFileHeader_List_First(const GWEN_SAR_FILEHEADER_LIST *l)
#define DBG_DEBUG(dbg_logger, format, args...)
Definition: debug.h:214
void GWEN_SarFileHeader_SetHashPos(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
int GWEN_Sar_VerifyArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key)
Definition: sar.c:2311
int GWEN_Sar_CheckFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh)
Definition: sar.c:1822
int GWEN_SyncIo_ReadForced(GWEN_SYNCIO *sio, uint8_t *buffer, uint32_t size)
Definition: syncio.c:360
int GWEN_Sar_Verify(GWEN_SAR *sr, GWEN_CRYPTMGR *cm)
Definition: sar.c:2128
struct GWEN_MDIGEST GWEN_MDIGEST
Definition: mdigest.h:25
#define GWEN_SYNCIO_FILE_FLAGS_GWRITE
Definition: syncio_file.h:63
void GWEN_Text_LogString(const char *s, unsigned int l, const char *logDomain, GWEN_LOGGER_LEVEL lv)
Definition: text.c:1606
uint64_t GWEN_SarFileHeader_GetDataSize(const GWEN_SAR_FILEHEADER *p_struct)
void GWEN_SarFileHeader_SetPermissions(GWEN_SAR_FILEHEADER *p_struct, uint32_t p_src)
GWEN_TLV * GWEN_TLV_new(void)
Definition: tlv.c:35
void GWEN_Sar_free(GWEN_SAR *sr)
Definition: sar.c:73
struct GWEN_CRYPT_KEY GWEN_CRYPT_KEY
Definition: cryptkey.h:26
#define GWEN_SYNCIO_FILE_FLAGS_UWRITE
Definition: syncio_file.h:59
#define GWEN_ERROR_OPEN
Definition: error.h:66
struct GWEN_SAR_FILEHEADER GWEN_SAR_FILEHEADER
void GWEN_SarFileHeader_List_free(GWEN_SAR_FILEHEADER_LIST *l)
const void * GWEN_TLV_GetTagData(const GWEN_TLV *tlv)
Definition: tlv.c:134
void GWEN_SarFileHeader_SetHeaderStartPos(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
unsigned int GWEN_TLV_GetTagSize(const GWEN_TLV *tlv)
Definition: tlv.c:126
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
void GWEN_SyncIo_free(GWEN_SYNCIO *sio)
Definition: syncio.c:78
GWEN_SAR_FILEHEADER * GWEN_SarFileHeader_new(void)
uint64_t GWEN_SarFileHeader_GetDataPos(const GWEN_SAR_FILEHEADER *p_struct)
GWEN_CRYPTMGR * GWEN_CryptMgrKeys_new(const char *localName, GWEN_CRYPT_KEY *localKey, const char *peerName, GWEN_CRYPT_KEY *peerKey, int ownKeys)
Definition: cryptmgrkeys.c:33
void GWEN_SyncIo_AddFlags(GWEN_SYNCIO *sio, uint32_t fl)
Definition: syncio.c:179
void GWEN_CryptMgr_free(GWEN_CRYPTMGR *cm)
Definition: cryptmgr.c:49
GWENHYWFAR_API uint32_t GWEN_Gui_ProgressStart(uint32_t progressFlags, const char *title, const char *text, uint64_t total, uint32_t guiid)
Definition: gui_virtual.c:404
GWENHYWFAR_API int GWEN_Gui_ProgressEnd(uint32_t id)
Definition: gui_virtual.c:480
void GWEN_SarFileHeader_SetFileSize(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
#define GWEN_ERROR_NOT_OPEN
Definition: error.h:70
int GWEN_MDigest_End(GWEN_MDIGEST *md)
Definition: mdigest.c:141
int GWEN_TLV_WriteHeader(unsigned int tagType, unsigned int tagMode, uint64_t tagLength, int isBerTlv, GWEN_BUFFER *mbuf)
Definition: tlv.c:494
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWENHYWFAR_API GWEN_TIME * GWEN_Time_fromUtcString(const char *s, const char *tmpl)
Definition: gwentime_all.c:352
#define GWEN_ERROR_EOF
Definition: error.h:96
int GWEN_Sar_OpenArchive(GWEN_SAR *sr, const char *aname, GWEN_SYNCIO_FILE_CREATIONMODE cm, uint32_t acc)
Definition: sar.c:134
unsigned int GWEN_MDigest_GetDigestSize(GWEN_MDIGEST *md)
Definition: mdigest.c:90
void GWEN_SarFileHeader_AddPermissions(GWEN_SAR_FILEHEADER *p_struct, uint32_t p_src)
int GWEN_Buffer_SetPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:261
const char * GWEN_SarFileHeader_GetPath(const GWEN_SAR_FILEHEADER *p_struct)
int GWEN_SyncIo_Disconnect(GWEN_SYNCIO *sio)
Definition: syncio.c:109
int GWEN_Sar_ExtractAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
Definition: sar.c:1120
#define GWEN_GUI_PROGRESS_SHOW_PROGRESS
Definition: gui.h:197
GWEN_SAR_FILEHEADER_LIST * GWEN_SarFileHeader_List_new()
unsigned int GWEN_TLV_GetTagLength(const GWEN_TLV *tlv)
Definition: tlv.c:118
#define GWEN_SYNCIO_FILE_FLAGS_OWRITE
Definition: syncio_file.h:67
int GWEN_Sar_AddAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
Definition: sar.c:687
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
uint32_t GWEN_SarFileHeader_GetFlags(const GWEN_SAR_FILEHEADER *p_struct)
int GWEN_Sar_CreateArchive(GWEN_SAR *sr, const char *aname)
Definition: sar.c:92
int GWEN_Sar__UnpackArchive(const char *inFile, const char *where)
Definition: sar.c:1846
int GWEN_Sar_ExtractAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly)
Definition: sar.c:1778
GWEN_TLV * GWEN_TLV_fromBuffer(GWEN_BUFFER *mbuf, int isBerTlv)
Definition: tlv.c:142
int GWEN_Sar_AddAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md)
Definition: sar.c:492
#define GWEN_ERROR_VERIFY
Definition: error.h:104
uint64_t GWEN_SarFileHeader_GetHeaderSize(const GWEN_SAR_FILEHEADER *p_struct)
GWENHYWFAR_API GWEN_SYNCIO * GWEN_SyncIo_File_new(const char *path, GWEN_SYNCIO_FILE_CREATIONMODE cm)
int GWEN_Sar_CheckArchive(const char *inFile)
Definition: sar.c:2403
void GWEN_Buffer_Rewind(GWEN_BUFFER *bf)
Definition: buffer.c:660
void GWEN_SarFileHeader_SetDataSize(GWEN_SAR_FILEHEADER *p_struct, uint64_t p_src)
struct GWEN_CRYPTMGR GWEN_CRYPTMGR
Definition: cryptmgr.h:64
int GWEN_CryptMgr_Verify(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf)
Definition: cryptmgr.c:482
int GWEN_Buffer_InsertBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition: buffer.c:883
uint64_t GWEN_SarFileHeader_GetHashPos(const GWEN_SAR_FILEHEADER *p_struct)
#define GWEN_SYNCIO_FILE_FLAGS_OREAD
Definition: syncio_file.h:66
#define GWEN_SYNCIO_FILE_FLAGS_UEXEC
Definition: syncio_file.h:60
GWENHYWFAR_API GWEN_TIME * GWEN_Time_fromSeconds(uint32_t s)
Definition: gwentime_all.c:77
void GWEN_SarFileHeader_SetPath(GWEN_SAR_FILEHEADER *p_struct, const char *p_src)
void GWEN_SarFileHeader_SetFlags(GWEN_SAR_FILEHEADER *p_struct, uint32_t p_src)
void GWEN_SarFileHeader_AddFlags(GWEN_SAR_FILEHEADER *p_struct, uint32_t p_src)
int GWEN_Sar_SignArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key)
Definition: sar.c:2357
struct GWEN_SAR GWEN_SAR
Definition: sar.h:37
int GWEN_SyncIo_Flush(GWEN_SYNCIO *sio)
Definition: syncio.c:121
uint32_t GWEN_SarFileHeader_List_GetCount(const GWEN_SAR_FILEHEADER_LIST *l)
#define GWEN_GUI_PROGRESS_SHOW_ABORT
Definition: gui.h:194
int GWEN_Sar_TlvToFileHeader(GWEN_BUFFER *mbuf, GWEN_SAR_FILEHEADER *fh)
Definition: sar.c:413