gwenhywfar
4.3.1
|
00001 /*************************************************************************** 00002 begin : Wed Jun 22 2011 00003 copyright : (C) 2011 by Martin Preuss 00004 email : martin@libchipcard.de 00005 00006 *************************************************************************** 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 00021 * MA 02111-1307 USA * 00022 * * 00023 ***************************************************************************/ 00024 00025 #ifdef HAVE_CONFIG_H 00026 # include <config.h> 00027 #endif 00028 00029 00030 #include "sar_p.h" 00031 #include "gwen_sar_fileheader_l.h" 00032 #include "i18n_l.h" 00033 00034 #include <gwenhywfar/misc.h> 00035 #include <gwenhywfar/debug.h> 00036 #include <gwenhywfar/tlv.h> 00037 #include <gwenhywfar/gui.h> 00038 #include <gwenhywfar/text.h> 00039 #include <gwenhywfar/cryptmgrkeys.h> 00040 00041 #include <sys/types.h> 00042 #include <sys/stat.h> 00043 #include <unistd.h> 00044 00045 #include <errno.h> 00046 #include <string.h> 00047 00048 00049 00050 GWEN_SAR *GWEN_Sar_new(void) { 00051 GWEN_SAR *sr; 00052 00053 GWEN_NEW_OBJECT(GWEN_SAR, sr); 00054 sr->refCount=1; 00055 00056 sr->headers=GWEN_SarFileHeader_List_new(); 00057 00058 return sr; 00059 } 00060 00061 00062 00063 void GWEN_Sar_Attach(GWEN_SAR *sr) { 00064 assert(sr); 00065 assert(sr->refCount); 00066 sr->refCount++; 00067 } 00068 00069 00070 00071 void GWEN_Sar_free(GWEN_SAR *sr) { 00072 if (sr) { 00073 assert(sr->refCount); 00074 if (sr->refCount==1) { 00075 free(sr->archiveName); 00076 GWEN_SarFileHeader_List_free(sr->headers); 00077 GWEN_SyncIo_free(sr->archiveSio); 00078 sr->refCount=0; 00079 GWEN_FREE_OBJECT(sr); 00080 } 00081 else { 00082 sr->refCount--; 00083 } 00084 } 00085 } 00086 00087 00088 00089 int GWEN_Sar_CreateArchive(GWEN_SAR *sr, const char *aname) { 00090 GWEN_SYNCIO *sio; 00091 int rv; 00092 00093 assert(sr); 00094 assert(sr->refCount); 00095 00096 assert(aname); 00097 if (sr->openMode!=GWEN_Sar_OpenMode_Closed) { 00098 DBG_ERROR(GWEN_LOGDOMAIN, "Archive already open"); 00099 return GWEN_ERROR_OPEN; 00100 } 00101 00102 free(sr->archiveName); 00103 sr->archiveName=strdup(aname); 00104 sio=GWEN_SyncIo_File_new(aname, GWEN_SyncIo_File_CreationMode_CreateAlways); 00105 GWEN_SyncIo_AddFlags(sio, 00106 GWEN_SYNCIO_FILE_FLAGS_READ | 00107 GWEN_SYNCIO_FILE_FLAGS_WRITE | 00108 GWEN_SYNCIO_FILE_FLAGS_UREAD | 00109 GWEN_SYNCIO_FILE_FLAGS_UWRITE | 00110 GWEN_SYNCIO_FILE_FLAGS_GREAD | 00111 GWEN_SYNCIO_FILE_FLAGS_GWRITE); 00112 rv=GWEN_SyncIo_Connect(sio); 00113 if (rv<0) { 00114 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00115 GWEN_SyncIo_free(sio); 00116 return rv; 00117 } 00118 00119 sr->archiveSio=sio; 00120 sr->openMode=GWEN_Sar_OpenMode_Created; 00121 00122 sr->signaturePos=0; 00123 sr->signatureSize=0; 00124 00125 return 0; 00126 } 00127 00128 00129 00130 int GWEN_Sar_OpenArchive(GWEN_SAR *sr, const char *aname, 00131 GWEN_SYNCIO_FILE_CREATIONMODE cm, 00132 uint32_t acc) { 00133 GWEN_SYNCIO *sio; 00134 int rv; 00135 00136 assert(sr); 00137 assert(sr->refCount); 00138 00139 assert(aname); 00140 if (sr->openMode!=GWEN_Sar_OpenMode_Closed) { 00141 DBG_ERROR(GWEN_LOGDOMAIN, "Archive already open"); 00142 return GWEN_ERROR_OPEN; 00143 } 00144 00145 free(sr->archiveName); 00146 sr->archiveName=strdup(aname); 00147 sio=GWEN_SyncIo_File_new(aname, cm); 00148 GWEN_SyncIo_AddFlags(sio, acc); 00149 rv=GWEN_SyncIo_Connect(sio); 00150 if (rv<0) { 00151 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00152 GWEN_SyncIo_free(sio); 00153 return rv; 00154 } 00155 00156 sr->archiveSio=sio; 00157 sr->openMode=GWEN_Sar_OpenMode_Opened; 00158 00159 sr->signaturePos=0; 00160 sr->signatureSize=0; 00161 00162 rv=GWEN_Sar_ScanFile(sr); 00163 if (rv<0) { 00164 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00165 sr->archiveSio=NULL; 00166 sr->openMode=GWEN_Sar_OpenMode_Closed; 00167 GWEN_SyncIo_free(sio); 00168 return rv; 00169 } 00170 00171 return 0; 00172 } 00173 00174 00175 00176 int GWEN_Sar_CloseArchive(GWEN_SAR *sr, int abandon) { 00177 int rv; 00178 00179 assert(sr); 00180 assert(sr->refCount); 00181 00182 if (sr->openMode!=GWEN_Sar_OpenMode_Opened && 00183 sr->openMode!=GWEN_Sar_OpenMode_Created) { 00184 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open"); 00185 return GWEN_ERROR_NOT_OPEN; 00186 } 00187 00188 if (!abandon) { 00189 /* flush */ 00190 rv=GWEN_SyncIo_Flush(sr->archiveSio); 00191 if (rv<0) { 00192 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00193 GWEN_SyncIo_Disconnect(sr->archiveSio); 00194 GWEN_SyncIo_free(sr->archiveSio); 00195 sr->archiveSio=NULL; 00196 free(sr->archiveName); 00197 sr->archiveName=NULL; 00198 sr->openMode=GWEN_Sar_OpenMode_Closed; 00199 return rv; 00200 } 00201 } 00202 00203 /* disconnect */ 00204 rv=GWEN_SyncIo_Disconnect(sr->archiveSio); 00205 if (rv<0) { 00206 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00207 GWEN_SyncIo_free(sr->archiveSio); 00208 sr->archiveSio=NULL; 00209 free(sr->archiveName); 00210 sr->archiveName=NULL; 00211 sr->openMode=GWEN_Sar_OpenMode_Closed; 00212 return rv; 00213 } 00214 00215 GWEN_SyncIo_free(sr->archiveSio); 00216 sr->archiveSio=NULL; 00217 free(sr->archiveName); 00218 sr->archiveName=NULL; 00219 sr->openMode=GWEN_Sar_OpenMode_Closed; 00220 return 0; 00221 } 00222 00223 00224 00225 int GWEN_Sar_FileHeaderToTlv(const GWEN_SAR_FILEHEADER *fh, GWEN_BUFFER *tbuf) { 00226 const char *s; 00227 uint16_t v8; 00228 uint32_t v32; 00229 uint64_t v64; 00230 uint8_t hbuf[8]; 00231 const GWEN_TIME *ti; 00232 int rv; 00233 00234 /* header version */ 00235 v32=GWEN_SAR_HEADER_VERSION; 00236 hbuf[0]=(v32>>24) & 0xff; 00237 hbuf[1]=(v32>>16) & 0xff; 00238 hbuf[2]=(v32>>8) & 0xff; 00239 hbuf[3]=v32 & 0xff; 00240 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_VERSION, 0x00, hbuf, 4, 1, tbuf); 00241 00242 /* status */ 00243 v8=GWEN_SarFileHeader_GetStatus(fh) & 0xff; 00244 hbuf[0]=v8; 00245 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_STATUS, 0x00, hbuf, 1, 1, tbuf); 00246 00247 /* flags */ 00248 v32=GWEN_SarFileHeader_GetFlags(fh); 00249 hbuf[0]=(v32>>24) & 0xff; 00250 hbuf[1]=(v32>>16) & 0xff; 00251 hbuf[2]=(v32>>8) & 0xff; 00252 hbuf[3]=v32 & 0xff; 00253 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_FLAGS, 0x00, hbuf, 4, 1, tbuf); 00254 00255 /* path */ 00256 s=GWEN_SarFileHeader_GetPath(fh); 00257 if (s && *s) 00258 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_PATH, 0x00, s, strlen(s)+1, 1, tbuf); 00259 00260 /* file type */ 00261 v8=GWEN_SarFileHeader_GetFileType(fh) & 0xff; 00262 hbuf[0]=v8; 00263 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_TYPE, 0x00, hbuf, 1, 1, tbuf); 00264 00265 /* permissions */ 00266 v32=GWEN_SarFileHeader_GetPermissions(fh); 00267 hbuf[0]=(v32>>24) & 0xff; 00268 hbuf[1]=(v32>>16) & 0xff; 00269 hbuf[2]=(v32>>8) & 0xff; 00270 hbuf[3]=v32 & 0xff; 00271 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_PERM, 0x00, hbuf, 4, 1, tbuf); 00272 00273 /* atime */ 00274 ti=GWEN_SarFileHeader_GetAtime(fh); 00275 if (ti) { 00276 GWEN_BUFFER *xbuf; 00277 00278 xbuf=GWEN_Buffer_new(0, 32, 0, 1); 00279 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf); 00280 if (rv>=0) 00281 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_ATIME, 0x00, 00282 GWEN_Buffer_GetStart(xbuf), 00283 GWEN_Buffer_GetUsedBytes(xbuf), 00284 1, 00285 tbuf); 00286 GWEN_Buffer_free(xbuf); 00287 } 00288 00289 /* mtime */ 00290 ti=GWEN_SarFileHeader_GetMtime(fh); 00291 if (ti) { 00292 GWEN_BUFFER *xbuf; 00293 00294 xbuf=GWEN_Buffer_new(0, 32, 0, 1); 00295 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf); 00296 if (rv>=0) 00297 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_MTIME, 0x00, 00298 GWEN_Buffer_GetStart(xbuf), 00299 GWEN_Buffer_GetUsedBytes(xbuf), 00300 1, 00301 tbuf); 00302 GWEN_Buffer_free(xbuf); 00303 } 00304 00305 /* ctime */ 00306 ti=GWEN_SarFileHeader_GetCtime(fh); 00307 if (ti) { 00308 GWEN_BUFFER *xbuf; 00309 00310 xbuf=GWEN_Buffer_new(0, 32, 0, 1); 00311 rv=GWEN_Time_toUtcString(ti, "YYYYMMDDhhmmss", xbuf); 00312 if (rv>=0) 00313 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_CTIME, 0x00, 00314 GWEN_Buffer_GetStart(xbuf), 00315 GWEN_Buffer_GetUsedBytes(xbuf), 00316 1, 00317 tbuf); 00318 GWEN_Buffer_free(xbuf); 00319 } 00320 00321 /* file size */ 00322 v64=GWEN_SarFileHeader_GetFileSize(fh); 00323 hbuf[0]=(v64>>56) & 0xff; 00324 hbuf[1]=(v64>>48) & 0xff; 00325 hbuf[2]=(v64>>40) & 0xff; 00326 hbuf[3]=(v64>>32) & 0xff; 00327 hbuf[4]=(v64>>24) & 0xff; 00328 hbuf[5]=(v64>>16) & 0xff; 00329 hbuf[6]=(v64>>8) & 0xff; 00330 hbuf[7]=v64 & 0xff; 00331 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HEADER_SIZE, 0x00, hbuf, 8, 1, tbuf); 00332 00333 return 0; 00334 } 00335 00336 00337 00338 uint64_t GWEN_Sar_ReadUint64(const uint8_t *p, uint32_t bs) { 00339 uint64_t v=0; 00340 00341 switch(bs) { 00342 case 8: 00343 v=(((uint64_t)(p[0]))<<56)+ 00344 (((uint64_t)(p[1]))<<48)+ 00345 (((uint64_t)(p[2]))<<40)+ 00346 (((uint64_t)(p[3]))<<32)+ 00347 (((uint64_t)(p[4]))<<24)+ 00348 (((uint64_t)(p[5]))<<16)+ 00349 (((uint64_t)(p[6]))<<8)+ 00350 ((uint64_t)(p[7])); 00351 break; 00352 case 7: 00353 v=(((uint64_t)(p[0]))<<48)+ 00354 (((uint64_t)(p[1]))<<40)+ 00355 (((uint64_t)(p[2]))<<32)+ 00356 (((uint64_t)(p[3]))<<24)+ 00357 (((uint64_t)(p[4]))<<16)+ 00358 (((uint64_t)(p[5]))<<8)+ 00359 ((uint64_t)(p[6])); 00360 break; 00361 case 6: 00362 v=(((uint64_t)(p[0]))<<40)+ 00363 (((uint64_t)(p[1]))<<32)+ 00364 (((uint64_t)(p[2]))<<24)+ 00365 (((uint64_t)(p[3]))<<16)+ 00366 (((uint64_t)(p[4]))<<8)+ 00367 ((uint64_t)(p[5])); 00368 break; 00369 case 5: 00370 v=(((uint64_t)(p[0]))<<32)+ 00371 (((uint64_t)(p[1]))<<24)+ 00372 (((uint64_t)(p[2]))<<16)+ 00373 (((uint64_t)(p[3]))<<8)+ 00374 ((uint64_t)(p[4])); 00375 break; 00376 case 4: 00377 v=(((uint64_t)(p[0]))<<24)+ 00378 (((uint64_t)(p[1]))<<16)+ 00379 (((uint64_t)(p[2]))<<8)+ 00380 ((uint64_t)(p[3])); 00381 break; 00382 case 3: 00383 v=(((uint64_t)(p[0]))<<16)+ 00384 (((uint64_t)(p[1]))<<8)+ 00385 ((uint64_t)(p[2])); 00386 break; 00387 case 2: 00388 v=(((uint64_t)(p[0]))<<8)+ 00389 ((uint64_t)(p[1])); 00390 break; 00391 case 1: 00392 v=((uint64_t)(p[0])); 00393 break; 00394 00395 default: 00396 DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported size of %d for uint32", bs); 00397 break; 00398 } 00399 00400 return v; 00401 } 00402 00403 00404 00405 int GWEN_Sar_TlvToFileHeader(GWEN_BUFFER *mbuf, GWEN_SAR_FILEHEADER *fh) { 00406 while(GWEN_Buffer_GetBytesLeft(mbuf)) { 00407 GWEN_TLV *tlv; 00408 00409 tlv=GWEN_TLV_fromBuffer(mbuf, 1); 00410 if (tlv) { 00411 const uint8_t *p; 00412 uint32_t bs; 00413 uint64_t v; 00414 GWEN_TIME *ti; 00415 00416 p=GWEN_TLV_GetTagData(tlv); 00417 bs=GWEN_TLV_GetTagLength(tlv); 00418 switch(GWEN_TLV_GetTagType(tlv)) { 00419 case GWEN_SAR_TAG_HEADER_VERSION: 00420 v=GWEN_Sar_ReadUint64(p, bs); 00421 DBG_DEBUG(GWEN_LOGDOMAIN, "File Header Version: %08x", (unsigned int) (v & 0xffffffff)); 00422 break; 00423 00424 case GWEN_SAR_TAG_HEADER_STATUS: 00425 v=GWEN_Sar_ReadUint64(p, bs); 00426 GWEN_SarFileHeader_SetStatus(fh, v & 0xffffffff); 00427 break; 00428 00429 case GWEN_SAR_TAG_HEADER_FLAGS: 00430 v=GWEN_Sar_ReadUint64(p, bs); 00431 GWEN_SarFileHeader_SetFlags(fh, v & 0xffffffff); 00432 break; 00433 00434 case GWEN_SAR_TAG_HEADER_PATH: 00435 GWEN_SarFileHeader_SetPath(fh, (const char*)p); 00436 break; 00437 00438 case GWEN_SAR_TAG_HEADER_TYPE: 00439 v=GWEN_Sar_ReadUint64(p, bs); 00440 GWEN_SarFileHeader_SetFileType(fh, v & 0xffffffff); 00441 break; 00442 00443 case GWEN_SAR_TAG_HEADER_PERM: 00444 v=GWEN_Sar_ReadUint64(p, bs); 00445 GWEN_SarFileHeader_SetPermissions(fh, v & 0xffffffff); 00446 break; 00447 00448 case GWEN_SAR_TAG_HEADER_ATIME: 00449 ti=GWEN_Time_fromUtcString((const char*) p, "YYYYMMDDhhmmss"); 00450 GWEN_SarFileHeader_SetAtime(fh, ti); 00451 break; 00452 00453 case GWEN_SAR_TAG_HEADER_MTIME: 00454 ti=GWEN_Time_fromUtcString((const char*) p, "YYYYMMDDhhmmss"); 00455 GWEN_SarFileHeader_SetMtime(fh, ti); 00456 break; 00457 00458 case GWEN_SAR_TAG_HEADER_CTIME: 00459 ti=GWEN_Time_fromUtcString((const char*) p, "YYYYMMDDhhmmss"); 00460 GWEN_SarFileHeader_SetCtime(fh, ti); 00461 break; 00462 00463 case GWEN_SAR_TAG_HEADER_SIZE: 00464 v=GWEN_Sar_ReadUint64(p, bs); 00465 GWEN_SarFileHeader_SetFileSize(fh, v); 00466 break; 00467 default: 00468 DBG_WARN(GWEN_LOGDOMAIN, "Ignoring unknown tag %d", GWEN_TLV_GetTagType(tlv)); 00469 break; 00470 } 00471 00472 } 00473 else { 00474 DBG_ERROR(GWEN_LOGDOMAIN, "No TLV in buffer"); 00475 return GWEN_ERROR_BAD_DATA; 00476 } 00477 } 00478 return 0; 00479 } 00480 00481 00482 00483 int GWEN_Sar_AddAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md) { 00484 int rv; 00485 const char *fname; 00486 uint64_t fsize; 00487 uint64_t bytesDone; 00488 GWEN_BUFFER *hbuf; 00489 00490 assert(sr); 00491 assert(sr->refCount); 00492 00493 fname=GWEN_SarFileHeader_GetPath(fh); 00494 assert(fname); 00495 fsize=GWEN_SarFileHeader_GetFileSize(fh); 00496 00497 /* create TLV header */ 00498 hbuf=GWEN_Buffer_new(0, 32, 0, 1); 00499 rv=GWEN_TLV_WriteHeader(GWEN_SAR_TAG_FILE, 0x00, fsize, 1, hbuf); 00500 if (rv<0) { 00501 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00502 GWEN_Buffer_free(hbuf); 00503 return rv; 00504 } 00505 00506 /* write TLV header */ 00507 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, 00508 (const uint8_t*) GWEN_Buffer_GetStart(hbuf), 00509 GWEN_Buffer_GetUsedBytes(hbuf)); 00510 if (rv<0) { 00511 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00512 GWEN_Buffer_free(hbuf); 00513 return rv; 00514 } 00515 00516 GWEN_Buffer_free(hbuf); 00517 00518 /* copy file if fsize>0 */ 00519 if (fsize>0) { 00520 GWEN_SYNCIO *sio; 00521 uint32_t pid; 00522 00523 /* open input file */ 00524 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_OpenExisting); 00525 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ); 00526 rv=GWEN_SyncIo_Connect(sio); 00527 if (rv<0) { 00528 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00529 GWEN_SyncIo_free(sio); 00530 return rv; 00531 } 00532 00533 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 00534 GWEN_GUI_PROGRESS_SHOW_ABORT | 00535 GWEN_GUI_PROGRESS_ALLOW_EMBED | 00536 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 00537 I18N("File Operation"), 00538 I18N("Copying file into archive"), 00539 fsize, 00540 0); 00541 bytesDone=0; 00542 while(fsize) { 00543 uint8_t fbuf[10240]; 00544 uint64_t bs; 00545 00546 bs=fsize; 00547 if (bs>sizeof(fbuf)) 00548 bs=sizeof(fbuf); 00549 00550 /* read from input */ 00551 rv=GWEN_SyncIo_Read(sio, fbuf, bs); 00552 if (rv<0) { 00553 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00554 GWEN_Gui_ProgressEnd(pid); 00555 GWEN_SyncIo_Disconnect(sio); 00556 GWEN_SyncIo_free(sio); 00557 return rv; 00558 } 00559 bs=rv; 00560 00561 /* digest data */ 00562 rv=GWEN_MDigest_Update(md, fbuf, bs); 00563 if (rv<0) { 00564 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00565 GWEN_Gui_ProgressEnd(pid); 00566 GWEN_SyncIo_Disconnect(sio); 00567 GWEN_SyncIo_free(sio); 00568 return rv; 00569 } 00570 00571 /* write to archive */ 00572 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, fbuf, bs); 00573 if (rv<0) { 00574 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00575 GWEN_Gui_ProgressEnd(pid); 00576 GWEN_SyncIo_Disconnect(sio); 00577 GWEN_SyncIo_free(sio); 00578 return rv; 00579 } 00580 00581 if (bs>fsize) { 00582 DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: bs>fsize (%lu>%lu)", 00583 (unsigned long int)bs, (unsigned long int) fsize); 00584 GWEN_Gui_ProgressEnd(pid); 00585 GWEN_SyncIo_Disconnect(sio); 00586 GWEN_SyncIo_free(sio); 00587 return rv; 00588 } 00589 00590 bytesDone+=bs; 00591 fsize-=bs; 00592 00593 /* advance progress bar */ 00594 rv=GWEN_Gui_ProgressAdvance(pid, bytesDone); 00595 if (rv<0) { 00596 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00597 GWEN_Gui_ProgressEnd(pid); 00598 GWEN_SyncIo_Disconnect(sio); 00599 GWEN_SyncIo_free(sio); 00600 return rv; 00601 } 00602 00603 } /* while */ 00604 GWEN_Gui_ProgressEnd(pid); 00605 00606 /* close input file */ 00607 GWEN_SyncIo_Disconnect(sio); 00608 GWEN_SyncIo_free(sio); 00609 } 00610 00611 return 0; 00612 } 00613 00614 00615 00616 int GWEN_Sar_AddAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md) { 00617 #if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) || _POSIX_C_SOURCE >= 200112L || defined(OS_DARWIN) 00618 int rv; 00619 const char *fname; 00620 GWEN_BUFFER *hbuf; 00621 char lbuf[300]; 00622 int len; 00623 00624 assert(sr); 00625 assert(sr->refCount); 00626 00627 fname=GWEN_SarFileHeader_GetPath(fh); 00628 assert(fname); 00629 00630 /* read link content */ 00631 rv=readlink(fname, lbuf, sizeof(lbuf)-1); 00632 if (rv<0) { 00633 DBG_ERROR(GWEN_LOGDOMAIN, "readlink(%s): %d (%s)", 00634 fname, errno, strerror(errno)); 00635 return GWEN_ERROR_IO; 00636 } 00637 len=rv; 00638 lbuf[len]=0; 00639 00640 /* create TLV header */ 00641 hbuf=GWEN_Buffer_new(0, rv+8, 0, 1); 00642 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_FILE, 0x00, 00643 lbuf, len+1, 00644 1, hbuf); 00645 00646 00647 /* write TLV */ 00648 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, 00649 (const uint8_t*) GWEN_Buffer_GetStart(hbuf), 00650 GWEN_Buffer_GetUsedBytes(hbuf)); 00651 if (rv<0) { 00652 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00653 GWEN_Buffer_free(hbuf); 00654 return rv; 00655 } 00656 GWEN_Buffer_free(hbuf); 00657 00658 /* digest data */ 00659 rv=GWEN_MDigest_Update(md, (const uint8_t*) lbuf, len+1); 00660 if (rv<0) { 00661 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00662 return rv; 00663 } 00664 00665 return 0; 00666 #else 00667 # warning "Function readlink() is not available" 00668 DBG_ERROR(GWEN_LOGDOMAIN, "Function readlink() is not available"); 00669 return GWEN_ERROR_IO; 00670 #endif 00671 } 00672 00673 00674 00675 int GWEN_Sar_AddAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, GWEN_MDIGEST *md) { 00676 int rv; 00677 00678 switch(GWEN_SarFileHeader_GetFileType(fh)) { 00679 case GWEN_SarFileHeader_FType_File: 00680 rv=GWEN_Sar_AddAndDigestFileReg(sr, fh, md); 00681 break; 00682 case GWEN_SarFileHeader_FType_Dir: 00683 rv=0; 00684 break; 00685 case GWEN_SarFileHeader_FType_SymLink: 00686 rv=GWEN_Sar_AddAndDigestFileLink(sr, fh, md); 00687 break; 00688 default: 00689 DBG_ERROR(GWEN_LOGDOMAIN, "File type %d not supported", GWEN_SarFileHeader_GetFileType(fh)); 00690 return GWEN_ERROR_INVALID; 00691 } 00692 00693 if (rv<0) { 00694 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00695 return rv; 00696 } 00697 00698 return 0; 00699 } 00700 00701 00702 00703 int GWEN_Sar_AddFile(GWEN_SAR *sr, const char *fname) { 00704 struct stat st; 00705 int rv; 00706 GWEN_SAR_FILEHEADER *fh; 00707 GWEN_TIME *ti; 00708 GWEN_BUFFER *hbuf; 00709 GWEN_BUFFER *xbuf; 00710 GWEN_MDIGEST *md; 00711 uint64_t pos; 00712 00713 assert(sr); 00714 assert(sr->refCount); 00715 00716 /* stat file to be added */ 00717 #if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED 00718 rv=lstat(fname, &st); 00719 #else 00720 rv=stat(fname, &st); 00721 #endif 00722 if (rv) { 00723 DBG_ERROR(GWEN_LOGDOMAIN, "stat(%s): %d (%s)", 00724 fname, errno, strerror(errno)); 00725 return GWEN_ERROR_IO; 00726 } 00727 00728 /* create and setup file header */ 00729 fh=GWEN_SarFileHeader_new(); 00730 00731 /* path */ 00732 GWEN_SarFileHeader_SetPath(fh, fname); 00733 00734 /* file type */ 00735 switch(st.st_mode & S_IFMT) { 00736 #ifdef S_IFLNK 00737 case S_IFLNK: 00738 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_SymLink); 00739 break; 00740 #endif 00741 case S_IFREG: 00742 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_File); 00743 break; 00744 case S_IFDIR: 00745 GWEN_SarFileHeader_SetFileType(fh, GWEN_SarFileHeader_FType_Dir); 00746 break; 00747 default: 00748 GWEN_SarFileHeader_free(fh); 00749 return GWEN_ERROR_INVALID; 00750 } 00751 00752 /* permissions */ 00753 if (st.st_mode & S_IRUSR) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UREAD); 00754 if (st.st_mode & S_IWUSR) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UWRITE); 00755 if (st.st_mode & S_IXUSR) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_UEXEC); 00756 00757 #ifdef S_IRGRP 00758 if (st.st_mode & S_IRGRP) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GREAD); 00759 #endif 00760 #ifdef S_IWGRP 00761 if (st.st_mode & S_IWGRP) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GWRITE); 00762 #endif 00763 #ifdef S_IXGRP 00764 if (st.st_mode & S_IXGRP) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_GEXEC); 00765 #endif 00766 00767 #ifdef S_IROTH 00768 if (st.st_mode & S_IROTH) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OREAD); 00769 #endif 00770 #ifdef S_IWOTH 00771 if (st.st_mode & S_IWOTH) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OWRITE); 00772 #endif 00773 #ifdef S_IXOTH 00774 if (st.st_mode & S_IXOTH) GWEN_SarFileHeader_AddPermissions(fh, GWEN_SYNCIO_FILE_FLAGS_OEXEC); 00775 #endif 00776 00777 /* atime */ 00778 ti=GWEN_Time_fromSeconds(st.st_atime); 00779 GWEN_SarFileHeader_SetAtime(fh, ti); 00780 00781 /* mtime */ 00782 ti=GWEN_Time_fromSeconds(st.st_mtime); 00783 GWEN_SarFileHeader_SetMtime(fh, ti); 00784 00785 /* ctime */ 00786 ti=GWEN_Time_fromSeconds(st.st_ctime); 00787 GWEN_SarFileHeader_SetCtime(fh, ti); 00788 00789 /* file size */ 00790 GWEN_SarFileHeader_SetFileSize(fh, st.st_size); 00791 00792 00793 /* prepare header */ 00794 hbuf=GWEN_Buffer_new(0, 256, 0, 1); 00795 GWEN_Buffer_ReserveBytes(hbuf, 16); 00796 rv=GWEN_Sar_FileHeaderToTlv(fh, hbuf); 00797 if (rv<0) { 00798 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00799 GWEN_Buffer_free(hbuf); 00800 GWEN_SarFileHeader_free(fh); 00801 return rv; 00802 } 00803 00804 /* create TLV header for file header */ 00805 xbuf=GWEN_Buffer_new(0, 16, 0, 1); 00806 rv=GWEN_TLV_WriteHeader(GWEN_SAR_TAG_HEADER, 0xe0, 00807 GWEN_Buffer_GetUsedBytes(hbuf), 1, xbuf); 00808 if (rv<0) { 00809 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00810 GWEN_Buffer_free(xbuf); 00811 GWEN_Buffer_free(hbuf); 00812 GWEN_SarFileHeader_free(fh); 00813 return rv; 00814 } 00815 00816 /* insert TLV header into file header buffer */ 00817 GWEN_Buffer_SetPos(hbuf, 0); 00818 GWEN_Buffer_InsertBytes(hbuf, 00819 GWEN_Buffer_GetStart(xbuf), 00820 GWEN_Buffer_GetUsedBytes(xbuf)); 00821 GWEN_Buffer_SetPos(hbuf, GWEN_Buffer_GetUsedBytes(hbuf)); 00822 GWEN_Buffer_free(xbuf); 00823 00824 /* seek to end of file */ 00825 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, 0, GWEN_SyncIo_File_Whence_End); 00826 if (pos<0) { 00827 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 00828 GWEN_Buffer_free(hbuf); 00829 GWEN_SarFileHeader_free(fh); 00830 return (int) pos; 00831 } 00832 00833 /* write header into archive file */ 00834 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, 00835 (const uint8_t*) GWEN_Buffer_GetStart(hbuf), 00836 GWEN_Buffer_GetUsedBytes(hbuf)); 00837 if (rv<0) { 00838 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00839 GWEN_Buffer_free(hbuf); 00840 GWEN_SarFileHeader_free(fh); 00841 return rv; 00842 } 00843 00844 /* prepare digest */ 00845 md=GWEN_MDigest_Rmd160_new(); 00846 rv=GWEN_MDigest_Begin(md); 00847 if (rv<0) { 00848 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00849 GWEN_MDigest_free(md); 00850 GWEN_Buffer_free(hbuf); 00851 GWEN_SarFileHeader_free(fh); 00852 return rv; 00853 } 00854 00855 /* digest header */ 00856 rv=GWEN_MDigest_Update(md, (const uint8_t*) GWEN_Buffer_GetStart(hbuf), GWEN_Buffer_GetUsedBytes(hbuf)); 00857 if (rv<0) { 00858 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00859 GWEN_MDigest_free(md); 00860 GWEN_Buffer_free(hbuf); 00861 GWEN_SarFileHeader_free(fh); 00862 return rv; 00863 } 00864 00865 GWEN_Buffer_Reset(hbuf); 00866 00867 /* copy file into archive */ 00868 rv=GWEN_Sar_AddAndDigestFile(sr, fh, md); 00869 if (rv<0) { 00870 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00871 GWEN_MDigest_free(md); 00872 GWEN_Buffer_free(hbuf); 00873 GWEN_SarFileHeader_free(fh); 00874 return rv; 00875 } 00876 00877 /* finish hash */ 00878 rv=GWEN_MDigest_End(md); 00879 if (rv<0) { 00880 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00881 GWEN_MDigest_free(md); 00882 GWEN_Buffer_free(hbuf); 00883 GWEN_SarFileHeader_free(fh); 00884 return rv; 00885 } 00886 00887 /* create hash TLV */ 00888 GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_HASH, 0x00, 00889 GWEN_MDigest_GetDigestPtr(md), 00890 GWEN_MDigest_GetDigestSize(md), 00891 1, hbuf); 00892 GWEN_MDigest_free(md); 00893 00894 /* write hash into archive file */ 00895 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, 00896 (const uint8_t*) GWEN_Buffer_GetStart(hbuf), 00897 GWEN_Buffer_GetUsedBytes(hbuf)); 00898 if (rv<0) { 00899 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00900 GWEN_Buffer_free(hbuf); 00901 GWEN_SarFileHeader_free(fh); 00902 return rv; 00903 } 00904 00905 /* done */ 00906 GWEN_Buffer_free(hbuf); 00907 GWEN_SarFileHeader_free(fh); 00908 return 0; 00909 } 00910 00911 00912 00913 00914 int GWEN_Sar_ScanFile(GWEN_SAR *sr) { 00915 int rv; 00916 int64_t pos; 00917 GWEN_BUFFER *mbuf; 00918 GWEN_SAR_FILEHEADER *lastHeader=NULL; 00919 00920 assert(sr); 00921 assert(sr->refCount); 00922 00923 sr->signaturePos=0; 00924 sr->signatureSize=0; 00925 00926 /* scan all TLV elements */ 00927 pos=0; 00928 mbuf=GWEN_Buffer_new(0, 1024, 0, 1); 00929 for (;;) { 00930 int64_t startOfTagHeader; 00931 int64_t startOfTagData; 00932 unsigned int tagType; 00933 uint32_t tagLength; 00934 uint32_t fullTagSize; 00935 uint32_t bs; 00936 GWEN_TLV *tlv; 00937 uint8_t buffer[32]; 00938 00939 startOfTagHeader=pos; 00940 rv=GWEN_SyncIo_Read(sr->archiveSio, buffer, sizeof(buffer)); 00941 if (rv<0) { 00942 if (rv==GWEN_ERROR_EOF) 00943 break; 00944 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00945 GWEN_Buffer_free(mbuf); 00946 return rv; 00947 } 00948 else if (rv==0) { 00949 DBG_VERBOUS(GWEN_LOGDOMAIN, "EOF met"); 00950 break; 00951 } 00952 bs=rv; 00953 00954 /* read start of fileheader TLV */ 00955 tlv=GWEN_TLV_new(); 00956 rv=GWEN_TLV_ReadHeader(tlv, buffer, bs, 1); 00957 if (rv<2) { 00958 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00959 GWEN_TLV_free(tlv); 00960 GWEN_Buffer_free(mbuf); 00961 return rv; 00962 } 00963 /* got it, now calculate start of tag data */ 00964 startOfTagData=pos+rv; 00965 tagLength=GWEN_TLV_GetTagLength(tlv); 00966 tagType=GWEN_TLV_GetTagType(tlv); 00967 fullTagSize=GWEN_TLV_GetTagSize(tlv); 00968 GWEN_TLV_free(tlv); 00969 00970 /* seek to start of header data */ 00971 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, startOfTagData, GWEN_SyncIo_File_Whence_Set); 00972 if (pos<0) { 00973 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 00974 GWEN_Buffer_free(mbuf); 00975 return (int) pos; 00976 } 00977 00978 /* now read or skip info */ 00979 if (tagType==GWEN_SAR_TAG_HEADER) { 00980 GWEN_SAR_FILEHEADER *fh; 00981 const char *s; 00982 00983 /* alloc memory for data */ 00984 GWEN_Buffer_AllocRoom(mbuf, tagLength); 00985 00986 /* read header data */ 00987 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, (uint8_t*) GWEN_Buffer_GetStart(mbuf), tagLength); 00988 if (rv<0) { 00989 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 00990 GWEN_Buffer_free(mbuf); 00991 return rv; 00992 } 00993 GWEN_Buffer_IncrementPos(mbuf, tagLength); 00994 GWEN_Buffer_AdjustUsedBytes(mbuf); 00995 GWEN_Buffer_Rewind(mbuf); 00996 00997 /* now parse header */ 00998 fh=GWEN_SarFileHeader_new(); 00999 rv=GWEN_Sar_TlvToFileHeader(mbuf, fh); 01000 if (rv<0) { 01001 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01002 GWEN_SarFileHeader_free(fh); 01003 GWEN_Buffer_free(mbuf); 01004 return rv; 01005 } 01006 01007 GWEN_SarFileHeader_SetHeaderStartPos(fh, startOfTagHeader); 01008 GWEN_SarFileHeader_SetHeaderSize(fh, fullTagSize); 01009 01010 s=GWEN_SarFileHeader_GetPath(fh); 01011 DBG_DEBUG(GWEN_LOGDOMAIN, "Got entry [%s]", s?s:"(empty)"); 01012 01013 GWEN_SarFileHeader_List_Add(fh, sr->headers); 01014 lastHeader=fh; 01015 } 01016 else if (tagType==GWEN_SAR_TAG_FILE) { 01017 if (lastHeader==NULL) { 01018 DBG_ERROR(GWEN_LOGDOMAIN, "Bad file structure: No file header before data"); 01019 GWEN_Buffer_free(mbuf); 01020 return GWEN_ERROR_BAD_DATA; 01021 } 01022 if (GWEN_SarFileHeader_GetFileType(lastHeader)!=GWEN_SarFileHeader_FType_SymLink && 01023 GWEN_SarFileHeader_GetFileSize(lastHeader)!=tagLength) { 01024 DBG_ERROR(GWEN_LOGDOMAIN, "File size in header and in archive differ (%s: hs=%lu, ts=%lu)", 01025 GWEN_SarFileHeader_GetPath(lastHeader), 01026 (unsigned long int) GWEN_SarFileHeader_GetFileSize(lastHeader), 01027 (unsigned long int) tagLength); 01028 GWEN_Buffer_free(mbuf); 01029 return GWEN_ERROR_BAD_DATA; 01030 } 01031 /* only store position of file data */ 01032 GWEN_SarFileHeader_SetDataPos(lastHeader, startOfTagData); 01033 GWEN_SarFileHeader_SetDataSize(lastHeader, tagLength); 01034 01035 /* skip data */ 01036 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current); 01037 if (pos<0) { 01038 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01039 GWEN_Buffer_free(mbuf); 01040 return (int) pos; 01041 } 01042 } 01043 else if (tagType==GWEN_SAR_TAG_HASH) { 01044 if (lastHeader==NULL) { 01045 DBG_ERROR(GWEN_LOGDOMAIN, "Bad file structure: No file header before data"); 01046 GWEN_Buffer_free(mbuf); 01047 return GWEN_ERROR_BAD_DATA; 01048 } 01049 /* only store position of file data */ 01050 GWEN_SarFileHeader_SetHashPos(lastHeader, startOfTagData); 01051 01052 /* skip data */ 01053 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current); 01054 if (pos<0) { 01055 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01056 GWEN_Buffer_free(mbuf); 01057 return (int) pos; 01058 } 01059 } 01060 else if (tagType==GWEN_SAR_TAG_SIGNATURE) { 01061 /* only store position of file data */ 01062 DBG_INFO(GWEN_LOGDOMAIN, "Signature found"); 01063 sr->signaturePos=startOfTagData; 01064 sr->signatureSize=tagLength; 01065 01066 /* skip data */ 01067 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current); 01068 if (pos<0) { 01069 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01070 GWEN_Buffer_free(mbuf); 01071 return (int) pos; 01072 } 01073 } 01074 else { 01075 DBG_WARN(GWEN_LOGDOMAIN, "Unknown TAG %d, ignoring", (int) tagType); 01076 /* just skip data */ 01077 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, tagLength, GWEN_SyncIo_File_Whence_Current); 01078 if (pos<0) { 01079 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01080 GWEN_Buffer_free(mbuf); 01081 return (int) pos; 01082 } 01083 } 01084 01085 GWEN_Buffer_Reset(mbuf); 01086 pos=startOfTagData+tagLength; 01087 } /* for */ 01088 01089 /* done */ 01090 GWEN_Buffer_free(mbuf); 01091 return 0; 01092 } 01093 01094 01095 01096 int GWEN_Sar_ExtractAndDigestFileReg(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly) { 01097 int rv; 01098 const char *fname; 01099 uint32_t perms; 01100 uint64_t dpos; 01101 uint64_t fsize; 01102 uint64_t bytesDone; 01103 uint64_t hsize; 01104 uint64_t hpos; 01105 uint64_t mpos; 01106 uint64_t pos; 01107 GWEN_MDIGEST *md; 01108 01109 assert(sr); 01110 assert(sr->refCount); 01111 01112 md=GWEN_MDigest_Rmd160_new(); 01113 rv=GWEN_MDigest_Begin(md); 01114 if (rv<0) { 01115 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01116 GWEN_MDigest_free(md); 01117 return rv; 01118 } 01119 01120 fname=GWEN_SarFileHeader_GetPath(fh); 01121 assert(fname); 01122 perms=GWEN_SarFileHeader_GetPermissions(fh); 01123 fsize=GWEN_SarFileHeader_GetFileSize(fh); 01124 dpos=GWEN_SarFileHeader_GetDataPos(fh); 01125 01126 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh); 01127 hsize=GWEN_SarFileHeader_GetHeaderSize(fh); 01128 if (hsize>0) { 01129 GWEN_BUFFER *mbuf; 01130 01131 /* seek to start of header */ 01132 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set); 01133 if (pos<0) { 01134 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01135 GWEN_MDigest_free(md); 01136 return (int) pos; 01137 } 01138 01139 mbuf=GWEN_Buffer_new(0, hsize, 0, 1); 01140 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01141 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01142 hsize); 01143 if (rv<0) { 01144 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01145 GWEN_Buffer_free(mbuf); 01146 GWEN_MDigest_free(md); 01147 return rv; 01148 } 01149 GWEN_Buffer_IncrementPos(mbuf, hsize); 01150 GWEN_Buffer_AdjustUsedBytes(mbuf); 01151 01152 /* digest TLV */ 01153 rv=GWEN_MDigest_Update(md, (const uint8_t*) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf)); 01154 if (rv<0) { 01155 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01156 GWEN_Buffer_free(mbuf); 01157 GWEN_MDigest_free(md); 01158 return rv; 01159 } 01160 GWEN_Buffer_free(mbuf); 01161 } 01162 01163 /* copy file if fsize>0 */ 01164 if (1) { 01165 GWEN_SYNCIO *sio=NULL; 01166 uint32_t pid; 01167 01168 /* open input file */ 01169 if (!checkOnly) { 01170 sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateNew); 01171 GWEN_SyncIo_AddFlags(sio, GWEN_SYNCIO_FILE_FLAGS_READ | GWEN_SYNCIO_FILE_FLAGS_WRITE); 01172 GWEN_SyncIo_AddFlags(sio, perms); 01173 rv=GWEN_SyncIo_Connect(sio); 01174 if (rv<0) { 01175 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01176 GWEN_SyncIo_free(sio); 01177 GWEN_MDigest_free(md); 01178 return rv; 01179 } 01180 } 01181 01182 if (fsize>0) { 01183 /* seek to start of data */ 01184 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, dpos, GWEN_SyncIo_File_Whence_Set); 01185 if (pos<0) { 01186 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01187 if (!checkOnly) { 01188 GWEN_SyncIo_Disconnect(sio); 01189 GWEN_SyncIo_free(sio); 01190 } 01191 GWEN_MDigest_free(md); 01192 return (int) pos; 01193 } 01194 01195 /* start extracting */ 01196 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 01197 GWEN_GUI_PROGRESS_SHOW_ABORT | 01198 GWEN_GUI_PROGRESS_ALLOW_EMBED | 01199 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 01200 I18N("File Operation"), 01201 I18N("Extracting file from archive"), 01202 fsize, 01203 0); 01204 bytesDone=0; 01205 while(fsize) { 01206 uint8_t fbuf[10240]; 01207 uint64_t bs; 01208 01209 bs=fsize; 01210 if (bs>sizeof(fbuf)) 01211 bs=sizeof(fbuf); 01212 01213 /* read from input */ 01214 rv=GWEN_SyncIo_Read(sr->archiveSio, fbuf, bs); 01215 if (rv<0) { 01216 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01217 GWEN_Gui_ProgressEnd(pid); 01218 if (!checkOnly) { 01219 GWEN_SyncIo_Disconnect(sio); 01220 GWEN_SyncIo_free(sio); 01221 } 01222 GWEN_MDigest_free(md); 01223 return rv; 01224 } 01225 bs=rv; 01226 01227 /* digest data */ 01228 rv=GWEN_MDigest_Update(md, fbuf, bs); 01229 if (rv<0) { 01230 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01231 GWEN_Gui_ProgressEnd(pid); 01232 if (!checkOnly) { 01233 GWEN_SyncIo_Disconnect(sio); 01234 GWEN_SyncIo_free(sio); 01235 } 01236 GWEN_MDigest_free(md); 01237 return rv; 01238 } 01239 01240 if (!checkOnly) { 01241 /* write to archive */ 01242 rv=GWEN_SyncIo_WriteForced(sio, fbuf, bs); 01243 if (rv<0) { 01244 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01245 GWEN_Gui_ProgressEnd(pid); 01246 if (!checkOnly) { 01247 GWEN_SyncIo_Disconnect(sio); 01248 GWEN_SyncIo_free(sio); 01249 } 01250 GWEN_MDigest_free(md); 01251 return rv; 01252 } 01253 } 01254 01255 if (bs>fsize) { 01256 DBG_ERROR(GWEN_LOGDOMAIN, "Internal error: bs>fsize (%lu>%lu)", 01257 (unsigned long int)bs, (unsigned long int) fsize); 01258 GWEN_Gui_ProgressEnd(pid); 01259 if (!checkOnly) { 01260 GWEN_SyncIo_Disconnect(sio); 01261 GWEN_SyncIo_free(sio); 01262 } 01263 GWEN_MDigest_free(md); 01264 return rv; 01265 } 01266 01267 bytesDone+=bs; 01268 fsize-=bs; 01269 01270 /* advance progress bar */ 01271 rv=GWEN_Gui_ProgressAdvance(pid, bytesDone); 01272 if (rv<0) { 01273 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01274 GWEN_Gui_ProgressEnd(pid); 01275 if (!checkOnly) { 01276 GWEN_SyncIo_Disconnect(sio); 01277 GWEN_SyncIo_free(sio); 01278 } 01279 GWEN_MDigest_free(md); 01280 return rv; 01281 } 01282 01283 } /* while */ 01284 GWEN_Gui_ProgressEnd(pid); 01285 } 01286 01287 if (!checkOnly) { 01288 /* close output file */ 01289 GWEN_SyncIo_Disconnect(sio); 01290 GWEN_SyncIo_free(sio); 01291 } 01292 01293 /* finish hash */ 01294 rv=GWEN_MDigest_End(md); 01295 if (rv<0) { 01296 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01297 GWEN_MDigest_free(md); 01298 return rv; 01299 } 01300 01301 /* read and check hash */ 01302 mpos=GWEN_SarFileHeader_GetHashPos(fh); 01303 if (mpos) { 01304 GWEN_BUFFER *mbuf; 01305 01306 /* seek to end of file */ 01307 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set); 01308 if (pos<0) { 01309 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01310 GWEN_MDigest_free(md); 01311 return (int) pos; 01312 } 01313 01314 /* read 20 bytes of hash */ 01315 mbuf=GWEN_Buffer_new(0, 20, 0, 1); 01316 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01317 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01318 20); 01319 if (rv<0) { 01320 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01321 GWEN_Buffer_free(mbuf); 01322 GWEN_MDigest_free(md); 01323 return rv; 01324 } 01325 GWEN_Buffer_IncrementPos(mbuf, 20); 01326 GWEN_Buffer_AdjustUsedBytes(mbuf); 01327 01328 if (memcmp(GWEN_MDigest_GetDigestPtr(md), 01329 GWEN_Buffer_GetStart(mbuf), 01330 20)!=0) { 01331 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01332 DBG_ERROR(0, "Hash don't match:"); 01333 GWEN_Text_LogString((const char*) GWEN_MDigest_GetDigestPtr(md), 20, 01334 GWEN_LOGDOMAIN, GWEN_LoggerLevel_Error); 01335 01336 GWEN_Text_LogString(GWEN_Buffer_GetStart(mbuf), 20, 01337 GWEN_LOGDOMAIN, GWEN_LoggerLevel_Error); 01338 GWEN_Buffer_free(mbuf); 01339 GWEN_MDigest_free(md); 01340 return GWEN_ERROR_BAD_DATA; 01341 } 01342 01343 GWEN_Buffer_free(mbuf); 01344 } 01345 01346 GWEN_MDigest_free(md); 01347 } 01348 01349 return 0; 01350 } 01351 01352 01353 01354 int GWEN_Sar_ExtractAndDigestFileLink(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly) { 01355 #if _BSD_SOURCE || _XOPEN_SOURCE >= 500 || (_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) || _POSIX_C_SOURCE >= 200112L || defined(OS_DARWIN) 01356 int rv; 01357 const char *fname; 01358 uint32_t perms; 01359 uint64_t dpos; 01360 uint64_t fsize; 01361 uint64_t hsize; 01362 uint64_t hpos; 01363 uint64_t mpos; 01364 uint64_t pos; 01365 GWEN_MDIGEST *md; 01366 01367 assert(sr); 01368 assert(sr->refCount); 01369 01370 md=GWEN_MDigest_Rmd160_new(); 01371 rv=GWEN_MDigest_Begin(md); 01372 if (rv<0) { 01373 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01374 GWEN_MDigest_free(md); 01375 return rv; 01376 } 01377 01378 fname=GWEN_SarFileHeader_GetPath(fh); 01379 perms=GWEN_SarFileHeader_GetPermissions(fh); 01380 assert(fname); 01381 fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */ 01382 dpos=GWEN_SarFileHeader_GetDataPos(fh); 01383 01384 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh); 01385 hsize=GWEN_SarFileHeader_GetHeaderSize(fh); 01386 if (hsize>0) { 01387 GWEN_BUFFER *mbuf; 01388 01389 /* seek to header pos */ 01390 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set); 01391 if (pos<0) { 01392 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01393 GWEN_MDigest_free(md); 01394 return (int) pos; 01395 } 01396 01397 mbuf=GWEN_Buffer_new(0, hsize, 0, 1); 01398 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01399 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01400 hsize); 01401 if (rv<0) { 01402 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01403 GWEN_Buffer_free(mbuf); 01404 GWEN_MDigest_free(md); 01405 return rv; 01406 } 01407 GWEN_Buffer_IncrementPos(mbuf, hsize); 01408 GWEN_Buffer_AdjustUsedBytes(mbuf); 01409 01410 /* digest header TLV */ 01411 rv=GWEN_MDigest_Update(md, (const uint8_t*) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf)); 01412 if (rv<0) { 01413 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01414 GWEN_Buffer_free(mbuf); 01415 GWEN_MDigest_free(md); 01416 return rv; 01417 } 01418 GWEN_Buffer_free(mbuf); 01419 } 01420 01421 /* seek to data pos */ 01422 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, dpos, GWEN_SyncIo_File_Whence_Set); 01423 if (pos<0) { 01424 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01425 GWEN_MDigest_free(md); 01426 return (int) pos; 01427 } 01428 01429 /* copy file if fsize>0 */ 01430 if (fsize>0) { /* fsize is the size of the file tag data */ 01431 GWEN_BUFFER *mbuf; 01432 01433 mbuf=GWEN_Buffer_new(0, fsize, 0, 1); 01434 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01435 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01436 fsize); 01437 if (rv<0) { 01438 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01439 GWEN_Buffer_free(mbuf); 01440 GWEN_MDigest_free(md); 01441 return rv; 01442 } 01443 GWEN_Buffer_IncrementPos(mbuf, fsize); 01444 GWEN_Buffer_AdjustUsedBytes(mbuf); 01445 01446 /* digest TLV */ 01447 rv=GWEN_MDigest_Update(md, (const uint8_t*) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf)); 01448 if (rv<0) { 01449 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01450 GWEN_Buffer_free(mbuf); 01451 GWEN_MDigest_free(md); 01452 return rv; 01453 } 01454 01455 if (!checkOnly) { 01456 mode_t mode=0; 01457 01458 if (symlink(GWEN_Buffer_GetStart(mbuf), fname)) { 01459 DBG_ERROR(GWEN_LOGDOMAIN, "symlink(%s, %s): %d (%s)", 01460 GWEN_Buffer_GetStart(mbuf), 01461 fname, errno, strerror(errno)); 01462 GWEN_Buffer_free(mbuf); 01463 GWEN_MDigest_free(md); 01464 return GWEN_ERROR_IO; 01465 } 01466 /* owner perms */ 01467 if (perms & GWEN_SYNCIO_FILE_FLAGS_UREAD) 01468 mode|=S_IRUSR; 01469 if (perms & GWEN_SYNCIO_FILE_FLAGS_UWRITE) 01470 mode|=S_IWUSR; 01471 if (perms & GWEN_SYNCIO_FILE_FLAGS_UEXEC) 01472 mode|=S_IXUSR; 01473 01474 #if 0 /* CHMOD on symlinks doesn't work */ 01475 01476 /* group perms */ 01477 #ifdef S_IRGRP 01478 if (perms & GWEN_SYNCIO_FILE_FLAGS_GREAD) mode|=S_IRGRP; 01479 #endif 01480 #ifdef S_IWGRP 01481 if (perms & GWEN_SYNCIO_FILE_FLAGS_GWRITE) mode|=S_IWGRP; 01482 #endif 01483 #ifdef S_IXGRP 01484 if (perms & GWEN_SYNCIO_FILE_FLAGS_GEXEC) mode|=S_IXGRP; 01485 #endif 01486 01487 /* other perms */ 01488 #ifdef S_IROTH 01489 if (perms & GWEN_SYNCIO_FILE_FLAGS_OREAD) mode|=S_IROTH; 01490 #endif 01491 #ifdef S_IWOTH 01492 if (perms & GWEN_SYNCIO_FILE_FLAGS_OWRITE) mode|=S_IWOTH; 01493 #endif 01494 #ifdef S_IXOTH 01495 if (perms & GWEN_SYNCIO_FILE_FLAGS_OEXEC) mode|=S_IXOTH; 01496 #endif 01497 01498 rv=chmod(fname, mode); 01499 if (rv<0) { 01500 DBG_WARN(GWEN_LOGDOMAIN, "chmod(%s): %d (%s), ignoring", 01501 fname, errno, strerror(errno)); 01502 } 01503 01504 #endif 01505 } 01506 GWEN_Buffer_free(mbuf); 01507 } 01508 01509 /* finish hash */ 01510 rv=GWEN_MDigest_End(md); 01511 if (rv<0) { 01512 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01513 GWEN_MDigest_free(md); 01514 return rv; 01515 } 01516 01517 /* read and check hash */ 01518 mpos=GWEN_SarFileHeader_GetHashPos(fh); 01519 if (mpos) { 01520 GWEN_BUFFER *mbuf; 01521 01522 /* seek to end of file */ 01523 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set); 01524 if (pos<0) { 01525 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01526 GWEN_MDigest_free(md); 01527 return (int) pos; 01528 } 01529 01530 /* read 20 bytes of hash */ 01531 mbuf=GWEN_Buffer_new(0, 20, 0, 1); 01532 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01533 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01534 20); 01535 if (rv<0) { 01536 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01537 GWEN_Buffer_free(mbuf); 01538 GWEN_MDigest_free(md); 01539 if (!checkOnly) 01540 unlink(fname); 01541 return rv; 01542 } 01543 GWEN_Buffer_IncrementPos(mbuf, 20); 01544 GWEN_Buffer_AdjustUsedBytes(mbuf); 01545 01546 if (memcmp(GWEN_MDigest_GetDigestPtr(md), 01547 GWEN_Buffer_GetStart(mbuf), 01548 20)!=0) { 01549 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01550 GWEN_Buffer_free(mbuf); 01551 GWEN_MDigest_free(md); 01552 if (!checkOnly) 01553 unlink(fname); 01554 return GWEN_ERROR_BAD_DATA; 01555 } 01556 01557 GWEN_Buffer_free(mbuf); 01558 } 01559 01560 GWEN_MDigest_free(md); 01561 01562 return 0; 01563 #else 01564 # warning "Function symlink() is not available" 01565 DBG_ERROR(GWEN_LOGDOMAIN, "Function symlink() is not available"); 01566 return GWEN_ERROR_IO; 01567 #endif 01568 } 01569 01570 01571 01572 int GWEN_Sar_ExtractAndDigestFileDir(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly) { 01573 int rv; 01574 const char *fname; 01575 uint64_t dpos; 01576 uint64_t fsize; 01577 uint64_t hsize; 01578 uint64_t hpos; 01579 uint64_t mpos; 01580 uint64_t pos; 01581 GWEN_MDIGEST *md; 01582 GWEN_BUFFER *mbuf; 01583 uint32_t perms; 01584 01585 assert(sr); 01586 assert(sr->refCount); 01587 01588 md=GWEN_MDigest_Rmd160_new(); 01589 rv=GWEN_MDigest_Begin(md); 01590 if (rv<0) { 01591 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01592 GWEN_MDigest_free(md); 01593 return rv; 01594 } 01595 01596 fname=GWEN_SarFileHeader_GetPath(fh); 01597 assert(fname); 01598 perms=GWEN_SarFileHeader_GetPermissions(fh); 01599 fsize=GWEN_SarFileHeader_GetDataSize(fh); /* not FileSize!! */ 01600 dpos=GWEN_SarFileHeader_GetDataPos(fh); 01601 01602 hpos=GWEN_SarFileHeader_GetHeaderStartPos(fh); 01603 hsize=GWEN_SarFileHeader_GetHeaderSize(fh); 01604 assert(hsize); 01605 01606 /* seek to end of file */ 01607 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set); 01608 if (pos<0) { 01609 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01610 GWEN_MDigest_free(md); 01611 return (int) pos; 01612 } 01613 01614 mbuf=GWEN_Buffer_new(0, hsize, 0, 1); 01615 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01616 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01617 hsize); 01618 if (rv<0) { 01619 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01620 GWEN_Buffer_free(mbuf); 01621 GWEN_MDigest_free(md); 01622 return rv; 01623 } 01624 GWEN_Buffer_IncrementPos(mbuf, hsize); 01625 GWEN_Buffer_AdjustUsedBytes(mbuf); 01626 01627 /* digest TLV */ 01628 rv=GWEN_MDigest_Update(md, (const uint8_t*) GWEN_Buffer_GetStart(mbuf), GWEN_Buffer_GetUsedBytes(mbuf)); 01629 if (rv<0) { 01630 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01631 GWEN_Buffer_free(mbuf); 01632 GWEN_MDigest_free(md); 01633 return rv; 01634 } 01635 GWEN_Buffer_free(mbuf); 01636 01637 /* finish hash */ 01638 rv=GWEN_MDigest_End(md); 01639 if (rv<0) { 01640 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01641 GWEN_MDigest_free(md); 01642 return rv; 01643 } 01644 01645 /* read and check hash */ 01646 mpos=GWEN_SarFileHeader_GetHashPos(fh); 01647 if (mpos) { 01648 GWEN_BUFFER *mbuf; 01649 01650 /* seek to end of file */ 01651 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, mpos, GWEN_SyncIo_File_Whence_Set); 01652 if (pos<0) { 01653 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01654 GWEN_MDigest_free(md); 01655 return (int) pos; 01656 } 01657 01658 /* read 20 bytes of hash */ 01659 mbuf=GWEN_Buffer_new(0, 20, 0, 1); 01660 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 01661 (uint8_t*) GWEN_Buffer_GetStart(mbuf), 01662 20); 01663 if (rv<0) { 01664 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01665 GWEN_Buffer_free(mbuf); 01666 GWEN_MDigest_free(md); 01667 unlink(fname); 01668 return rv; 01669 } 01670 GWEN_Buffer_IncrementPos(mbuf, 20); 01671 GWEN_Buffer_AdjustUsedBytes(mbuf); 01672 01673 if (memcmp(GWEN_MDigest_GetDigestPtr(md), 01674 GWEN_Buffer_GetStart(mbuf), 01675 20)!=0) { 01676 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01677 GWEN_Buffer_free(mbuf); 01678 GWEN_MDigest_free(md); 01679 unlink(fname); 01680 return GWEN_ERROR_BAD_DATA; 01681 } 01682 01683 GWEN_Buffer_free(mbuf); 01684 } 01685 01686 GWEN_MDigest_free(md); 01687 01688 if (!checkOnly) { 01689 mode_t mode=0; 01690 01691 /* owner perms */ 01692 if (perms & GWEN_SYNCIO_FILE_FLAGS_UREAD) 01693 mode|=S_IRUSR; 01694 if (perms & GWEN_SYNCIO_FILE_FLAGS_UWRITE) 01695 mode|=S_IWUSR; 01696 if (perms & GWEN_SYNCIO_FILE_FLAGS_UEXEC) 01697 mode|=S_IXUSR; 01698 01699 /* group perms */ 01700 #ifdef S_IRGRP 01701 if (perms & GWEN_SYNCIO_FILE_FLAGS_GREAD) mode|=S_IRGRP; 01702 #endif 01703 #ifdef S_IWGRP 01704 if (perms & GWEN_SYNCIO_FILE_FLAGS_GWRITE) mode|=S_IWGRP; 01705 #endif 01706 #ifdef S_IXGRP 01707 if (perms & GWEN_SYNCIO_FILE_FLAGS_GEXEC) mode|=S_IXGRP; 01708 #endif 01709 01710 /* other perms */ 01711 #ifdef S_IROTH 01712 if (perms & GWEN_SYNCIO_FILE_FLAGS_OREAD) mode|=S_IROTH; 01713 #endif 01714 #ifdef S_IWOTH 01715 if (perms & GWEN_SYNCIO_FILE_FLAGS_OWRITE) mode|=S_IWOTH; 01716 #endif 01717 #ifdef S_IXOTH 01718 if (perms & GWEN_SYNCIO_FILE_FLAGS_OEXEC) mode|=S_IXOTH; 01719 #endif 01720 01721 /* create folder */ 01722 #ifndef OS_WIN32 01723 rv=mkdir(fname, mode); 01724 #else 01725 rv=mkdir(fname); 01726 #endif 01727 if (rv) { 01728 DBG_ERROR(GWEN_LOGDOMAIN, "mkdir(%s): %d (%s)", 01729 fname, errno, strerror(errno)); 01730 return GWEN_ERROR_IO; 01731 } 01732 } 01733 01734 return 0; 01735 } 01736 01737 01738 01739 int GWEN_Sar_ExtractAndDigestFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh, int checkOnly) { 01740 int rv; 01741 01742 switch(GWEN_SarFileHeader_GetFileType(fh)) { 01743 case GWEN_SarFileHeader_FType_File: 01744 rv=GWEN_Sar_ExtractAndDigestFileReg(sr, fh, checkOnly); 01745 break; 01746 case GWEN_SarFileHeader_FType_Dir: 01747 rv=GWEN_Sar_ExtractAndDigestFileDir(sr, fh, checkOnly); 01748 break; 01749 case GWEN_SarFileHeader_FType_SymLink: 01750 rv=GWEN_Sar_ExtractAndDigestFileLink(sr, fh, checkOnly); 01751 break; 01752 default: 01753 DBG_ERROR(GWEN_LOGDOMAIN, "File type %d not supported", GWEN_SarFileHeader_GetFileType(fh)); 01754 return GWEN_ERROR_INVALID; 01755 } 01756 01757 if (rv<0) { 01758 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01759 return rv; 01760 } 01761 01762 return 0; 01763 } 01764 01765 01766 01767 int GWEN_Sar_ExtractFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh) { 01768 int rv; 01769 01770 rv=GWEN_Sar_ExtractAndDigestFile(sr, fh, 0); 01771 if (rv<0) { 01772 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01773 return rv; 01774 } 01775 01776 return rv; 01777 } 01778 01779 01780 01781 int GWEN_Sar_CheckFile(GWEN_SAR *sr, const GWEN_SAR_FILEHEADER *fh) { 01782 int rv; 01783 01784 rv=GWEN_Sar_ExtractAndDigestFile(sr, fh, 1); 01785 if (rv<0) { 01786 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01787 return rv; 01788 } 01789 01790 return rv; 01791 } 01792 01793 01794 01795 const GWEN_SAR_FILEHEADER_LIST *GWEN_Sar_GetHeaders(GWEN_SAR *sr) { 01796 assert(sr); 01797 assert(sr->refCount); 01798 return sr->headers; 01799 } 01800 01801 01802 01803 int GWEN_Sar__UnpackArchive(const char *inFile, const char *where) { 01804 GWEN_SAR *sr; 01805 int rv; 01806 const GWEN_SAR_FILEHEADER_LIST *fhl; 01807 01808 /* open archive file */ 01809 sr=GWEN_Sar_new(); 01810 rv=GWEN_Sar_OpenArchive(sr, inFile, 01811 GWEN_SyncIo_File_CreationMode_OpenExisting, 01812 GWEN_SYNCIO_FILE_FLAGS_READ); 01813 if (rv<0) { 01814 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01815 return rv; 01816 } 01817 01818 /* change to "where" */ 01819 if (chdir(where)) { 01820 DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", where, strerror(errno)); 01821 GWEN_Sar_CloseArchive(sr, 1); 01822 GWEN_Sar_free(sr); 01823 return GWEN_ERROR_IO; 01824 } 01825 01826 fhl=GWEN_Sar_GetHeaders(sr); 01827 if (fhl) { 01828 const GWEN_SAR_FILEHEADER *fh; 01829 uint32_t pid; 01830 01831 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 01832 GWEN_GUI_PROGRESS_SHOW_ABORT | 01833 GWEN_GUI_PROGRESS_ALLOW_EMBED | 01834 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 01835 I18N("File Operation"), 01836 I18N("Unpacking archive file"), 01837 GWEN_SarFileHeader_List_GetCount(fhl), 01838 0); 01839 01840 fh=GWEN_SarFileHeader_List_First(fhl); 01841 while(fh) { 01842 const char *s; 01843 01844 s=GWEN_SarFileHeader_GetPath(fh); 01845 rv=GWEN_Sar_ExtractFile(sr, fh); 01846 if (rv<0) { 01847 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01848 GWEN_Gui_ProgressEnd(pid); 01849 GWEN_Sar_CloseArchive(sr, 1); 01850 GWEN_Sar_free(sr); 01851 } 01852 01853 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE); 01854 if (rv<0) { 01855 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01856 GWEN_Gui_ProgressEnd(pid); 01857 GWEN_Sar_CloseArchive(sr, 1); 01858 GWEN_Sar_free(sr); 01859 return rv; 01860 } 01861 01862 fh=GWEN_SarFileHeader_List_Next(fh); 01863 } 01864 GWEN_Gui_ProgressEnd(pid); 01865 } 01866 01867 rv=GWEN_Sar_CloseArchive(sr, 0); 01868 if (rv<0) { 01869 fprintf(stderr, "Error closing archive (%d)\n", rv); 01870 return 2; 01871 } 01872 01873 return 0; 01874 } 01875 01876 01877 01878 int GWEN_Sar_UnpackArchive(const char *inFile, const char *where) { 01879 char savedPwd[300]; 01880 int rv; 01881 01882 /* get current working dir */ 01883 if (getcwd(savedPwd, sizeof(savedPwd)-1)==NULL) { 01884 DBG_ERROR(GWEN_LOGDOMAIN, "getcwd(): %s", strerror(errno)); 01885 return GWEN_ERROR_IO; 01886 } 01887 savedPwd[sizeof(savedPwd)-1]=0; 01888 01889 rv=GWEN_Sar__UnpackArchive(inFile, where); 01890 if (rv<0) { 01891 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01892 } 01893 01894 /* change back to previous pwd */ 01895 if (chdir(savedPwd)) { 01896 DBG_ERROR(GWEN_LOGDOMAIN, "chdir(%s): %s", savedPwd, strerror(errno)); 01897 return GWEN_ERROR_IO; 01898 } 01899 01900 return rv; 01901 } 01902 01903 01904 01905 int GWEN_Sar_Sign(GWEN_SAR *sr, GWEN_CRYPTMGR *cm) { 01906 int rv; 01907 GWEN_SAR_FILEHEADER_LIST *fhl; 01908 01909 assert(sr); 01910 assert(sr->refCount); 01911 01912 if (sr->openMode!=GWEN_Sar_OpenMode_Opened && 01913 sr->openMode!=GWEN_Sar_OpenMode_Created) { 01914 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open"); 01915 return GWEN_ERROR_NOT_OPEN; 01916 } 01917 01918 if (sr->signaturePos!=0 || sr->signatureSize!=0) { 01919 DBG_ERROR(GWEN_LOGDOMAIN, "There already is a signature in the archive file"); 01920 return GWEN_ERROR_INVALID; 01921 } 01922 01923 fhl=sr->headers; 01924 if (fhl) { 01925 GWEN_SAR_FILEHEADER *fh; 01926 uint32_t pid; 01927 GWEN_MDIGEST *md; 01928 uint8_t hashBuf[21]; 01929 GWEN_BUFFER *sbuf; 01930 GWEN_BUFFER *tbuf; 01931 int64_t pos; 01932 01933 md=GWEN_MDigest_Rmd160_new(); 01934 rv=GWEN_MDigest_Begin(md); 01935 if (rv<0) { 01936 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01937 GWEN_MDigest_free(md); 01938 return rv; 01939 } 01940 01941 /* clear SIGNED flags */ 01942 fh=GWEN_SarFileHeader_List_First(fhl); 01943 while(fh) { 01944 GWEN_SarFileHeader_SubFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED); 01945 fh=GWEN_SarFileHeader_List_Next(fh); 01946 } 01947 01948 /* calculate hash over all file hashes */ 01949 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 01950 GWEN_GUI_PROGRESS_SHOW_ABORT | 01951 GWEN_GUI_PROGRESS_ALLOW_EMBED | 01952 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 01953 I18N("File Operation"), 01954 I18N("Signing archive file"), 01955 GWEN_SarFileHeader_List_GetCount(fhl), 01956 0); 01957 fh=GWEN_SarFileHeader_List_First(fhl); 01958 while(fh) { 01959 const char *s; 01960 uint64_t hpos; 01961 01962 s=GWEN_SarFileHeader_GetPath(fh); 01963 hpos=GWEN_SarFileHeader_GetHashPos(fh); 01964 if (hpos==0) { 01965 DBG_WARN(GWEN_LOGDOMAIN, "File %s has no valid hash", s?s:"(unnamed)"); 01966 } 01967 else { 01968 /* seek to start of hash */ 01969 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set); 01970 if (pos<0) { 01971 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 01972 GWEN_Gui_ProgressEnd(pid); 01973 GWEN_MDigest_free(md); 01974 return (int) pos; 01975 } 01976 01977 /* read hash */ 01978 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, hashBuf, 20); 01979 if (rv<0) { 01980 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01981 GWEN_Gui_ProgressEnd(pid); 01982 GWEN_MDigest_free(md); 01983 return rv; 01984 } 01985 01986 /* digest hash */ 01987 rv=GWEN_MDigest_Update(md, hashBuf, 20); 01988 if (rv<0) { 01989 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 01990 GWEN_Gui_ProgressEnd(pid); 01991 GWEN_MDigest_free(md); 01992 return rv; 01993 } 01994 01995 01996 GWEN_SarFileHeader_AddFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED); 01997 } 01998 01999 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE); 02000 if (rv<0) { 02001 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02002 GWEN_Gui_ProgressEnd(pid); 02003 GWEN_MDigest_free(md); 02004 return rv; 02005 } 02006 02007 fh=GWEN_SarFileHeader_List_Next(fh); 02008 } 02009 02010 /* finish hash */ 02011 rv=GWEN_MDigest_End(md); 02012 if (rv<0) { 02013 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02014 GWEN_Gui_ProgressEnd(pid); 02015 GWEN_MDigest_free(md); 02016 return rv; 02017 } 02018 02019 /* sign hash */ 02020 sbuf=GWEN_Buffer_new(0, 256, 0, 1); 02021 rv=GWEN_CryptMgr_Sign(cm, 02022 GWEN_MDigest_GetDigestPtr(md), 02023 GWEN_MDigest_GetDigestSize(md), 02024 sbuf); 02025 if (rv<0) { 02026 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02027 GWEN_Buffer_free(sbuf); 02028 GWEN_Gui_ProgressEnd(pid); 02029 GWEN_MDigest_free(md); 02030 return rv; 02031 } 02032 GWEN_MDigest_free(md); 02033 02034 /* create signature TLV */ 02035 tbuf=GWEN_Buffer_new(0, 256, 0, 1); 02036 rv=GWEN_TLV_DirectlyToBuffer(GWEN_SAR_TAG_SIGNATURE, 0x00, 02037 GWEN_Buffer_GetStart(sbuf), 02038 GWEN_Buffer_GetUsedBytes(sbuf), 02039 1, tbuf); 02040 if (rv<0) { 02041 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02042 GWEN_Buffer_free(tbuf); 02043 GWEN_Buffer_free(sbuf); 02044 GWEN_Gui_ProgressEnd(pid); 02045 return rv; 02046 } 02047 02048 /* seek to end of file */ 02049 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, 0, GWEN_SyncIo_File_Whence_End); 02050 if (pos<0) { 02051 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 02052 GWEN_Buffer_free(tbuf); 02053 GWEN_Buffer_free(sbuf); 02054 GWEN_Gui_ProgressEnd(pid); 02055 return (int) pos; 02056 } 02057 02058 /* write TLV into archive file */ 02059 rv=GWEN_SyncIo_WriteForced(sr->archiveSio, 02060 (const uint8_t*) GWEN_Buffer_GetStart(tbuf), 02061 GWEN_Buffer_GetUsedBytes(tbuf)); 02062 if (rv<0) { 02063 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02064 GWEN_Buffer_free(tbuf); 02065 GWEN_Buffer_free(sbuf); 02066 GWEN_Gui_ProgressEnd(pid); 02067 return rv; 02068 } 02069 02070 02071 GWEN_Buffer_free(tbuf); 02072 GWEN_Buffer_free(sbuf); 02073 02074 GWEN_Gui_ProgressEnd(pid); 02075 } 02076 02077 return 0; 02078 } 02079 02080 02081 02082 int GWEN_Sar_Verify(GWEN_SAR *sr, GWEN_CRYPTMGR *cm) { 02083 int rv; 02084 GWEN_SAR_FILEHEADER_LIST *fhl; 02085 02086 assert(sr); 02087 assert(sr->refCount); 02088 02089 if (sr->openMode!=GWEN_Sar_OpenMode_Opened && 02090 sr->openMode!=GWEN_Sar_OpenMode_Created) { 02091 DBG_ERROR(GWEN_LOGDOMAIN, "Archive not open"); 02092 return GWEN_ERROR_NOT_OPEN; 02093 } 02094 02095 if (sr->signaturePos==0 || sr->signatureSize==0) { 02096 DBG_ERROR(GWEN_LOGDOMAIN, "No valid signature data in the archive file"); 02097 return GWEN_ERROR_INVALID; 02098 } 02099 02100 fhl=sr->headers; 02101 if (fhl) { 02102 GWEN_SAR_FILEHEADER *fh; 02103 uint32_t pid; 02104 GWEN_MDIGEST *md; 02105 uint8_t hashBuf[21]; 02106 GWEN_BUFFER *sbuf; 02107 GWEN_BUFFER *hbuf; 02108 int64_t pos; 02109 02110 md=GWEN_MDigest_Rmd160_new(); 02111 rv=GWEN_MDigest_Begin(md); 02112 if (rv<0) { 02113 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02114 GWEN_MDigest_free(md); 02115 return rv; 02116 } 02117 02118 /* clear SIGNED flags */ 02119 fh=GWEN_SarFileHeader_List_First(fhl); 02120 while(fh) { 02121 GWEN_SarFileHeader_SubFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED); 02122 fh=GWEN_SarFileHeader_List_Next(fh); 02123 } 02124 02125 /* calculate hash over all file hashes */ 02126 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 02127 GWEN_GUI_PROGRESS_SHOW_ABORT | 02128 GWEN_GUI_PROGRESS_ALLOW_EMBED | 02129 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 02130 I18N("File Operation"), 02131 I18N("Signing archive file"), 02132 GWEN_SarFileHeader_List_GetCount(fhl), 02133 0); 02134 fh=GWEN_SarFileHeader_List_First(fhl); 02135 while(fh) { 02136 const char *s; 02137 uint64_t hpos; 02138 02139 s=GWEN_SarFileHeader_GetPath(fh); 02140 hpos=GWEN_SarFileHeader_GetHashPos(fh); 02141 if (hpos==0) { 02142 DBG_WARN(GWEN_LOGDOMAIN, "File %s has no valid hash", s?s:"(unnamed)"); 02143 } 02144 else { 02145 /* seek to start of hash */ 02146 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, hpos, GWEN_SyncIo_File_Whence_Set); 02147 if (pos<0) { 02148 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 02149 GWEN_Gui_ProgressEnd(pid); 02150 GWEN_MDigest_free(md); 02151 return (int) pos; 02152 } 02153 02154 /* read hash */ 02155 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, hashBuf, 20); 02156 if (rv<0) { 02157 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02158 GWEN_Gui_ProgressEnd(pid); 02159 GWEN_MDigest_free(md); 02160 return rv; 02161 } 02162 02163 /* digest hash */ 02164 rv=GWEN_MDigest_Update(md, hashBuf, 20); 02165 if (rv<0) { 02166 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02167 GWEN_Gui_ProgressEnd(pid); 02168 GWEN_MDigest_free(md); 02169 return rv; 02170 } 02171 02172 02173 GWEN_SarFileHeader_AddFlags(fh, GWEN_SAR_FILEHEADER_FLAGS_SIGNED); 02174 } 02175 02176 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE); 02177 if (rv<0) { 02178 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02179 GWEN_Gui_ProgressEnd(pid); 02180 GWEN_MDigest_free(md); 02181 return rv; 02182 } 02183 02184 fh=GWEN_SarFileHeader_List_Next(fh); 02185 } 02186 02187 /* finish hash */ 02188 rv=GWEN_MDigest_End(md); 02189 if (rv<0) { 02190 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02191 GWEN_Gui_ProgressEnd(pid); 02192 GWEN_MDigest_free(md); 02193 return rv; 02194 } 02195 02196 /* seek to start of signature data */ 02197 pos=GWEN_SyncIo_File_Seek(sr->archiveSio, sr->signaturePos, GWEN_SyncIo_File_Whence_Set); 02198 if (pos<0) { 02199 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", (int) pos); 02200 GWEN_Gui_ProgressEnd(pid); 02201 GWEN_MDigest_free(md); 02202 return (int) pos; 02203 } 02204 02205 /* read signature data */ 02206 sbuf=GWEN_Buffer_new(0, sr->signatureSize, 0, 1); 02207 rv=GWEN_SyncIo_ReadForced(sr->archiveSio, 02208 (uint8_t*) GWEN_Buffer_GetStart(sbuf), 02209 sr->signatureSize); 02210 if (rv<0) { 02211 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02212 GWEN_Buffer_free(sbuf); 02213 GWEN_Gui_ProgressEnd(pid); 02214 GWEN_MDigest_free(md); 02215 return rv; 02216 } 02217 GWEN_Buffer_IncrementPos(sbuf, sr->signatureSize); 02218 GWEN_Buffer_AdjustUsedBytes(sbuf); 02219 02220 /* verify signature */ 02221 hbuf=GWEN_Buffer_new(0, 256, 0, 1); 02222 rv=GWEN_CryptMgr_Verify(cm, 02223 (const uint8_t*) GWEN_Buffer_GetStart(sbuf), 02224 GWEN_Buffer_GetUsedBytes(sbuf), 02225 hbuf); 02226 if (rv<0) { 02227 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02228 GWEN_Buffer_free(hbuf); 02229 GWEN_Buffer_free(sbuf); 02230 GWEN_Gui_ProgressEnd(pid); 02231 GWEN_MDigest_free(md); 02232 return rv; 02233 } 02234 GWEN_Buffer_free(sbuf); 02235 02236 /* verify hash */ 02237 if (GWEN_Buffer_GetUsedBytes(hbuf)!=20) { 02238 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid size of signed hash (%d)", GWEN_Buffer_GetUsedBytes(hbuf)); 02239 GWEN_Buffer_free(hbuf); 02240 GWEN_Gui_ProgressEnd(pid); 02241 GWEN_MDigest_free(md); 02242 return GWEN_ERROR_BAD_DATA; 02243 } 02244 if (memcmp(GWEN_Buffer_GetStart(hbuf), GWEN_MDigest_GetDigestPtr(md), 20)!=0) { 02245 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid hash, data is invalid!"); 02246 GWEN_Buffer_free(hbuf); 02247 GWEN_Gui_ProgressEnd(pid); 02248 GWEN_MDigest_free(md); 02249 return GWEN_ERROR_VERIFY; 02250 } 02251 DBG_INFO(GWEN_LOGDOMAIN, "Signature is valid"); 02252 02253 GWEN_MDigest_free(md); 02254 GWEN_Buffer_free(hbuf); 02255 02256 GWEN_Gui_ProgressEnd(pid); 02257 } 02258 02259 return 0; 02260 } 02261 02262 02263 02264 int GWEN_Sar_VerifyArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key) { 02265 GWEN_SAR *sr; 02266 int rv; 02267 02268 /* open archive file */ 02269 sr=GWEN_Sar_new(); 02270 rv=GWEN_Sar_OpenArchive(sr, inFile, 02271 GWEN_SyncIo_File_CreationMode_OpenExisting, 02272 GWEN_SYNCIO_FILE_FLAGS_READ); 02273 if (rv<0) { 02274 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02275 GWEN_Sar_free(sr); 02276 return rv; 02277 } 02278 else { 02279 GWEN_CRYPTMGR *cm; 02280 02281 cm=GWEN_CryptMgrKeys_new(NULL, NULL, signer, key, 0); 02282 02283 /* verify */ 02284 rv=GWEN_Sar_Verify(sr, cm); 02285 if (rv<0) { 02286 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02287 GWEN_CryptMgr_free(cm); 02288 GWEN_Sar_CloseArchive(sr, 1); 02289 GWEN_Sar_free(sr); 02290 return rv; 02291 } 02292 GWEN_CryptMgr_free(cm); 02293 02294 /* close archive */ 02295 rv=GWEN_Sar_CloseArchive(sr, 0); 02296 if (rv<0) { 02297 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02298 GWEN_Sar_CloseArchive(sr, 1); 02299 GWEN_Sar_free(sr); 02300 return rv; 02301 } 02302 GWEN_Sar_free(sr); 02303 return 0; 02304 } 02305 } 02306 02307 02308 02309 int GWEN_Sar_SignArchive(const char *inFile, const char *signer, GWEN_CRYPT_KEY *key) { 02310 GWEN_SAR *sr; 02311 int rv; 02312 02313 /* open archive file */ 02314 sr=GWEN_Sar_new(); 02315 rv=GWEN_Sar_OpenArchive(sr, inFile, 02316 GWEN_SyncIo_File_CreationMode_OpenExisting, 02317 GWEN_SYNCIO_FILE_FLAGS_READ); 02318 if (rv<0) { 02319 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02320 GWEN_Sar_free(sr); 02321 return rv; 02322 } 02323 else { 02324 GWEN_CRYPTMGR *cm; 02325 02326 cm=GWEN_CryptMgrKeys_new(NULL, NULL, signer, key, 0); 02327 02328 /* verify */ 02329 rv=GWEN_Sar_Sign(sr, cm); 02330 if (rv<0) { 02331 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02332 GWEN_CryptMgr_free(cm); 02333 GWEN_Sar_CloseArchive(sr, 1); 02334 GWEN_Sar_free(sr); 02335 return rv; 02336 } 02337 GWEN_CryptMgr_free(cm); 02338 02339 /* close archive */ 02340 rv=GWEN_Sar_CloseArchive(sr, 0); 02341 if (rv<0) { 02342 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02343 GWEN_Sar_CloseArchive(sr, 1); 02344 GWEN_Sar_free(sr); 02345 return rv; 02346 } 02347 GWEN_Sar_free(sr); 02348 return 0; 02349 } 02350 } 02351 02352 02353 02354 int GWEN_Sar_CheckArchive(const char *inFile) { 02355 GWEN_SAR *sr; 02356 int rv; 02357 const GWEN_SAR_FILEHEADER_LIST *fhl; 02358 02359 /* open archive file */ 02360 sr=GWEN_Sar_new(); 02361 rv=GWEN_Sar_OpenArchive(sr, inFile, 02362 GWEN_SyncIo_File_CreationMode_OpenExisting, 02363 GWEN_SYNCIO_FILE_FLAGS_READ); 02364 if (rv<0) { 02365 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02366 return rv; 02367 } 02368 02369 fhl=GWEN_Sar_GetHeaders(sr); 02370 if (fhl) { 02371 const GWEN_SAR_FILEHEADER *fh; 02372 uint32_t pid; 02373 02374 pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY | 02375 GWEN_GUI_PROGRESS_SHOW_ABORT | 02376 GWEN_GUI_PROGRESS_ALLOW_EMBED | 02377 GWEN_GUI_PROGRESS_SHOW_PROGRESS, 02378 I18N("File Operation"), 02379 I18N("Checking archive file"), 02380 GWEN_SarFileHeader_List_GetCount(fhl), 02381 0); 02382 02383 fh=GWEN_SarFileHeader_List_First(fhl); 02384 while(fh) { 02385 const char *s; 02386 02387 s=GWEN_SarFileHeader_GetPath(fh); 02388 rv=GWEN_Sar_CheckFile(sr, fh); 02389 if (rv<0) { 02390 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02391 GWEN_Gui_ProgressEnd(pid); 02392 GWEN_Sar_CloseArchive(sr, 1); 02393 GWEN_Sar_free(sr); 02394 } 02395 02396 rv=GWEN_Gui_ProgressAdvance(pid, GWEN_GUI_PROGRESS_ONE); 02397 if (rv<0) { 02398 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv); 02399 GWEN_Gui_ProgressEnd(pid); 02400 GWEN_Sar_CloseArchive(sr, 1); 02401 GWEN_Sar_free(sr); 02402 return rv; 02403 } 02404 02405 fh=GWEN_SarFileHeader_List_Next(fh); 02406 } 02407 GWEN_Gui_ProgressEnd(pid); 02408 } 02409 02410 rv=GWEN_Sar_CloseArchive(sr, 0); 02411 if (rv<0) { 02412 fprintf(stderr, "Error closing archive (%d)\n", rv); 02413 return 2; 02414 } 02415 GWEN_Sar_free(sr); 02416 02417 return 0; 02418 } 02419 02420 02421