static void pkgFini(void * _pkg) /*@modifies _pkg @*/ { Package pkg = _pkg; if (pkg == NULL) return; /* XXX assert? */ pkg->preInFile = _free(pkg->preInFile); pkg->postInFile = _free(pkg->postInFile); pkg->preUnFile = _free(pkg->preUnFile); pkg->postUnFile = _free(pkg->postUnFile); pkg->verifyFile = _free(pkg->verifyFile); pkg->sanityCheckFile = _free(pkg->sanityCheckFile); (void)headerFree(pkg->header); pkg->header = NULL; (void)rpmdsFree(pkg->ds); pkg->ds = NULL; pkg->fileList = rpmiobFree(pkg->fileList); pkg->fileFile = _free(pkg->fileFile); if (pkg->fi != NULL) { rpmfi fi = pkg->fi; pkg->fi = NULL; fi = rpmfiFree(fi); } pkg->specialDoc = rpmiobFree(pkg->specialDoc); pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles); }
static int rpm_slurp(lua_State *L) /*@globals fileSystem, internalState @*/ /*@modifies L, fileSystem, internalState @*/ { rpmiob iob = NULL; const char *fn; int rc; if (lua_isstring(L, 1)) fn = lua_tostring(L, 1); else { (void)luaL_argerror(L, 1, "filename"); return 0; } /*@-globs@*/ rc = rpmiobSlurp(fn, &iob); /*@=globs@*/ if (rc || iob == NULL) { (void)luaL_error(L, "failed to slurp data"); return 0; } lua_pushlstring(L, (const char *)rpmiobStr(iob), rpmiobLen(iob)); iob = rpmiobFree(iob); return 1; }
static const char * rpmcliEvalSlurp(const char * arg) /*@globals rpmGlobalMacroContext @*/ /*@modifies rpmGlobalMacroContext @*/ { const char * pre = ""; const char * post = ""; rpmiob iob = NULL; const char * val = NULL; struct stat sb; int xx; if (!strcmp(arg, "-")) { /* Macros from stdin arg. */ xx = rpmiobSlurp(arg, &iob); } else if ((arg[0] == '/' || strchr(arg, ' ') == NULL) && !Stat(arg, &sb) && S_ISREG(sb.st_mode)) { /* Macros from a file arg. */ xx = rpmiobSlurp(arg, &iob); } else { /* Macros from string arg. */ iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0); } val = rpmExpand(pre, iob->b, post, NULL); iob = rpmiobFree(iob); return val; }
rpmRC rpmkuFindPubkey(pgpDigParams sigp, /*@out@*/ rpmiob * iobp) { if (iobp != NULL) *iobp = NULL; #if defined(HAVE_KEYUTILS_H) if (_kuCache) { /*@observer@*/ static const char krprefix[] = "rpm:gpg:pubkey:"; key_serial_t keyring = (key_serial_t) _kuKeyring; char krfp[32]; char * krn = (char *) alloca(strlen(krprefix) + sizeof("12345678")); long key; int xx; (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4)); krfp[sizeof(krfp)-1] = '\0'; *krn = '\0'; (void) stpcpy( stpcpy(krn, krprefix), krfp); key = keyctl_search(keyring, "user", krn, 0); xx = keyctl_read(key, NULL, 0); if (xx > 0) { rpmiob iob = rpmiobNew(xx); xx = keyctl_read(key, (char *)iob->b, iob->blen); if (xx > 0) { #ifdef NOTYET pubkeysource = xstrdup(krn); _kuCache = 0; /* XXX don't bother caching. */ #endif } else iob = rpmiobFree(iob); if (iob != NULL && iobp != NULL) { *iobp = iob; return RPMRC_OK; } else { iob = rpmiobFree(iob); return RPMRC_NOTFOUND; } } else return RPMRC_NOTFOUND; } else #endif /* HAVE_KEYUTILS_H */ return RPMRC_NOTFOUND; }
static void rpmiob_dtor(JSContext *cx, JSObject *obj) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmiobClass, NULL); rpmiob iob = ptr; _DTOR_DEBUG_ENTRY(_debug); if (iob) (void) rpmiobFree(iob); }
int parseChangelog(Spec spec) { rpmParseState nextPart; rpmiob iob = rpmiobNew(0); rpmRC rc; /* There are no options to %changelog */ if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) { iob = rpmiobFree(iob); #if defined(RPM_VENDOR_MANDRIVA) return (spec->clean == NULL) ? PART_CLEAN : PART_NONE; #else return PART_NONE; #endif } if (rc != RPMRC_OK) return rc; while ((nextPart = isPart(spec)) == PART_NONE) { const char * line; line = xstrdup(spec->line); line = xstrtolocale(line); iob = rpmiobAppend(iob, spec->line, 0); line = _free(line); if ((rc = readLine(spec, STRIP_COMMENTS | STRIP_NOEXPAND)) > 0) { #if defined(RPM_VENDOR_MANDRIVA) nextPart = (spec->clean == NULL) ? PART_CLEAN : PART_NONE; #else nextPart = PART_NONE; #endif break; } if (rc != RPMRC_OK) return rc; } rc = addChangelog(spec->packages->header, iob); iob = rpmiobFree(iob); return (rc != RPMRC_OK ? rc : (rpmRC)nextPart); }
static void rpmtclFini(void * _tcl) /*@globals fileSystem @*/ /*@modifies *_tcl, fileSystem @*/ { rpmtcl tcl = (rpmtcl) _tcl; #if defined(WITH_TCL) Tcl_DeleteInterp((Tcl_Interp *)tcl->I); #endif tcl->I = NULL; (void)rpmiobFree(tcl->iob); tcl->iob = NULL; }
static JSBool syck_dump(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { SyckEmitter *emitter = syck_new_emitter(); struct emitter_xtra * bonus = xcalloc(1, sizeof(*bonus)); JSBool ok = JS_FALSE; if (_debug) fprintf(stderr, "==> %s(%p,%p,%p[%u],%p)\n", __FUNCTION__, cx, obj, argv, (unsigned)argc, rval); #ifdef NOTYET ok = JS_ConvertArguments(cx, argc, argv, "", &version, &syck_ns_str, &data); #endif if (!ok) goto exit; bonus->iob = rpmiobNew(0); #ifdef NOTYET bonus->L = lua_newthread(L); luaL_buffinit(L, &bonus->output); #endif emitter->bonus = bonus; syck_emitter_handler(emitter, js_syck_emitter_handler); syck_output_handler(emitter, js_syck_output_handler); #ifdef NOTYET lua_pushvalue(L, -2); lua_xmove(L, bonus->L, 1); #endif bonus->id = 1; js_syck_mark_emitter(emitter, bonus->id); bonus->id = 1; syck_emit(emitter, (st_data_t)((long)bonus->id)); syck_emitter_flush(emitter, 0); #ifdef NOTYET luaL_pushresult(&bonus->output); #endif ok = JS_TRUE; exit: bonus->iob = rpmiobFree(bonus->iob); syck_free_emitter(emitter); return ok; }
rpmRC rpmpythonRunFile(rpmpython python, const char * fn, const char ** resultp) { rpmRC rc = RPMRC_FAIL; if (_rpmpython_debug) fprintf(stderr, "==> %s(%p,%s)\n", __FUNCTION__, python, fn); if (python == NULL) python = rpmpythonI(); if (fn != NULL) { #if defined(WITH_PYTHONEMBED) const char * pyfn = ((fn == NULL || !strcmp(fn, "-")) ? "<stdin>" : fn); FILE * pyfp = (!strcmp(pyfn, "<stdin>") ? stdin : fopen(fn, "rb")); int closeit = (pyfp != stdin); PyCompilerFlags cf = { .cf_flags = 0 }; if (pyfp != NULL) { PyRun_AnyFileExFlags(pyfp, pyfn, closeit, &cf); rc = RPMRC_OK; } #endif } return rc; } static const char * rpmpythonSlurp(const char * arg) /*@*/ { rpmiob iob = NULL; const char * val = NULL; struct stat sb; int xx; if (!strcmp(arg, "-")) { /* Macros from stdin arg. */ xx = rpmiobSlurp(arg, &iob); } else if ((arg[0] == '/' || strchr(arg, ' ') == NULL) && !Stat(arg, &sb) && S_ISREG(sb.st_mode)) { /* Macros from a file arg. */ xx = rpmiobSlurp(arg, &iob); } else { /* Macros from string arg. */ iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0); } val = xstrdup(rpmiobStr(iob)); iob = rpmiobFree(iob); return val; }
rpmRC rpmkuStorePubkey(pgpDigParams sigp, /*@only@*/ rpmiob iob) { #if defined(HAVE_KEYUTILS_H) if (_kuCache) { /*@observer@*/ static const char krprefix[] = "rpm:gpg:pubkey:"; key_serial_t keyring = (key_serial_t) _kuKeyring; char krfp[32]; char * krn = (char *) alloca(strlen(krprefix) + sizeof("12345678")); (void) snprintf(krfp, sizeof(krfp), "%08X", pgpGrab(sigp->signid+4, 4)); krfp[sizeof(krfp)-1] = '\0'; *krn = '\0'; (void) stpcpy( stpcpy(krn, krprefix), krfp); /*@-moduncon -noeffectuncon @*/ (void) add_key("user", krn, iob->b, iob->blen, keyring); /*@=moduncon =noeffectuncon @*/ } #endif /* HAVE_KEYUTILS_H */ iob = rpmiobFree(iob); return RPMRC_OK; }
static void integrity_check(const char *progname, enum modes progmode_num) { rpmts ts = NULL; rpmlua lua = NULL; char *spec_fn = NULL; char *proc_fn = NULL; char *pkey_fn = NULL; char *spec = NULL; char *proc = NULL; rpmiob spec_iob = NULL; rpmiob proc_iob = NULL; const char *result = NULL; const char *error = NULL; int xx; const char *progmode; int rc = INTEGRITY_ERROR; /* determine paths of integrity checking related files */ spec_fn = rpmExpand("%{?_integrity_spec_cfg}%{!?_integrity_spec_cfg:scripts/integrity.cfg}", NULL); if (spec_fn == NULL || spec_fn[0] == '\0') { integrity_check_message("ERROR: Integrity Configuration Specification file not configured.\n" "rpm: HINT: macro %%{_integrity_spec_cfg} not configured correctly.\n"); goto failure; } proc_fn = rpmExpand("%{?_integrity_proc_lua}%{!?_integrity_proc_lua:scripts/integrity.lua}", NULL); if (proc_fn == NULL || proc_fn[0] == '\0') { integrity_check_message("ERROR: Integrity Validation Processor file not configured.\n" "rpm: HINT: macro %%{_integrity_proc_lua} not configured correctly.\n"); goto failure; } pkey_fn = rpmExpand("%{?_integrity_pkey_pgp}%{!?_integrity_pkey_pgp:scripts/integrity.pgp}", NULL); if (pkey_fn == NULL || pkey_fn[0] == '\0') { integrity_check_message("ERROR: Integrity Autority Public-Key file not configured.\n" "rpm: HINT: macro %%{_integrity_pkey_pgp} not configured correctly.\n"); goto failure; } /* create RPM transaction environment and open RPM database */ ts = rpmtsCreate(); (void)rpmtsOpenDB(ts, O_RDONLY); /* check signature on integrity configuration specification file */ if (rpmnsProbeSignature(ts, spec_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) { integrity_check_message("ERROR: Integrity Configuration Specification file contains invalid signature.\n" "rpm: HINT: Check file \"%s\".\n", spec_fn); goto failure; } /* check signature on integrity validation processor file */ if (rpmnsProbeSignature(ts, proc_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) { integrity_check_message("ERROR: Integrity Validation Processor file contains invalid signature.\n" "rpm: HINT: Check file \"%s\".\n", proc_fn); goto failure; } /* load integrity configuration specification file */ xx = rpmiobSlurp(spec_fn, &spec_iob); if (!(xx == 0 && spec_iob != NULL)) { integrity_check_message("ERROR: Unable to load Integrity Configuration Specification file.\n" "rpm: HINT: Check file \"%s\".\n", spec_fn); goto failure; } spec = rpmiobStr(spec_iob); /* load integrity validation processor file */ xx = rpmiobSlurp(proc_fn, &proc_iob); if (!(xx == 0 && proc_iob != NULL)) { integrity_check_message("ERROR: Unable to load Integrity Validation Processor file.\n" "rpm: HINT: Check file \"%s\".\n", proc_fn); goto failure; } proc = rpmiobStr(proc_iob); /* provision program name and mode */ if (progname == NULL || progname[0] == '\0') progname = "rpm"; switch (progmode_num) { case MODE_QUERY: progmode = "query"; break; case MODE_VERIFY: progmode = "verify"; break; case MODE_CHECKSIG: progmode = "checksig"; break; case MODE_RESIGN: progmode = "resign"; break; case MODE_INSTALL: progmode = "install"; break; case MODE_ERASE: progmode = "erase"; break; case MODE_BUILD: progmode = "build"; break; case MODE_REBUILD: progmode = "rebuild"; break; case MODE_RECOMPILE: progmode = "recompile"; break; case MODE_TARBUILD: progmode = "tarbuild"; break; case MODE_REBUILDDB: progmode = "rebuilddb"; break; case MODE_UNKNOWN: progmode = "unknown"; break; default: progmode = "unknown"; break; } /* execute Integrity Validation Processor via Lua glue code */ lua = rpmluaNew(); rpmluaSetPrintBuffer(lua, 1); rpmluaextActivate(lua); lua_getfield(lua->L, LUA_GLOBALSINDEX, "integrity"); lua_getfield(lua->L, -1, "processor"); lua_remove(lua->L, -2); lua_pushstring(lua->L, progname); lua_pushstring(lua->L, progmode); lua_pushstring(lua->L, spec_fn); lua_pushstring(lua->L, spec); lua_pushstring(lua->L, proc_fn); lua_pushstring(lua->L, proc); #ifdef RPM_INTEGRITY_MV lua_pushstring(lua->L, RPM_INTEGRITY_MV); #else lua_pushstring(lua->L, "0"); #endif if (lua_pcall(lua->L, 7, 1, 0) != 0) { error = lua_isstring(lua->L, -1) ? lua_tostring(lua->L, -1) : "unknown error"; lua_pop(lua->L, 1); integrity_check_message("ERROR: Failed to execute Integrity Validation Processor.\n" "rpm: ERROR: Lua: %s.\n" "rpm: HINT: Check file \"%s\".\n", error, proc_fn); goto failure; } /* check Integrity Validation Processor results */ if (!lua_isstring(lua->L, -1)) { integrity_check_message("ERROR: Failed to fetch Integrity Validation Processor results.\n" "rpm: HINT: Check file \"%s\".\n", proc_fn); goto failure; } result = lua_tostring(lua->L, -1); if (strcmp(result, "OK") == 0) rc = INTEGRITY_OK; else if (strncmp(result, "WARNING:", 8) == 0) { rc = INTEGRITY_WARNING; integrity_check_message("%s\n", result); } else { rc = INTEGRITY_ERROR; integrity_check_message("%s\n", result); } /* cleanup processing */ failure: if (lua != NULL) rpmluaFree(lua); if (ts != NULL) (void)rpmtsFree(ts); ts = NULL; if (spec_iob != NULL) spec_iob = rpmiobFree(spec_iob); if (proc_iob != NULL) proc_iob = rpmiobFree(proc_iob); /* final result handling */ if (rc != INTEGRITY_OK) { if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO)) sleep(4); if (rc == INTEGRITY_ERROR) exit(42); } return; }
int parseDescription(Spec spec) /*@globals name, lang @*/ /*@modifies name, lang @*/ { rpmParseState nextPart = (rpmParseState) RPMRC_FAIL; /* assume error */ rpmiob iob = NULL; int flag = PART_SUBNAME; Package pkg; int rc, argc; int arg; const char **argv = NULL; poptContext optCon = NULL; spectag t = NULL; { char * se = strchr(spec->line, '#'); if (se) { *se = '\0'; while (--se >= spec->line && strchr(" \t\n\r", *se) != NULL) *se = '\0'; } } if ((rc = poptParseArgvString(spec->line, &argc, &argv))) { rpmlog(RPMLOG_ERR, _("line %d: Error parsing %%description: %s\n"), spec->lineNum, poptStrerror(rc)); goto exit; } name = NULL; lang = RPMBUILD_DEFAULT_LANG; optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); while ((arg = poptGetNextOpt(optCon)) > 0) {;} if (name != NULL) flag = PART_NAME; if (arg < -1) { rpmlog(RPMLOG_ERR, _("line %d: Bad option %s: %s\n"), spec->lineNum, poptBadOption(optCon, POPT_BADOPTION_NOALIAS), spec->line); goto exit; } if (poptPeekArg(optCon)) { if (name == NULL) name = poptGetArg(optCon); if (poptPeekArg(optCon)) { rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"), spec->lineNum, spec->line); goto exit; } } if (lookupPackage(spec, name, flag, &pkg) != RPMRC_OK) { rpmlog(RPMLOG_ERR, _("line %d: Package does not exist: %s\n"), spec->lineNum, spec->line); goto exit; } /* Lose the inheirited %description (if present). */ if (spec->packages->header != pkg->header) { HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); int xx; he->tag = RPMTAG_DESCRIPTION; xx = headerGet(pkg->header, he, 0); he->p.ptr = _free(he->p.ptr); if (xx && he->t == RPM_STRING_TYPE) xx = headerDel(pkg->header, he, 0); } t = stashSt(spec, pkg->header, RPMTAG_DESCRIPTION, lang); iob = rpmiobNew(0); if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { nextPart = PART_NONE; goto exit; } if (rc < 0) { nextPart = (rpmParseState) RPMRC_FAIL; goto exit; } while ((nextPart = isPart(spec)) == PART_NONE) { iob = rpmiobAppend(iob, spec->line, 1); if (t) t->t_nlines++; if ((rc = readLine(spec, STRIP_TRAILINGSPACE | STRIP_COMMENTS)) > 0) { nextPart = PART_NONE; break; } if (rc) { nextPart = (rpmParseState) RPMRC_FAIL; goto exit; } } iob = rpmiobRTrim(iob); if (!(noLang && strcmp(lang, RPMBUILD_DEFAULT_LANG))) { const char * s = rpmiobStr(iob); (void) headerAddI18NString(pkg->header, RPMTAG_DESCRIPTION, s, lang); } exit: iob = rpmiobFree(iob); argv = _free(argv); optCon = poptFreeContext(optCon); return nextPart; }
/*@-mods@*/ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp) { HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he)); HE_t she = (HE_t) memset(alloca(sizeof(*she)), 0, sizeof(*she)); pgpDig dig = rpmtsDig(ts); char buf[8*BUFSIZ]; ssize_t count; Header sigh = NULL; rpmtsOpX opx; rpmop op = NULL; size_t nb; unsigned ix; Header h = NULL; const char * msg = NULL; rpmVSFlags vsflags; rpmRC rc = RPMRC_FAIL; /* assume failure */ rpmop opsave = (rpmop) memset(alloca(sizeof(*opsave)), 0, sizeof(*opsave)); int xx; pgpPkt pp = (pgpPkt) alloca(sizeof(*pp)); if (hdrp) *hdrp = NULL; assert(dig != NULL); (void) fdSetDig(fd, dig); /* Snapshot current I/O counters (cached persistent I/O reuses counters) */ (void) rpmswAdd(opsave, fdstat_op(fd, FDSTAT_READ)); { const char item[] = "Lead"; msg = NULL; rc = rpmpkgRead(item, fd, NULL, &msg); switch (rc) { default: rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); /*@fallthrough@*/ case RPMRC_NOTFOUND: msg = _free(msg); goto exit; /*@notreached@*/ break; case RPMRC_OK: break; } msg = _free(msg); } { const char item[] = "Signature"; msg = NULL; rc = rpmpkgRead(item, fd, &sigh, &msg); switch (rc) { default: rpmlog(RPMLOG_ERR, "%s: %s: %s", fn, item, (msg && *msg ? msg : _("read failed\n"))); msg = _free(msg); goto exit; /*@notreached@*/ break; case RPMRC_OK: if (sigh == NULL) { rpmlog(RPMLOG_ERR, _("%s: No signature available\n"), fn); rc = RPMRC_FAIL; goto exit; } break; } msg = _free(msg); } #define _chk(_mask) (she->tag == 0 && !(vsflags & (_mask))) /* * Figger the most effective available signature. * Prefer signatures over digests, then header-only over header+payload. * DSA will be preferred over RSA if both exist because tested first. * Note that NEEDPAYLOAD prevents header+payload signatures and digests. */ she->tag = (rpmTag)0; opx = (rpmtsOpX)0; vsflags = pgpDigVSFlags; if (_chk(RPMVSF_NOECDSAHEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_ECDSA)) { she->tag = (rpmTag)RPMSIGTAG_ECDSA; } else if (_chk(RPMVSF_NODSAHEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_DSA)) { she->tag = (rpmTag)RPMSIGTAG_DSA; } else if (_chk(RPMVSF_NORSAHEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_RSA)) { she->tag = (rpmTag)RPMSIGTAG_RSA; } else if (_chk(RPMVSF_NOSHA1HEADER) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_SHA1)) { she->tag = (rpmTag)RPMSIGTAG_SHA1; } else if (_chk(RPMVSF_NOMD5|RPMVSF_NEEDPAYLOAD) && headerIsEntry(sigh, (rpmTag)RPMSIGTAG_MD5)) { she->tag = (rpmTag)RPMSIGTAG_MD5; fdInitDigest(fd, PGPHASHALGO_MD5, 0); opx = RPMTS_OP_DIGEST; } /* Read the metadata, computing digest(s) on the fly. */ h = NULL; msg = NULL; /* XXX stats will include header i/o and setup overhead. */ /* XXX repackaged packages have appended tags, legacy dig/sig check fails */ if (opx > 0) { op = (rpmop) pgpStatsAccumulator(dig, opx); (void) rpmswEnter(op, 0); } /*@-type@*/ /* XXX arrow access of non-pointer (FDSTAT_t) */ nb = fd->stats->ops[FDSTAT_READ].bytes; { const char item[] = "Header"; msg = NULL; rc = rpmpkgRead(item, fd, &h, &msg); if (rc != RPMRC_OK) { rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, item, msg); msg = _free(msg); goto exit; } msg = _free(msg); } nb = fd->stats->ops[FDSTAT_READ].bytes - nb; /*@=type@*/ if (opx > 0 && op != NULL) { (void) rpmswExit(op, nb); op = NULL; } /* Any digests or signatures to check? */ if (she->tag == 0) { rc = RPMRC_OK; goto exit; } dig->nbytes = 0; /* Fish out the autosign pubkey (if present). */ he->tag = RPMTAG_PUBKEYS; xx = headerGet(h, he, 0); if (xx && he->p.argv != NULL && he->c > 0) switch (he->t) { default: break; case RPM_STRING_ARRAY_TYPE: ix = he->c - 1; /* XXX FIXME: assumes last pubkey */ dig->pub = _free(dig->pub); dig->publen = 0; { rpmiob iob = rpmiobNew(0); iob = rpmiobAppend(iob, he->p.argv[ix], 0); xx = pgpArmorUnwrap(iob, (rpmuint8_t **)&dig->pub, &dig->publen); iob = rpmiobFree(iob); } if (xx != PGPARMOR_PUBKEY) { dig->pub = _free(dig->pub); dig->publen = 0; } break; } he->p.ptr = _free(he->p.ptr); /* Retrieve the tag parameters from the signature header. */ xx = headerGet(sigh, she, 0); if (she->p.ptr == NULL) { rc = RPMRC_FAIL; goto exit; } /*@-ownedtrans -noeffect@*/ xx = pgpSetSig(dig, she->tag, she->t, she->p.ptr, she->c); /*@=ownedtrans =noeffect@*/ switch ((rpmSigTag)she->tag) { default: /* XXX keep gcc quiet. */ assert(0); /*@notreached@*/ break; case RPMSIGTAG_RSA: /* Parse the parameters from the OpenPGP packets that will be needed. */ xx = pgpPktLen(she->p.ui8p, she->c, pp); xx = rpmhkpLoadSignature(NULL, dig, pp); if (dig->signature.version != 3 && dig->signature.version != 4) { rpmlog(RPMLOG_ERR, _("skipping package %s with unverifiable V%u signature\n"), fn, dig->signature.version); rc = RPMRC_FAIL; goto exit; } xx = hBlobDigest(h, dig, dig->signature.hash_algo, &dig->hrsa); break; case RPMSIGTAG_DSA: /* Parse the parameters from the OpenPGP packets that will be needed. */ xx = pgpPktLen(she->p.ui8p, she->c, pp); xx = rpmhkpLoadSignature(NULL, dig, pp); if (dig->signature.version != 3 && dig->signature.version != 4) { rpmlog(RPMLOG_ERR, _("skipping package %s with unverifiable V%u signature\n"), fn, dig->signature.version); rc = RPMRC_FAIL; goto exit; } xx = hBlobDigest(h, dig, dig->signature.hash_algo, &dig->hdsa); break; case RPMSIGTAG_ECDSA: /* Parse the parameters from the OpenPGP packets that will be needed. */ xx = pgpPktLen(she->p.ui8p, she->c, pp); xx = rpmhkpLoadSignature(NULL, dig, pp); if (dig->signature.version != 3 && dig->signature.version != 4) { rpmlog(RPMLOG_ERR, _("skipping package %s with unverifiable V%u signature\n"), fn, dig->signature.version); rc = RPMRC_FAIL; goto exit; } xx = hBlobDigest(h, dig, dig->signature.hash_algo, &dig->hecdsa); break; case RPMSIGTAG_SHA1: /* XXX dig->hsha? */ xx = hBlobDigest(h, dig, PGPHASHALGO_SHA1, &dig->hdsa); break; case RPMSIGTAG_MD5: /* Legacy signatures need the compressed payload in the digest too. */ op = (rpmop) pgpStatsAccumulator(dig, 10); /* RPMTS_OP_DIGEST */ (void) rpmswEnter(op, 0); while ((count = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0) dig->nbytes += count; (void) rpmswExit(op, dig->nbytes); op->count--; /* XXX one too many */ dig->nbytes += nb; /* XXX include size of header blob. */ if (count < 0) { rpmlog(RPMLOG_ERR, _("%s: Fread failed: %s\n"), fn, Fstrerror(fd)); rc = RPMRC_FAIL; goto exit; } /* XXX Steal the digest-in-progress from the file handle. */ fdStealDigest(fd, dig); break; } /** @todo Implement disable/enable/warn/error/anal policy. */ buf[0] = '\0'; rc = rpmVerifySignature(dig, buf); switch (rc) { case RPMRC_OK: /* Signature is OK. */ rpmlog(RPMLOG_DEBUG, "%s: %s\n", fn, buf); break; case RPMRC_NOTTRUSTED: /* Signature is OK, but key is not trusted. */ case RPMRC_NOKEY: /* Public key is unavailable. */ #ifndef DYING /* XXX Print NOKEY/NOTTRUSTED warning only once. */ { int lvl = (pgpStashKeyid(dig) ? RPMLOG_DEBUG : RPMLOG_WARNING); rpmlog(lvl, "%s: %s\n", fn, buf); } break; case RPMRC_NOTFOUND: /* Signature is unknown type. */ rpmlog(RPMLOG_WARNING, "%s: %s\n", fn, buf); break; #else case RPMRC_NOTFOUND: /* Signature is unknown type. */ case RPMRC_NOSIG: /* Signature is unavailable. */ #endif default: case RPMRC_FAIL: /* Signature does not verify. */ rpmlog(RPMLOG_ERR, "%s: %s\n", fn, buf); break; } exit: if (rc != RPMRC_FAIL && h != NULL && hdrp != NULL) { /* Append (and remap) signature tags to the metadata. */ headerMergeLegacySigs(h, sigh); /* Bump reference count for return. */ *hdrp = headerLink(h); } (void)headerFree(h); h = NULL; /* Accumulate time reading package header. */ (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_READHDR), fdstat_op(fd, FDSTAT_READ)); (void) rpmswSub(rpmtsOp(ts, RPMTS_OP_READHDR), opsave); #ifdef NOTYET /* Return RPMRC_NOSIG for MANDATORY signature verification. */ { rpmSigTag sigtag = pgpGetSigtag(dig); switch (sigtag) { default: rc = RPMRC_NOSIG; /*@fallthrough@*/ case RPMSIGTAG_RSA: case RPMSIGTAG_DSA: case RPMSIGTAG_ECDSA: break; } } #endif rpmtsCleanDig(ts); (void)headerFree(sigh); sigh = NULL; return rc; }
int parsePrep(Spec spec, int verify) { rpmParseState nextPart; int res, rc; rpmiob iob; ARGV_t saveLines = NULL; ARGV_t lines; const char * cp; int xx; if (spec->prep != NULL) { rpmlog(RPMLOG_ERR, _("line %d: second %%prep\n"), spec->lineNum); return RPMRC_FAIL; } spec->prep = rpmiobNew(0); /* There are no options to %prep */ if ((rc = readLine(spec, STRIP_NOTHING)) > 0) return PART_NONE; if (rc) return rc; /* Check to make sure that all sources/patches are present. */ if (verify) { rc = prepFetch(spec); if (rc) return RPMRC_FAIL; } iob = rpmiobNew(0); while ((nextPart = isPart(spec)) == PART_NONE) { /* Need to expand the macros inline. That way we */ /* can give good line number information on error. */ iob = rpmiobAppend(iob, spec->line, 0); if ((rc = readLine(spec, STRIP_NOTHING)) > 0) { nextPart = PART_NONE; break; } if (rc) return rc; } xx = argvSplit(&saveLines, rpmiobStr(iob), "\n"); /*@-usereleased@*/ for (lines = saveLines; *lines; lines++) { res = 0; for (cp = *lines; *cp == ' ' || *cp == '\t'; cp++) {}; if (!strncmp(cp, "%setup", sizeof("%setup")-1)) { res = doSetupMacro(spec, cp); #ifndef DYING } else if (! strncmp(cp, "%patch", sizeof("%patch")-1)) { res = doPatchMacro(spec, cp); #endif } else { spec->prep = rpmiobAppend(spec->prep, *lines, 1); } if (res && !spec->force) { saveLines = argvFree(saveLines); iob = rpmiobFree(iob); return res; } } /*@=usereleased@*/ saveLines = argvFree(saveLines); iob = rpmiobFree(iob); return nextPart; }
/** * Parse %setup macro. * @todo FIXME: Option -q broken when not immediately after %setup. * @param spec build info * @param line current line from spec file * @return 0 on success */ static int doSetupMacro(Spec spec, const char * line) /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ /*@modifies spec->buildSubdir, spec->macros, spec->prep, spec->packages->header, rpmGlobalMacroContext, fileSystem, internalState @*/ { char buf[BUFSIZ]; rpmiob before = NULL; rpmiob after = NULL; poptContext optCon; int argc; const char ** argv; int arg; const char * optArg; int rc; rpmuint32_t num; rpmRC ec = RPMRC_FAIL; /* XXX assume failure */ /*@-mods@*/ leaveDirs = skipDefaultAction = 0; createDir = quietly = 0; dirName = NULL; /*@=mods@*/ if ((rc = poptParseArgvString(line, &argc, &argv))) { rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"), poptStrerror(rc)); goto exit; } before = rpmiobNew(0); after = rpmiobNew(0); optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); while ((arg = poptGetNextOpt(optCon)) > 0) { optArg = poptGetOptArg(optCon); /* We only parse -a and -b here */ if (parseNum(optArg, &num)) { rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"), spec->lineNum, (optArg ? optArg : "???")); optCon = poptFreeContext(optCon); argv = _free(argv); goto exit; } { const char *chptr = doUntar(spec, num, quietly); if (chptr == NULL) goto exit; (void) rpmiobAppend((arg == 'a' ? after : before), chptr, 1); } } if (arg < -1) { rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"), spec->lineNum, poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(arg)); optCon = poptFreeContext(optCon); argv = _free(argv); goto exit; } if (dirName) { spec->buildSubdir = xstrdup(dirName); } else { const char *N, *V; (void) headerNEVRA(spec->packages->header, &N, NULL, &V, NULL, NULL); (void) snprintf(buf, sizeof(buf), "%s-%s", N, V); buf[sizeof(buf)-1] = '\0'; N = _free(N); V = _free(V); spec->buildSubdir = xstrdup(buf); } addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC); optCon = poptFreeContext(optCon); argv = _free(argv); /* cd to the build dir */ { const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", ""); const char *buildDir; (void) urlPath(buildDirURL, &buildDir); rc = rpmioMkpath(buildDir, 0755, -1, -1); sprintf(buf, "cd '%s'", buildDir); spec->prep = rpmiobAppend(spec->prep, buf, 1); buildDirURL = _free(buildDirURL); } /* delete any old sources */ if (!leaveDirs) { sprintf(buf, "rm -rf '%s'", spec->buildSubdir); spec->prep = rpmiobAppend(spec->prep, buf, 1); } /* check if source is a ruby gem */ { struct Source *sp; for (sp = spec->sources; sp != NULL; sp = sp->next) { if ((sp->flags & RPMFILE_SOURCE) && (sp->num == 0)) { break; } } if (sp != NULL) { char *t = strrchr(sp->source, '.'); if(t && !strcasecmp(t, ".gem")) createDir = 1; } } /* if necessary, create and cd into the proper dir */ if (createDir) { char *mkdir_p; mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL); if (!mkdir_p) mkdir_p = xstrdup("mkdir -p"); sprintf(buf, "%s '%s'\ncd '%s'", mkdir_p, spec->buildSubdir, spec->buildSubdir); mkdir_p = _free(mkdir_p); spec->prep = rpmiobAppend(spec->prep, buf, 1); } /* do the default action */ if (!createDir && !skipDefaultAction) { const char *chptr = doUntar(spec, 0, quietly); if (chptr == NULL) goto exit; spec->prep = rpmiobAppend(spec->prep, chptr, 1); } spec->prep = rpmiobAppend(spec->prep, rpmiobStr(before), 0); if (!createDir) { sprintf(buf, "cd '%s'", spec->buildSubdir); spec->prep = rpmiobAppend(spec->prep, buf, 1); } if (createDir && !skipDefaultAction) { const char * chptr = doUntar(spec, 0, quietly); if (chptr == NULL) goto exit; spec->prep = rpmiobAppend(spec->prep, chptr, 1); } spec->prep = rpmiobAppend(spec->prep, rpmiobStr(after), 0); /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */ /* Fix the owner, group, and permissions of the setup build tree */ { /*@observer@*/ static const char *fixmacs[] = { "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL }; const char ** fm; for (fm = fixmacs; *fm; fm++) { const char *fix; fix = rpmExpand(*fm, " .", NULL); if (fix && *fix != '%') spec->prep = rpmiobAppend(spec->prep, fix, 1); fix = _free(fix); } } ec = RPMRC_OK; exit: before = rpmiobFree(before); after = rpmiobFree(after); return ec; }
static void specFini(void * _spec) /*@modifies _spec @*/ { Spec spec = _spec; struct ReadLevelEntry *rl; if (spec == NULL) return; /* XXX assert? */ spec->lbuf = _free(spec->lbuf); spec->sl = freeSl(spec->sl); spec->st = freeSt(spec->st); spec->prep = rpmiobFree(spec->prep); spec->build = rpmiobFree(spec->build); spec->install = rpmiobFree(spec->install); spec->check = rpmiobFree(spec->check); spec->clean = rpmiobFree(spec->clean); spec->foo = tagStoreFree(spec->foo, spec->nfoo); spec->nfoo = 0; spec->buildSubdir = _free(spec->buildSubdir); spec->rootURL = _free(spec->rootURL); spec->specFile = _free(spec->specFile); closeSpec(spec); while (spec->readStack) { rl = spec->readStack; /*@-dependenttrans@*/ spec->readStack = rl->next; /*@=dependenttrans@*/ rl->next = NULL; rl = _free(rl); } spec->sourceRpmName = _free(spec->sourceRpmName); spec->sourcePkgId = _free(spec->sourcePkgId); spec->sourceHeader = headerFree(spec->sourceHeader); if (spec->fi != NULL) { rpmfi fi = spec->fi; spec->fi = NULL; fi = rpmfiFree(fi); } if (!spec->recursing) { if (spec->BASpecs != NULL) while (spec->BACount--) { /*@-unqualifiedtrans@*/ spec->BASpecs[spec->BACount] = freeSpec(spec->BASpecs[spec->BACount]); /*@=unqualifiedtrans@*/ } /*@-compdef@*/ spec->BASpecs = _free(spec->BASpecs); /*@=compdef@*/ } spec->BANames = _free(spec->BANames); spec->passPhrase = _free(spec->passPhrase); spec->cookie = _free(spec->cookie); #ifdef WITH_LUA { rpmlua lua = NULL; /* global state */ rpmluaDelVar(lua, "patches"); rpmluaDelVar(lua, "sources"); } #endif spec->sources = freeSources(spec->sources); spec->dig = pgpDigFree(spec->dig); spec->packages = freePackages(spec->packages); }