rpm
4.5
|
00001 #ifndef H_RPMIO_INTERNAL 00002 #define H_RPMIO_INTERNAL 00003 00009 #include <rpmio.h> 00010 #include <rpmurl.h> 00011 00012 #if USE_INTERNAL_BEECRYPT 00013 #if HAVE_BEECRYPT_API_H 00014 #include <api.h> 00015 #else 00016 #include <beecrypt.api.h> 00017 #endif 00018 #else /* use system beecrypt */ 00019 #if HAVE_BEECRYPT_API_H 00020 #include <beecrypt/api.h> 00021 #else 00022 #include <beecrypt/beecrypt.api.h> 00023 #endif 00024 #endif 00025 00026 #include <rpmpgp.h> 00027 #include <rpmsw.h> 00028 00029 /* Drag in the beecrypt includes. */ 00030 #if USE_INTERNAL_BEECRYPT 00031 #include <beecrypt.h> 00032 #include <base64.h> 00033 #include <dsa.h> 00034 #include <endianness.h> 00035 #include <md5.h> 00036 #include <mp.h> 00037 #include <rsa.h> 00038 #include <rsapk.h> 00039 #include <sha1.h> 00040 #if HAVE_BEECRYPT_API_H 00041 #include <sha256.h> 00042 #include <sha384.h> 00043 #include <sha512.h> 00044 #endif 00045 #else /* use system beecrypt */ 00046 #include <beecrypt/beecrypt.h> 00047 #include <beecrypt/base64.h> 00048 #include <beecrypt/dsa.h> 00049 #include <beecrypt/endianness.h> 00050 #include <beecrypt/md5.h> 00051 #include <beecrypt/mp.h> 00052 #include <beecrypt/rsa.h> 00053 #include <beecrypt/rsapk.h> 00054 #include <beecrypt/sha1.h> 00055 #if HAVE_BEECRYPT_API_H 00056 #include <beecrypt/sha256.h> 00057 #include <beecrypt/sha384.h> 00058 #include <beecrypt/sha512.h> 00059 #endif 00060 #endif 00061 00065 struct pgpDigParams_s { 00066 /*@only@*/ /*@null@*/ 00067 const char * userid; 00068 /*@only@*/ /*@null@*/ 00069 const byte * hash; 00070 const char * params[4]; 00071 byte tag; 00072 00073 byte version; 00074 byte time[4]; 00075 byte pubkey_algo; 00077 byte hash_algo; 00078 byte sigtype; 00079 byte hashlen; 00080 byte signhash16[2]; 00081 byte signid[8]; 00082 byte saved; 00083 #define PGPDIG_SAVED_TIME (1 << 0) 00084 #define PGPDIG_SAVED_ID (1 << 1) 00085 00086 }; 00087 00091 struct pgpDig_s { 00092 struct pgpDigParams_s signature; 00093 struct pgpDigParams_s pubkey; 00094 00095 byte ** ppkts; 00096 int npkts; 00097 size_t nbytes; 00099 /*@only@*/ /*@null@*/ 00100 DIGEST_CTX sha1ctx; 00101 /*@only@*/ /*@null@*/ 00102 DIGEST_CTX hdrsha1ctx; 00103 /*@only@*/ /*@null@*/ 00104 void * sha1; 00105 size_t sha1len; 00107 /*@only@*/ /*@null@*/ 00108 DIGEST_CTX md5ctx; 00109 /*@only@*/ /*@null@*/ 00110 DIGEST_CTX hdrmd5ctx; 00111 /*@only@*/ /*@null@*/ 00112 void * md5; 00113 size_t md5len; 00115 /* DSA parameters. */ 00116 mpbarrett p; 00117 mpbarrett q; 00118 mpnumber g; 00119 mpnumber y; 00120 mpnumber hm; 00121 mpnumber r; 00122 mpnumber s; 00123 00124 /* RSA parameters. */ 00125 rsapk rsa_pk; 00126 mpnumber m; 00127 mpnumber c; 00128 mpnumber rsahm; 00129 }; 00130 00133 typedef struct _FDSTACK_s { 00134 /*@exposed@*/ 00135 FDIO_t io; 00136 /*@dependent@*/ 00137 void * fp; 00138 int fdno; 00139 } FDSTACK_t; 00140 00144 typedef enum fdOpX_e { 00145 FDSTAT_READ = 0, 00146 FDSTAT_WRITE = 1, 00147 FDSTAT_SEEK = 2, 00148 FDSTAT_CLOSE = 3, 00149 FDSTAT_DIGEST = 4, 00150 FDSTAT_MAX = 5 00151 } fdOpX; 00152 00156 typedef /*@abstract@*/ struct { 00157 struct rpmop_s ops[FDSTAT_MAX]; 00158 } * FDSTAT_t; 00159 00162 typedef struct _FDDIGEST_s { 00163 pgpHashAlgo hashalgo; 00164 DIGEST_CTX hashctx; 00165 } * FDDIGEST_t; 00166 00170 struct _FD_s { 00171 /*@refs@*/ 00172 int nrefs; 00173 int flags; 00174 #define RPMIO_DEBUG_IO 0x40000000 00175 #define RPMIO_DEBUG_REFS 0x20000000 00176 int magic; 00177 #define FDMAGIC 0x04463138 00178 int nfps; 00179 FDSTACK_t fps[8]; 00180 int urlType; /* ufdio: */ 00181 00182 /*@dependent@*/ 00183 void * url; /* ufdio: URL info */ 00184 /*@relnull@*/ 00185 00186 int rd_timeoutsecs; /* ufdRead: per FD_t timer */ 00187 ssize_t bytesRemain; /* ufdio: */ 00188 ssize_t contentLength; /* ufdio: */ 00189 int persist; /* ufdio: */ 00190 int wr_chunked; /* ufdio: */ 00191 00192 int syserrno; /* last system errno encountered */ 00193 /*@observer@*/ 00194 const void *errcookie; /* gzdio/bzdio/ufdio: */ 00195 00196 /*null@*/ 00197 const char *opath; /* open(2) args. */ 00198 int oflags; 00199 mode_t omode; 00200 00201 FDSTAT_t stats; /* I/O statistics */ 00202 00203 int ndigests; 00204 #define FDDIGEST_MAX 32 00205 struct _FDDIGEST_s digests[FDDIGEST_MAX]; 00206 00207 int ftpFileDoneNeeded; /* ufdio: (FTP) */ 00208 unsigned long long fd_cpioPos; /* cpio: */ 00209 }; 00210 /*@access FD_t@*/ 00211 00212 #define FDSANE(fd) assert(fd && fd->magic == FDMAGIC) 00213 00214 /*@-redecl@*/ 00215 /*@unchecked@*/ 00216 extern int _rpmio_debug; 00217 /*@=redecl@*/ 00218 00219 /*@-redecl@*/ 00220 /*@unchecked@*/ 00221 extern int _av_debug; 00222 /*@=redecl@*/ 00223 00224 /*@-redecl@*/ 00225 /*@unchecked@*/ 00226 extern int _ftp_debug; 00227 /*@=redecl@*/ 00228 00229 /*@-redecl@*/ 00230 /*@unchecked@*/ 00231 extern int _dav_debug; 00232 /*@=redecl@*/ 00233 00234 #define DBG(_f, _m, _x) \ 00235 /*@-modfilesys@*/ \ 00236 if ((_rpmio_debug | ((_f) ? ((FD_t)(_f))->flags : 0)) & (_m)) fprintf _x \ 00237 /*@=modfilesys@*/ 00238 00239 #if defined(__LCLINT__XXX) 00240 #define DBGIO(_f, _x) 00241 #define DBGREFS(_f, _x) 00242 #else 00243 #define DBGIO(_f, _x) DBG((_f), RPMIO_DEBUG_IO, _x) 00244 #define DBGREFS(_f, _x) DBG((_f), RPMIO_DEBUG_REFS, _x) 00245 #endif 00246 00247 #ifdef __cplusplus 00248 extern "C" { 00249 #endif 00250 00253 /*@observer@*/ const char * fdbg(/*@null@*/ FD_t fd) 00254 /*@*/; 00255 00258 int fdFgets(FD_t fd, char * buf, size_t len) 00259 /*@globals errno, fileSystem @*/ 00260 /*@modifies *buf, fd, errno, fileSystem @*/; 00261 00264 /*@null@*/ FD_t ftpOpen(const char *url, /*@unused@*/ int flags, 00265 /*@unused@*/ mode_t mode, /*@out@*/ urlinfo *uret) 00266 /*@globals h_errno, fileSystem, internalState @*/ 00267 /*@modifies *uret, fileSystem, internalState @*/; 00268 00271 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg) 00272 /*@globals fileSystem, internalState @*/ 00273 /*@modifies data, fileSystem, internalState @*/; 00274 00277 int ftpCmd(const char * cmd, const char * url, const char * arg2) 00278 /*@globals h_errno, fileSystem, internalState @*/ 00279 /*@modifies fileSystem, internalState @*/; 00280 00283 int ufdClose( /*@only@*/ void * cookie) 00284 /*@globals fileSystem, internalState @*/ 00285 /*@modifies cookie, fileSystem, internalState @*/; 00286 00289 /*@unused@*/ static inline 00290 void fdSetOpen(FD_t fd, const char * path, int flags, mode_t mode) 00291 /*@modifies fd @*/ 00292 { 00293 FDSANE(fd); 00294 if (fd->opath != NULL) { 00295 free((void *)fd->opath); 00296 fd->opath = NULL; 00297 } 00298 fd->opath = xstrdup(path); 00299 fd->oflags = flags; 00300 fd->omode = mode; 00301 } 00302 00305 /*@unused@*/ static inline 00306 /*@null@*/ /*@observer@*/ const char * fdGetOPath(FD_t fd) 00307 /*@*/ 00308 { 00309 FDSANE(fd); 00310 return fd->opath; 00311 } 00312 00315 /*@unused@*/ static inline 00316 int fdGetOFlags(FD_t fd) 00317 /*@*/ 00318 { 00319 FDSANE(fd); 00320 return fd->oflags; 00321 } 00322 00325 /*@unused@*/ static inline 00326 mode_t fdGetOMode(FD_t fd) 00327 /*@*/ 00328 { 00329 FDSANE(fd); 00330 return fd->omode; 00331 } 00332 00335 /*@unused@*/ static inline 00336 /*@null@*/ FDIO_t fdGetIo(FD_t fd) 00337 /*@*/ 00338 { 00339 FDSANE(fd); 00340 /*@-boundsread@*/ 00341 return fd->fps[fd->nfps].io; 00342 /*@=boundsread@*/ 00343 } 00344 00347 /*@-nullstate@*/ /* FIX: io may be NULL */ 00348 /*@unused@*/ static inline 00349 void fdSetIo(FD_t fd, /*@kept@*/ /*@null@*/ FDIO_t io) 00350 /*@modifies fd @*/ 00351 { 00352 FDSANE(fd); 00353 /*@-boundswrite@*/ 00354 /*@-assignexpose@*/ 00355 fd->fps[fd->nfps].io = io; 00356 /*@=assignexpose@*/ 00357 /*@=boundswrite@*/ 00358 } 00359 /*@=nullstate@*/ 00360 00363 /*@unused@*/ static inline 00364 /*@exposed@*/ /*@dependent@*/ /*@null@*/ FILE * fdGetFILE(FD_t fd) 00365 /*@*/ 00366 { 00367 FDSANE(fd); 00368 /*@-boundsread@*/ 00369 /*@+voidabstract@*/ 00370 return ((FILE *)fd->fps[fd->nfps].fp); 00371 /*@=voidabstract@*/ 00372 /*@=boundsread@*/ 00373 } 00374 00377 /*@unused@*/ static inline 00378 /*@exposed@*/ /*@dependent@*/ /*@null@*/ void * fdGetFp(FD_t fd) 00379 /*@*/ 00380 { 00381 FDSANE(fd); 00382 /*@-boundsread@*/ 00383 return fd->fps[fd->nfps].fp; 00384 /*@=boundsread@*/ 00385 } 00386 00389 /*@-nullstate@*/ /* FIX: fp may be NULL */ 00390 /*@unused@*/ static inline 00391 void fdSetFp(FD_t fd, /*@kept@*/ /*@null@*/ void * fp) 00392 /*@modifies fd @*/ 00393 { 00394 FDSANE(fd); 00395 /*@-boundswrite@*/ 00396 /*@-assignexpose@*/ 00397 fd->fps[fd->nfps].fp = fp; 00398 /*@=assignexpose@*/ 00399 /*@=boundswrite@*/ 00400 } 00401 /*@=nullstate@*/ 00402 00405 /*@unused@*/ static inline 00406 int fdGetFdno(FD_t fd) 00407 /*@*/ 00408 { 00409 FDSANE(fd); 00410 /*@-boundsread@*/ 00411 return fd->fps[fd->nfps].fdno; 00412 /*@=boundsread@*/ 00413 } 00414 00417 /*@unused@*/ static inline 00418 void fdSetFdno(FD_t fd, int fdno) 00419 /*@modifies fd @*/ 00420 { 00421 FDSANE(fd); 00422 /*@-boundswrite@*/ 00423 fd->fps[fd->nfps].fdno = fdno; 00424 /*@=boundswrite@*/ 00425 } 00426 00429 /*@unused@*/ static inline 00430 void fdSetContentLength(FD_t fd, ssize_t contentLength) 00431 /*@modifies fd @*/ 00432 { 00433 FDSANE(fd); 00434 fd->contentLength = fd->bytesRemain = contentLength; 00435 } 00436 00439 /*@unused@*/ static inline 00440 void fdPush(FD_t fd, FDIO_t io, void * fp, int fdno) 00441 /*@modifies fd @*/ 00442 { 00443 FDSANE(fd); 00444 if (fd->nfps >= (sizeof(fd->fps)/sizeof(fd->fps[0]) - 1)) 00445 return; 00446 fd->nfps++; 00447 fdSetIo(fd, io); 00448 fdSetFp(fd, fp); 00449 fdSetFdno(fd, fdno); 00450 } 00451 00454 /*@unused@*/ static inline 00455 void fdPop(FD_t fd) 00456 /*@modifies fd @*/ 00457 { 00458 FDSANE(fd); 00459 if (fd->nfps < 0) return; 00460 fdSetIo(fd, NULL); 00461 fdSetFp(fd, NULL); 00462 fdSetFdno(fd, -1); 00463 fd->nfps--; 00464 } 00465 00468 /*@unused@*/ static inline /*@null@*/ 00469 rpmop fdstat_op(/*@null@*/ FD_t fd, fdOpX opx) 00470 /*@*/ 00471 { 00472 rpmop op = NULL; 00473 00474 /*@-boundsread@*/ 00475 if (fd != NULL && fd->stats != NULL && opx >= 0 && opx < FDSTAT_MAX) 00476 op = fd->stats->ops + opx; 00477 /*@=boundsread@*/ 00478 return op; 00479 } 00480 00483 /*@unused@*/ static inline 00484 void fdstat_enter(/*@null@*/ FD_t fd, int opx) 00485 /*@globals internalState @*/ 00486 /*@modifies internalState @*/ 00487 { 00488 if (fd == NULL) return; 00489 if (fd->stats != NULL) 00490 (void) rpmswEnter(fdstat_op(fd, opx), 0); 00491 } 00492 00495 /*@unused@*/ static inline 00496 void fdstat_exit(/*@null@*/ FD_t fd, int opx, ssize_t rc) 00497 /*@globals internalState @*/ 00498 /*@modifies fd, internalState @*/ 00499 { 00500 if (fd == NULL) return; 00501 if (rc == -1) 00502 fd->syserrno = errno; 00503 else if (rc > 0 && fd->bytesRemain > 0) 00504 switch (opx) { 00505 case FDSTAT_READ: 00506 case FDSTAT_WRITE: 00507 fd->bytesRemain -= rc; 00508 break; 00509 default: 00510 break; 00511 } 00512 if (fd->stats != NULL) 00513 (void) rpmswExit(fdstat_op(fd, opx), rc); 00514 } 00515 00518 /*@-boundsread@*/ 00519 /*@unused@*/ static inline 00520 void fdstat_print(/*@null@*/ FD_t fd, const char * msg, FILE * fp) 00521 /*@globals fileSystem @*/ 00522 /*@modifies *fp, fileSystem @*/ 00523 { 00524 static int usec_scale = (1000*1000); 00525 int opx; 00526 00527 if (fd == NULL || fd->stats == NULL) return; 00528 for (opx = 0; opx < 4; opx++) { 00529 rpmop op = &fd->stats->ops[opx]; 00530 if (op->count <= 0) continue; 00531 switch (opx) { 00532 case FDSTAT_READ: 00533 if (msg) fprintf(fp, "%s:", msg); 00534 fprintf(fp, "%8d reads, %8lu total bytes in %d.%06d secs\n", 00535 op->count, (unsigned long)op->bytes, 00536 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale)); 00537 /*@switchbreak@*/ break; 00538 case FDSTAT_WRITE: 00539 if (msg) fprintf(fp, "%s:", msg); 00540 fprintf(fp, "%8d writes, %8lu total bytes in %d.%06d secs\n", 00541 op->count, (unsigned long)op->bytes, 00542 (int)(op->usecs/usec_scale), (int)(op->usecs%usec_scale)); 00543 /*@switchbreak@*/ break; 00544 case FDSTAT_SEEK: 00545 /*@switchbreak@*/ break; 00546 case FDSTAT_CLOSE: 00547 /*@switchbreak@*/ break; 00548 } 00549 } 00550 } 00551 /*@=boundsread@*/ 00552 00555 /*@unused@*/ static inline 00556 void fdSetSyserrno(FD_t fd, int syserrno, /*@kept@*/ const void * errcookie) 00557 /*@modifies fd @*/ 00558 { 00559 FDSANE(fd); 00560 fd->syserrno = syserrno; 00561 /*@-assignexpose@*/ 00562 fd->errcookie = errcookie; 00563 /*@=assignexpose@*/ 00564 } 00565 00568 /*@unused@*/ static inline 00569 int fdGetRdTimeoutSecs(FD_t fd) 00570 /*@*/ 00571 { 00572 FDSANE(fd); 00573 return fd->rd_timeoutsecs; 00574 } 00575 00578 /*@unused@*/ static inline 00579 unsigned long long fdGetCpioPos(FD_t fd) 00580 /*@*/ 00581 { 00582 FDSANE(fd); 00583 return fd->fd_cpioPos; 00584 } 00585 00588 /*@unused@*/ static inline 00589 void fdSetCpioPos(FD_t fd, long int cpioPos) 00590 /*@modifies fd @*/ 00591 { 00592 FDSANE(fd); 00593 fd->fd_cpioPos = cpioPos; 00594 } 00595 00598 /*@mayexit@*/ /*@unused@*/ static inline 00599 FD_t c2f(/*@null@*/ void * cookie) 00600 /*@*/ 00601 { 00602 /*@-castexpose@*/ 00603 FD_t fd = (FD_t) cookie; 00604 /*@=castexpose@*/ 00605 FDSANE(fd); 00606 /*@-refcounttrans -retalias@*/ return fd; /*@=refcounttrans =retalias@*/ 00607 } 00608 00612 /*@unused@*/ static inline 00613 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags) 00614 /*@globals internalState @*/ 00615 /*@modifies fd, internalState @*/ 00616 { 00617 FDDIGEST_t fddig = fd->digests + fd->ndigests; 00618 if (fddig != (fd->digests + FDDIGEST_MAX)) { 00619 fd->ndigests++; 00620 fddig->hashalgo = hashalgo; 00621 fdstat_enter(fd, FDSTAT_DIGEST); 00622 fddig->hashctx = rpmDigestInit(hashalgo, flags); 00623 fdstat_exit(fd, FDSTAT_DIGEST, 0); 00624 } 00625 } 00626 00630 /*@unused@*/ static inline 00631 void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen) 00632 /*@globals internalState @*/ 00633 /*@modifies fd, internalState @*/ 00634 { 00635 int i; 00636 00637 if (buf != NULL && buflen > 0) 00638 for (i = fd->ndigests - 1; i >= 0; i--) { 00639 FDDIGEST_t fddig = fd->digests + i; 00640 if (fddig->hashctx == NULL) 00641 continue; 00642 fdstat_enter(fd, FDSTAT_DIGEST); 00643 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen); 00644 fdstat_exit(fd, FDSTAT_DIGEST, buflen); 00645 } 00646 } 00647 00650 /*@unused@*/ static inline 00651 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo, 00652 /*@null@*/ /*@out@*/ void * datap, 00653 /*@null@*/ /*@out@*/ size_t * lenp, 00654 int asAscii) 00655 /*@globals internalState @*/ 00656 /*@modifies fd, *datap, *lenp, internalState @*/ 00657 { 00658 int imax = -1; 00659 int i; 00660 00661 for (i = fd->ndigests - 1; i >= 0; i--) { 00662 FDDIGEST_t fddig = fd->digests + i; 00663 if (fddig->hashctx == NULL) 00664 continue; 00665 if (i > imax) imax = i; 00666 if (fddig->hashalgo != hashalgo) 00667 continue; 00668 fdstat_enter(fd, FDSTAT_DIGEST); 00669 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii); 00670 fdstat_exit(fd, FDSTAT_DIGEST, 0); 00671 fddig->hashctx = NULL; 00672 break; 00673 } 00674 /*@-boundswrite@*/ 00675 if (i < 0) { 00676 if (datap) *(void **)datap = NULL; 00677 if (lenp) *lenp = 0; 00678 } 00679 /*@=boundswrite@*/ 00680 00681 fd->ndigests = imax; 00682 if (i < imax) 00683 fd->ndigests++; /* convert index to count */ 00684 } 00685 00686 /*@-shadow@*/ 00689 /*@unused@*/ static inline 00690 int fdFileno(/*@null@*/ void * cookie) 00691 /*@*/ 00692 { 00693 FD_t fd; 00694 if (cookie == NULL) return -2; 00695 fd = c2f(cookie); 00696 /*@-boundsread@*/ 00697 return fd->fps[0].fdno; 00698 /*@=boundsread@*/ 00699 } 00700 /*@=shadow@*/ 00701 00709 int rpmioSlurp(const char * fn, 00710 /*@out@*/ const unsigned char ** bp, /*@out@*/ ssize_t * blenp) 00711 /*@globals h_errno, fileSystem, internalState @*/ 00712 /*@modifies *bp, *blenp, fileSystem, internalState @*/; 00713 00714 #ifdef __cplusplus 00715 } 00716 #endif 00717 00718 #endif /* H_RPMIO_INTERNAL */