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