[Rpm-maint] Tizen rpm security plug-in interface
Reshetova, Elena
elena.reshetova at intel.com
Mon Oct 10 13:00:53 UTC 2011
Hi,
Let me make first a short introduction and some explanation to you about the
rpm
security related work we have been doing recently at Intel.
I hope we can collaborate on this in the future and help to put good
enablers in rpm for security purposes.
Some history first:
January this year, there was a set of patches posted from Tero Aho, you can
find them in archives:
http://lists.rpm.org/pipermail/rpm-maint/2011-January/002980.html
I can see that even two tags were reserved for MSSF in rpm tags:
RPMTAG_MSSFMANIFEST and RPMTAG_MSSFDOMAIN.
These patches were intended for wiring a MSSF rpm security plug-in for MeeGo
that
would contain a rich set of security functionality, like setting up security
policies for installed packages,
labelling xattr for Smack and IMA and etc. I can provide more detailed
description of functionality, if needed.
As you probably heard, LiMo and MeeGo had merged into a new project, called
Tizen (https://www.tizen.org/).
This didn't eliminate by any means the need of security and similar security
functionality that we needed in MeeGo related to rpm.
So, our needs are still the same: we need to have a certain set of hooks in
rpm during different phases of rpm installation that
can be then implemented inside an rpm security plug-in. The hooks themselves
didn't change, but we did change their realisation
inside the plug-in, because we will be using a different security framework.
I would like to get your opinion about the hooks' position in rpm code. I
have just today rebased them to rpm master brunch.
Please consider this not as ready patch, but more like code for the initial
discussion.
I have excluded for now the code of the plugin itself for simplicity.
Best Regards,
Elena.
Makefile.am | 9
build/files.c | 15
build/parsePreamble.c | 1
build/rpmfc.c | 134 ++--
configure.ac | 68 ++
lib/Makefile.am | 3
lib/fsm.c | 17
lib/package.c | 4
lib/rpmfi.h | 1
lib/rpmscript.c | 6
lib/rpmsecurity.c | 269 +++++++++
lib/rpmsecurity.h | 160 +++++
lib/rpmtag.h | 4
lib/rpmte.c | 9
lib/rpmts.c | 4
lib/rpmtypes.h | 1
lib/transaction.c | 18
macros.in | 2
preinstall.am | 8
rpmio/base64.c | 6
rpmio/macro.c | 2
rpmio/rpmmalloc.c | 2
security/Makefile.am | 24
security/Makefile.msm | 15
security/msm.c | 816 +++++++++++++++++++++++++++++
security/msm.h | 489 +++++++++++++++++
security/msmconfig.c | 264 +++++++++
security/msmmanifest.c | 1358
+++++++++++++++++++++++++++++++++++++++++++++++++
security/msmmatch.c | 70 ++
security/msmxattr.c | 1248 +++++++++++++++++++++++++++++++++++++++++++++
security/security.h | 25
31 files changed, 4972 insertions(+), 80 deletions(-)
diff -Nuarp '--exclude=.git' rpm/build/files.c rpm-security/build/files.c
--- rpm/build/files.c 2011-10-10 15:25:30.577900228 +0300
+++ rpm-security/build/files.c 2011-10-10 14:14:25.000000000 +0300
@@ -809,6 +809,7 @@ static VFA_t virtualFileAttributes[] = {
{ "%readme", 0, RPMFILE_README },
{ "%license", 0, RPMFILE_LICENSE },
{ "%pubkey", 0, RPMFILE_PUBKEY },
+ { "%manifest", 0, RPMFILE_SECMANIFEST },
{ NULL, 0, 0 }
};
@@ -876,7 +877,7 @@ static rpmRC parseForSimple(rpmSpec spec
if (fl->currentFlags & RPMFILE_DOC) {
rstrscat(&specialDocBuf, " ", s, NULL);
} else
- if (fl->currentFlags & RPMFILE_PUBKEY)
+ if (fl->currentFlags & (RPMFILE_PUBKEY|RPMFILE_SECMANIFEST))
{
*fileName = s;
} else {
@@ -1583,6 +1584,14 @@ static rpmRC processMetadataFile(Package
apkt = pgpArmorWrap(PGPARMOR_PUBKEY, pkt, pktlen);
break;
}
+ case RPMTAG_SECMANIFEST:
+ if ((xx = rpmioSlurp(fn, &pkt, &pktlen)) != 0 || pkt == NULL) {
+ rpmlog(RPMLOG_ERR, _("%s: Security manifest file read
failed.\n"), fn);
+ goto exit;
+ }
+ apkt = b64encode(pkt, pktlen, -1);
+ rpmlog(RPMLOG_INFO, _("Aptk: %s\n"), apkt);
+ break;
}
if (!apkt) {
@@ -1834,7 +1843,9 @@ static rpmRC processPackageFiles(rpmSpec
dupAttrRec(&fl.def_ar, def_specialDocAttrRec);
} else if (fl.currentFlags & RPMFILE_PUBKEY) {
(void) processMetadataFile(pkg, &fl, fileName, RPMTAG_PUBKEYS);
- } else {
+ } else if (fl.currentFlags & RPMFILE_SECMANIFEST) {
+ (void) processMetadataFile(pkg, &fl, fileName,
RPMTAG_SECMANIFEST);
+ else {
(void) processBinaryFile(pkg, &fl, fileName);
}
}
diff -Nuarp '--exclude=.git' rpm/build/parsePreamble.c
rpm-security/build/parsePreamble.c
--- rpm/build/parsePreamble.c 2011-10-10 15:25:30.577900228 +0300
+++ rpm-security/build/parsePreamble.c 2011-10-10 14:26:26.000000000 +0300
@@ -924,6 +924,7 @@ static struct PreambleRec_s const preamb
{RPMTAG_BUGURL, 0, 0, LEN_AND_STR("bugurl")},
{RPMTAG_COLLECTIONS, 0, 0, LEN_AND_STR("collections")},
{RPMTAG_ORDERFLAGS, 2, 0,
LEN_AND_STR("orderwithrequires")},
+ {RPMTAG_SECMANIFEST, 0, 0, LEN_AND_STR("manifest")},
{0, 0, 0, 0}
};
diff -Nuarp '--exclude=.git' rpm/build/rpmfc.c rpm-security/build/rpmfc.c
--- rpm/build/rpmfc.c 2011-10-10 15:25:30.581900243 +0300
+++ rpm-security/build/rpmfc.c 2011-10-10 14:34:24.000000000 +0300
@@ -664,81 +664,83 @@ void rpmfcPrint(const char * msg, rpmfc
int dx;
int fx;
-int nprovides;
-int nrequires;
+ int nprovides;
+ int nrequires;
if (fp == NULL) fp = stderr;
if (msg)
fprintf(fp, "===================================== %s\n", msg);
-nprovides = rpmdsCount(fc->provides);
-nrequires = rpmdsCount(fc->requires);
- if (fc)
- for (fx = 0; fx < fc->nfiles; fx++) {
-assert(fx < fc->fcdictx->nvals);
- cx = fc->fcdictx->vals[fx];
-assert(fx < fc->fcolor->nvals);
- fcolor = fc->fcolor->vals[fx];
- ARGV_t fattrs = fc->fattrs[fx];
-
- fprintf(fp, "%3d %s", fx, fc->fn[fx]);
- if (fcolor != RPMFC_BLACK)
- fprintf(fp, "\t0x%x", fc->fcolor->vals[fx]);
- else
- fprintf(fp, "\t%s", fc->cdict[cx]);
- if (fattrs) {
- char *attrs = argvJoin(fattrs, ",");
- fprintf(fp, " [%s]", attrs);
- free(attrs);
- } else {
- fprintf(fp, " [none]");
- }
- fprintf(fp, "\n");
-
- if (fc->fddictx == NULL || fc->fddictn == NULL)
- continue;
-
-assert(fx < fc->fddictx->nvals);
- dx = fc->fddictx->vals[fx];
-assert(fx < fc->fddictn->nvals);
- ndx = fc->fddictn->vals[fx];
-
- while (ndx-- > 0) {
- const char * depval;
- unsigned char deptype;
- unsigned ix;
-
- ix = fc->ddictx->vals[dx++];
- deptype = ((ix >> 24) & 0xff);
- ix &= 0x00ffffff;
- depval = NULL;
- switch (deptype) {
- default:
-assert(depval != NULL);
- break;
- case 'P':
- if (nprovides > 0) {
-assert(ix < nprovides);
- (void) rpmdsSetIx(fc->provides, ix-1);
- if (rpmdsNext(fc->provides) >= 0)
- depval = rpmdsDNEVR(fc->provides);
+ if (fc) {
+
+ nprovides = rpmdsCount(fc->provides);
+ nrequires = rpmdsCount(fc->requires);
+ for (fx = 0; fx < fc->nfiles; fx++) {
+ assert(fx < fc->fcdictx->nvals);
+ cx = fc->fcdictx->vals[fx];
+ assert(fx < fc->fcolor->nvals);
+ fcolor = fc->fcolor->vals[fx];
+ ARGV_t fattrs = fc->fattrs[fx];
+
+ fprintf(fp, "%3d %s", fx, fc->fn[fx]);
+ if (fcolor != RPMFC_BLACK)
+ fprintf(fp, "\t0x%x", fc->fcolor->vals[fx]);
+ else
+ fprintf(fp, "\t%s", fc->cdict[cx]);
+ if (fattrs) {
+ char *attrs = argvJoin(fattrs, ",");
+ fprintf(fp, " [%s]", attrs);
+ free(attrs);
+ } else {
+ fprintf(fp, " [none]");
}
- break;
- case 'R':
- if (nrequires > 0) {
-assert(ix < nrequires);
- (void) rpmdsSetIx(fc->requires, ix-1);
- if (rpmdsNext(fc->requires) >= 0)
- depval = rpmdsDNEVR(fc->requires);
+ fprintf(fp, "\n");
+
+ if (fc->fddictx == NULL || fc->fddictn == NULL)
+ continue;
+
+ assert(fx < fc->fddictx->nvals);
+ dx = fc->fddictx->vals[fx];
+ assert(fx < fc->fddictn->nvals);
+ ndx = fc->fddictn->vals[fx];
+
+ while (ndx-- > 0) {
+ const char * depval;
+ unsigned char deptype;
+ unsigned ix;
+
+ ix = fc->ddictx->vals[dx++];
+ deptype = ((ix >> 24) & 0xff);
+ ix &= 0x00ffffff;
+ depval = NULL;
+ switch (deptype) {
+ default:
+ assert(depval != NULL);
+ break;
+ case 'P':
+ if (nprovides > 0) {
+ assert(ix < nprovides);
+ (void) rpmdsSetIx(fc->provides,
ix-1);
+ if (rpmdsNext(fc->provides) >= 0)
+ depval =
rpmdsDNEVR(fc->provides);
+ }
+ break;
+ case 'R':
+ if (nrequires > 0) {
+ assert(ix < nrequires);
+ (void) rpmdsSetIx(fc->requires,
ix-1);
+ if (rpmdsNext(fc->requires) >= 0)
+ depval =
rpmdsDNEVR(fc->requires);
+ }
+ break;
+ }
+ if (depval)
+ fprintf(fp, "\t%s\n", depval);
}
- break;
- }
- if (depval)
- fprintf(fp, "\t%s\n", depval);
- }
- }
+ }
+ }
}
rpmfc rpmfcFree(rpmfc fc)
diff -Nuarp '--exclude=.git' rpm/configure.ac rpm-security/configure.ac
--- rpm/configure.ac 2011-10-10 15:25:30.581900243 +0300
+++ rpm-security/configure.ac 2011-10-10 14:38:41.000000000 +0300
@@ -633,6 +633,68 @@ AC_SUBST(WITH_SELINUX_LIB)
AC_SUBST(WITH_SEMANAGE_LIB)
AM_CONDITIONAL(SELINUX,[test "$with_selinux" = yes])
+
+# msm
+WITH_MSM_LIB=
+WITH_MSM_INCLUDE=
+AC_ARG_WITH(msm, [AS_HELP_STRING([--with-msm],[build with msm support])],
+[case "$with_msm" in
+yes|no) ;;
+*) AC_MSG_ERROR([invalid argument to --with-msm])
+ ;;
+esac],
+[with_msm=no])
+
+AS_IF([test "$with_msm" = yes],[
+# AC_CHECK_HEADER([libxml2/libxml/xmlreader.h],[
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB([xml2],[xmlReaderForMemory],[],[
+ AC_MSG_ERROR([--with-msm given, but xmlReaderForMemory not found in
libxml2])])
+ LIBS="$save_LIBS"
+# ],[
+# AC_MSG_ERROR([--with-mssf given, but libxml2/libxml/xmlreader.h not
found])
+# ])
+ AC_CHECK_HEADER([sys/capability.h],[
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB([cap],[cap_set_file],[],[
+ AC_MSG_ERROR([--with-msm given, but cap_set_file not found in
libcap])])
+ LIBS="$save_LIBS"
+ ],[
+ AC_MSG_ERROR([--with-msm given, but sys/capability.h not found])
+ ])
+ AC_CHECK_HEADER([attr/xattr.h],[
+ save_LIBS="$LIBS"
+ AC_CHECK_LIB([attr],[setxattr],[],[
+ AC_MSG_ERROR([--with-msm given, but setxattr not found in libattr])])
+ LIBS="$save_LIBS"
+ ],[
+ AC_MSG_ERROR([--with-msm given, but attr/xattr.h not found])
+ ])
+ AC_CHECK_HEADER([uthash.h],[
+ save_LIBS="$LIBS"
+ LIBS="$save_LIBS"
+ ],[
+ AC_MSG_ERROR([--with-msm given, but uthash.h not found])
+ ])
+ AC_CHECK_HEADER([sys/smack.h],[
+ save_LIBS="$LIBS"
+ LIBS="$save_LIBS"
+ ],[
+ AC_MSG_ERROR([--with-msm given, but smack.h not found])
+ ])
+])
+
+AS_IF([test "$with_msm" = yes],[
+ AC_DEFINE(WITH_MSM, 1, [Build with msm support?])
+ WITH_MSM_LIB="`xml2-config --libs` -lcap -lattr -lsmack"
+ WITH_MSM_INCLUDE="`xml2-config --cflags`"
+])
+AC_SUBST(WITH_MSM_LIB)
+AC_SUBST(WITH_MSM_INCLUDE)
+AM_CONDITIONAL(MSM,[test "$with_msm" = yes])
+
+
+
# libcap
WITH_CAP_LIB=
AC_ARG_WITH(cap, [AS_HELP_STRING([--with-cap],[build with capability
support])],
@@ -712,6 +774,11 @@ AS_IF([test "$enable_plugins" = yes],[
])
AM_CONDITIONAL(ENABLE_PLUGINS,[test "$enable_plugins" = yes])
+AC_ARG_ENABLE(security, [AS_HELP_STRING([--disable-security],[build without
security plugin support])],,[enable_security=yes])
+AS_IF([test "$enable_security" = yes],[
+ AC_DEFINE(ENABLE_SECURITY, 1, [Build with security plugin support?])
+])
+AM_CONDITIONAL(ENABLE_SECURITY,[test "$enable_security" = yes])
with_dmalloc=no
AC_ARG_WITH(dmalloc, [AS_HELP_STRING([--with-dmalloc],[build with dmalloc
debugging support])])
@@ -814,5 +881,6 @@ AC_CONFIG_FILES([Makefile
tests/Makefile
plugins/Makefile
python/setup.py
+ security/Makefile
])
AC_OUTPUT
diff -Nuarp '--exclude=.git' rpm/lib/fsm.c rpm-security/lib/fsm.c
--- rpm/lib/fsm.c 2011-10-10 15:25:30.601900346 +0300
+++ rpm-security/lib/fsm.c 2011-10-10 14:43:16.000000000 +0300
@@ -27,6 +27,7 @@
#include "lib/rpmte_internal.h" /* XXX rpmfs */
#include "lib/rpmts_internal.h" /* rpmtsSELabelFoo() only */
#include "lib/rpmug.h"
+#include "lib/rpmsecurity.h" /* security hooks */
#include "debug.h"
@@ -798,6 +799,11 @@ static int expandRegular(FSM_t fsm)
if (rc)
goto exit;
+ /* Call security plugin to update file status. */
+ rc = rpmsecurityCallFsmUpdated(fsm);
+ if (rc)
+ goto exit;
+
rc = fsmNext(fsm, FSM_WRITE);
if (rc)
goto exit;
@@ -1065,7 +1071,7 @@ static int fsmMakeLinks(FSM_t fsm)
rc = fsmMapPath(fsm);
fsm->opath = fsm->path;
fsm->path = NULL;
- for (i = 0; i < fsm->li->nlink; i++) {
+ for (i = 0; fsm->li && i < fsm->li->nlink; i++) {
if (fsm->li->filex[i] < 0) continue;
if (fsm->li->createdPath == i) continue;
@@ -1652,6 +1658,13 @@ static int fsmStage(FSM_t fsm, fileStage
break;
}
+ /* Call security plugin to start up for a file. */
+ rc = rpmsecurityCallFsmOpened(fsm);
+ if (rc) {
+ (void) fsmNext(fsm, FSM_UNDO);
+ break;
+ }
+
/* Extract file from archive. */
rc = fsmNext(fsm, FSM_PROCESS);
if (rc) {
@@ -1663,6 +1676,8 @@ static int fsmStage(FSM_t fsm, fileStage
(void) fsmNext(fsm, FSM_NOTIFY);
rc = fsmNext(fsm, FSM_FINI);
+ /* Call security plugin with return code to finish the file. */
+ rc = rpmsecurityCallFsmClosed(fsm, rc);
if (rc) {
break;
}
diff -Nuarp '--exclude=.git' rpm/lib/Makefile.am
rpm-security/lib/Makefile.am
--- rpm/lib/Makefile.am 2011-10-10 15:25:30.597900320 +0300
+++ rpm-security/lib/Makefile.am 2011-10-10 14:47:40.000000000 +0300
@@ -36,7 +36,8 @@ librpm_la_SOURCES = \
verify.c rpmlock.c rpmlock.h misc.h \
rpmscript.h rpmscript.c legacy.c merge.c \
rpmchroot.c rpmchroot.h \
- rpmplugins.c rpmplugins.h rpmug.c rpmug.h
+ rpmplugins.c rpmplugins.h rpmug.c rpmug.h \
+ rpmsecurity.c rpmsecurity.h
librpm_la_LDFLAGS = -version-info 2:0:0
diff -Nuarp '--exclude=.git' rpm/lib/package.c rpm-security/lib/package.c
--- rpm/lib/package.c 2011-10-10 15:25:30.605900359 +0300
+++ rpm-security/lib/package.c 2011-10-10 14:50:26.000000000 +0300
@@ -17,6 +17,7 @@
#include "rpmio/digest.h"
#include "rpmio/rpmio_internal.h" /* fd digest bits */
#include "lib/header_internal.h" /* XXX headerCheck */
+#include "lib/rpmsecurity.h" /* security hooks */
#include "debug.h"
@@ -640,6 +641,9 @@ static rpmRC rpmpkgRead(rpmKeyring keyri
/** @todo Implement disable/enable/warn/error/anal policy. */
rc = rpmVerifySignature(keyring, &sigtd, dig, ctx, &msg);
+
+ /* Call security plugin to verify the signature. */
+ rc = rpmsecurityCallVerify(keyring, &sigtd, dig, rc);
switch (rc) {
case RPMRC_OK: /* Signature is OK. */
diff -Nuarp '--exclude=.git' rpm/lib/rpmfi.h rpm-security/lib/rpmfi.h
--- rpm/lib/rpmfi.h 2011-10-10 15:25:30.609900382 +0300
+++ rpm-security/lib/rpmfi.h 2011-10-10 14:53:35.000000000 +0300
@@ -62,6 +62,7 @@ enum rpmfileAttrs_e {
RPMFILE_EXCLUDE = (1 << 9), /*!< from %%exclude, internal */
RPMFILE_UNPATCHED = (1 << 10), /*!< placeholder (SuSE) */
RPMFILE_PUBKEY = (1 << 11), /*!< from %%pubkey */
+ RPMFILE_SECMANIFEST = (1 << 12), /*!< from %%manifest */
};
typedef rpmFlags rpmfileAttrs;
diff -Nuarp '--exclude=.git' rpm/lib/rpmscript.c
rpm-security/lib/rpmscript.c
--- rpm/lib/rpmscript.c 2011-10-10 15:25:30.617900423 +0300
+++ rpm-security/lib/rpmscript.c 2011-10-10 14:55:35.000000000 +0300
@@ -13,6 +13,7 @@
#include "rpmio/rpmlua.h"
#include "lib/rpmscript.h"
+#include "lib/rpmsecurity.h"
#include "debug.h"
@@ -169,7 +170,8 @@ static void doScriptExec(int selinux, AR
}
if (xx == 0) {
- xx = execv(argv[0], argv);
+ /* Exec the scriptlet through security plugin */
+ xx = rpmsecurityCallScriptExec(argv);
}
}
_exit(127); /* exit 127 for compatibility with bash(1) */
@@ -291,7 +293,7 @@ exit:
if (fn) {
if (!rpmIsDebug())
unlink(fn);
- free(fn);
+ if (fn) fn =_free(fn);
}
return rc;
}
diff -Nuarp '--exclude=.git' rpm/lib/rpmsecurity.c
rpm-security/lib/rpmsecurity.c
--- rpm/lib/rpmsecurity.c 1970-01-01 02:00:00.000000000 +0200
+++ rpm-security/lib/rpmsecurity.c 2011-08-04 11:29:00.000000000 +0300
@@ -0,0 +1,269 @@
+#include "system.h"
+
+#include <rpm/rpmmacro.h>
+#include <rpm/rpmtypes.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmstring.h>
+#include <rpm/rpmts.h>
+
+#include <rpm/rpmsecurity.h>
+
+#define STR1(x) #x
+#define STR(x) STR1(x)
+
+struct rpmSecurity_s {
+ void *handle;
+ rpmRC (*SECURITYHOOK_INIT_FUNC)(rpmts, const char *);
+ rpmRC (*SECURITYHOOK_FILE_CONFLICT_FUNC)(rpmts, rpmte, rpmfi, Header,
rpmfi, int);
+ rpmRC (*SECURITYHOOK_PRE_TSM_FUNC)(rpmts);
+ rpmRC (*SECURITYHOOK_VERIFY_FUNC)(rpmKeyring, rpmtd, pgpDig, rpmRC);
+ rpmRC (*SECURITYHOOK_PRE_PSM_FUNC)(rpmte);
+ rpmRC (*SECURITYHOOK_SCRIPT_EXEC_FUNC)(ARGV_const_t);
+ rpmRC (*SECURITYHOOK_FSM_OPENED_FUNC)(FSM_t);
+ rpmRC (*SECURITYHOOK_FSM_UPDATED_FUNC)(FSM_t);
+ rpmRC (*SECURITYHOOK_FSM_CLOSED_FUNC)(FSM_t, int);
+ rpmRC (*SECURITYHOOK_POST_PSM_FUNC)(rpmte, int);
+ rpmRC (*SECURITYHOOK_POST_TSM_FUNC)(rpmts);
+ rpmRC (*SECURITYHOOK_CLEANUP_FUNC)(void);
+ int count;
+ rpmts ts;
+};
+
+static rpmSecurity securityPlugin = NULL;
+
+rpmRC rpmsecurityCallInit(const char *opts);
+rpmRC rpmsecurityCallCleanup(void);
+
+#define RPMSECURITY_GET_HOOK_FUNC(hook)
\
+ *(void **)(&securityPlugin->hook) = dlsym(securityPlugin->handle,
STR(hook)); \
+ if ((error = dlerror()) != NULL) { \
+ rpmlog(RPMLOG_ERR, _("Failed to resolve security plugin symbol %s:
%s\n"), STR(hook), error); \
+ goto fail; \
+ }
+
+static rpmRC rpmsecurityAdd(const char *path, const char *opts, rpmts ts)
+{
+ char *error;
+
+ void *handle = dlopen(path, RTLD_LAZY);
+ if (!handle) {
+ rpmlog(RPMLOG_ERR, _("Failed to dlopen %s %s\n"), path, dlerror());
+ goto fail;
+ }
+
+ securityPlugin = xcalloc(1, sizeof(*securityPlugin));
+ if (!securityPlugin) {
+ rpmlog(RPMLOG_ERR, _("Failed to allocate security plugin %s\n"),
path);
+ goto fail;
+ }
+
+ securityPlugin->handle = handle;
+ securityPlugin->count++;
+ securityPlugin->ts = ts;
+
+ /* Security plugin really has to have all the hooks. This means that */
+ /* if the interface is changed, all plugins have to be changed which */
+ /* in general is not nice. However, a security plugin must be aware of
*/
+ /* all the hooks declaring empty functions if it doesn't need them. */
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_INIT_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_FILE_CONFLICT_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_PRE_TSM_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_VERIFY_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_PRE_PSM_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_SCRIPT_EXEC_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_FSM_OPENED_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_FSM_UPDATED_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_FSM_CLOSED_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_POST_PSM_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_POST_TSM_FUNC);
+ RPMSECURITY_GET_HOOK_FUNC(SECURITYHOOK_CLEANUP_FUNC);
+
+ return rpmsecurityCallInit(opts);
+
+ fail:
+ if (handle) dlclose(handle);
+ if (securityPlugin) free(securityPlugin);
+ return RPMRC_FAIL;
+}
+
+rpmRC rpmsecuritySetupPlugin(rpmts ts)
+{
+ char *path;
+ char *options;
+ int rc = RPMRC_FAIL;
+
+ if (securityPlugin) {
+ securityPlugin->count++;
+ return RPMRC_OK;
+ }
+
+ path = rpmExpand("%{?__security_plugin}", NULL);
+ if (!path || rstreq(path, "")) {
+#ifdef ENFORCE_SECURITY
+ rpmlog(RPMLOG_ERR, _("Failed to expand %%__security_plugin
macro\n"));
+#else
+ rpmlog(RPMLOG_INFO, _("Failed to expand %%__security_plugin
macro\n"));
+#endif
+ goto exit;
+ }
+
+ /* split the options from the path */
+#define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
+#define SKIPNONSPACE(s) { while (*(s) && !risspace(*(s))) (s)++; }
+ options = path;
+ SKIPNONSPACE(options);
+ if (risspace(*options)) {
+ *options = '\0';
+ options++;
+ SKIPSPACE(options);
+ }
+ if (*options == '\0') {
+ options = NULL;
+ }
+
+ rc = rpmsecurityAdd(path, options, ts);
+ exit:
+ if (path) _free(path);
+ return rc;
+}
+
+int rpmsecurityPluginAdded(void)
+{
+ return (securityPlugin != NULL);
+}
+
+rpmSecurity rpmsecurityFreePlugin()
+{
+ if (securityPlugin) {
+ securityPlugin->count--;
+ if (!securityPlugin->count) {
+ rpmsecurityCallCleanup();
+ dlclose(securityPlugin->handle);
+ securityPlugin = _free(securityPlugin);
+ }
+ }
+ return securityPlugin;
+}
+
+#define RPMSECURITY_SET_HOOK_FUNC(hook)
\
+ hookFunc = securityPlugin->hook; \
+ if (rpmtsFlags(securityPlugin->ts) & RPMTRANS_FLAG_TEST) { \
+ return RPMRC_OK; \
+ } \
+ rpmlog(RPMLOG_DEBUG, "Security: calling hook %s in security plugin\n",
STR(hook));
+
+rpmRC rpmsecurityCallInit(const char *opts)
+{
+ rpmRC (*hookFunc)(rpmts, const char *);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_INIT_FUNC);
+ return hookFunc(securityPlugin->ts, opts);
+}
+
+rpmRC rpmsecurityCallCleanup(void)
+{
+ rpmRC (*hookFunc)(void);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_CLEANUP_FUNC);
+ return hookFunc();
+}
+
+rpmRC rpmsecurityCallPreTsm(rpmts ts)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmts);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_PRE_TSM_FUNC);
+ return hookFunc(ts);
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallPostTsm(rpmts ts)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmts);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_POST_TSM_FUNC);
+ return hookFunc(ts);
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallPrePsm(rpmte te)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmte);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_PRE_PSM_FUNC);
+ return hookFunc(te);
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallPostPsm(rpmte te, int rpmrc)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmte, int);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_POST_PSM_FUNC);
+ return hookFunc(te, rpmrc);
+ }
+ return rpmrc;
+}
+
+rpmRC rpmsecurityCallScriptExec(ARGV_const_t argv)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(ARGV_const_t);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_SCRIPT_EXEC_FUNC);
+ return hookFunc(argv);
+ }
+ return execv(argv[0], argv);
+}
+
+rpmRC rpmsecurityCallFsmOpened(FSM_t fsm)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(FSM_t);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FSM_OPENED_FUNC);
+ return hookFunc(fsm);
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallFsmUpdated(FSM_t fsm)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(FSM_t);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FSM_UPDATED_FUNC);
+ return hookFunc(fsm);
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallFsmClosed(FSM_t fsm, int rpmrc)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(FSM_t, int);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FSM_CLOSED_FUNC);
+ return hookFunc(fsm, rpmrc);
+ }
+ return rpmrc;
+}
+
+rpmRC rpmsecurityCallVerify(rpmKeyring keyring, rpmtd sigtd,
+ pgpDig dig, rpmRC rpmrc)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmKeyring, rpmtd, pgpDig, rpmRC);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_VERIFY_FUNC);
+ return hookFunc(keyring, sigtd, dig, rpmrc);
+ }
+ return rpmrc;
+}
+
+rpmRC rpmsecurityCallFileConflict(rpmts ts, rpmte te, rpmfi fi,
+ Header oldHeader, rpmfi oldFi, int rpmrc)
+{
+ if (securityPlugin) {
+ rpmRC (*hookFunc)(rpmts, rpmte, rpmfi, Header, rpmfi, int);
+ RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FILE_CONFLICT_FUNC);
+ return hookFunc(ts, te, fi, oldHeader, oldFi, rpmrc);
+ }
+ return rpmrc;
+}
diff -Nuarp '--exclude=.git' rpm/lib/rpmsecurity.h
rpm-security/lib/rpmsecurity.h
--- rpm/lib/rpmsecurity.h 1970-01-01 02:00:00.000000000 +0200
+++ rpm-security/lib/rpmsecurity.h 2011-10-07 11:55:42.000000000 +0300
@@ -0,0 +1,160 @@
+#ifndef _SECURITY_H
+#define _SECURITY_H
+
+#include <rpm/rpmtypes.h>
+#include <rpm/rpmpgp.h>
+#include <lib/fsm.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \ingroup rpmsecurity
+ *
+ * General flow of code in rpm:
+ *
+ * The first hook SECURITYHOOK_INIT_FUNC is called right after keyring is
+ * loaded and database indexes are opened.
+ *
+ * At the time rpm prepares packages for installation, it might call
+ * SECURITYHOOK_FILE_CONFLICT_FUNC if some new package has conflicting
files.
+ * Security plugin can then decide if overwrite is allowed or not. After
+ * conflict resolving rpm calls SECURITYHOOK_PRE_TSM_FUNC.
+ *
+ * The actual package processing starts by calling SECURITYHOOK_VERIFY_FUNC
+ * where security plugin can verify the package signature (right after rpm
+ * has done it's own signature verifying).
+
+ * Then SECURITYHOOK_PRE_PSM_FUNC is called to start installing/removing
+ * the package. In the beginning of installation process there may be call
+ * to SECURITYHOOK_SCRIPT_EXEC_FUNC if package spec has a pre installation
+ * script. Then SECURITYHOOK_FSM_OPENED_FUNC, SECURITYHOOK_FSM_UPDATED_FUNC
+ * and SECURITYHOOK_FSM_CLOSED_FUNC are called for each installed file to
+ * make it possible to calculate hashes for the files (or use the sum
+ * in rpm package). At the end of installation process there may be call
+ * to SECURITYHOOK_SCRIPT_EXEC_FUNC if package spec has a post installation
+ * script. Finally SECURITYHOOK_POST_PSM_FUNC is called to wrap up package
+ * processing.
+ *
+ * SECURITYHOOK_POST_TSM_FUNC is called when all packages have been
processed.
+ *
+ * Finally SECURITYHOOK_CLEANUP_FUNC is called to free used resources.
+ */
+
+/** \ingroup rpmsecurity
+ * Add and open security plugin, calls SECURITYHOOK_INIT_FUNC.
+ * This is the place for the plugin to initialize itself, load
+ * possible configuration files etc.
+ * @param ts ts element
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecuritySetupPlugin(rpmts ts);
+
+/** \ingroup rpmsecurity
+ * Call the security file conflict plugin hook.
+ * This hook is called whenever there is a file conflict.
+ * @param ts transaction set
+ * @param te transaction element
+ * @param fi new file
+ * @param oldHeader old header
+ * @param oldFi old file
+ * @param rpmrc success from RPM
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallFileConflict(rpmts ts, rpmte te, rpmfi fi,
+ Header oldHeader, rpmfi oldFi, int rpmrc);
+
+/** \ingroup rpmsecurity
+ * Call the security pre tsm plugin hook.
+ * This hook is called before the transaction state machine is started.
+ * @param ts transaction set
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallPreTsm(rpmts ts);
+
+/** \ingroup rpmsecurity
+ * Call the security verify plugin hook.
+ * This hook is called right after RPM has verified package signature.
+ * @param keyring RPM keyring
+ * @param sigtd signature tag
+ * @param dig PGP digest
+ * @param rpmrc success from RPM
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallVerify(rpmKeyring keyring, rpmtd sigtd,
+ pgpDig dig, rpmRC rpmrc);
+
+/** \ingroup rpmsecurity
+ * Call the security pre psm plugin hook.
+ * This hook is called before the package state machine is started.
+ * @param te transaction element in question
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallPrePsm(rpmte te);
+
+/** \ingroup rpmsecurity
+ * Call the security script exec plugin hook.
+ * Script execution takes place in child process context.
+ * @param argv script command line arguments
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallScriptExec(ARGV_const_t argv);
+
+/** \ingroup rpmsecurity
+ * Call the security file opened plugin hook.
+ * This hook is called before the file state machine is started.
+ * @param fsm fsm in question
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallFsmOpened(FSM_t fsm);
+
+/** \ingroup rpmsecurity
+ * Call the security file updated plugin hook.
+ * This hook is called during the file state machine is running.
+ * @param fsm fsm in question
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallFsmUpdated(FSM_t fsm);
+
+/** \ingroup rpmsecurity
+ * Call the security file closed plugin hook.
+ * This hook is called after the file state machine has finished.
+ * @param fsm fsm in question
+ * @param rpmrc success from RPM
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallFsmClosed(FSM_t fsm, int rpmrc);
+
+/** \ingroup rpmsecurity
+ * Call the security post psm plugin hook.
+ * This hook is called after the package state machine has finished.
+ * @param te transaction element in question
+ * @param rpmrc success from RPM
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallPostPsm(rpmte te, int rpmrc);
+
+/** \ingroup rpmsecurity
+ * Call the security post tsm plugin hook.
+ * This hook is called after the transaction state machine has finished.
+ * @param ts transaction set
+ * @return RPMRC_OK on success, RPMRC_FAIL otherwise
+ */
+rpmRC rpmsecurityCallPostTsm(rpmts ts);
+
+/** \ingroup rpmsecurity
+ * Destroy security plugin structure, calls SECURITYHOOK_CLEANUP_FUNC.
+ * Plugin can save new state and new configuration in cleanup.
+ * @return NULL always
+ */
+rpmSecurity rpmsecurityFreePlugin(void);
+
+/** \ingroup rpmsecurity
+ * Determine if a security plugin has been added already.
+ * @return 1 if security plugin has already been added, 0
otherwise
+ */
+int rpmsecurityPluginAdded(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* _SECURITY_H */
diff -Nuarp '--exclude=.git' rpm/lib/rpmtag.h rpm-security/lib/rpmtag.h
--- rpm/lib/rpmtag.h 2011-10-10 15:25:30.617900423 +0300
+++ rpm-security/lib/rpmtag.h 2011-10-10 15:01:01.000000000 +0300
@@ -299,8 +299,8 @@ typedef enum rpmTag_e {
RPMTAG_ORDERNAME = 5035, /* s[] */
RPMTAG_ORDERVERSION = 5036, /* s[] */
RPMTAG_ORDERFLAGS = 5037, /* i[] */
- RPMTAG_MSSFMANIFEST = 5038, /* s[] reservation
(unimplemented) */
- RPMTAG_MSSFDOMAIN = 5039, /* s[] reservation (unimplemented)
*/
+ RPMTAG_SECMANIFEST = 5038, /* s[] reservation (unimplemented)
*/
+ RPMTAG_SECSWSOURCE = 5039, /* s[] reservation (unimplemented)
*/
RPMTAG_INSTFILENAMES = 5040, /* s[] extension */
RPMTAG_REQUIRENEVRS = 5041, /* s[] extension */
RPMTAG_PROVIDENEVRS = 5042, /* s[] extension */
diff -Nuarp '--exclude=.git' rpm/lib/rpmte.c rpm-security/lib/rpmte.c
--- rpm/lib/rpmte.c 2011-10-10 15:25:30.617900423 +0300
+++ rpm-security/lib/rpmte.c 2011-10-10 15:02:43.000000000 +0300
@@ -14,6 +14,7 @@
#include <rpm/rpmlog.h>
#include "lib/rpmplugins.h"
+#include "lib/rpmsecurity.h"
#include "lib/rpmte_internal.h"
#include "debug.h"
@@ -912,7 +913,13 @@ int rpmteProcess(rpmte te, pkgGoal goal)
}
if (rpmteOpen(te, reset_fi)) {
- failed = rpmpsmRun(te->ts, te, goal);
+ /* Call security plugin to set te for next operations */
+ failed = rpmsecurityCallPrePsm(te);
+ if (!failed) {
+ failed = rpmpsmRun(te->ts, te, goal);
+ /* Call security plugin to finish any te related tasks */
+ failed = rpmsecurityCallPostPsm(te, failed);
+ }
rpmteClose(te, reset_fi);
}
diff -Nuarp '--exclude=.git' rpm/lib/rpmts.c rpm-security/lib/rpmts.c
--- rpm/lib/rpmts.c 2011-10-10 15:25:30.621900442 +0300
+++ rpm-security/lib/rpmts.c 2011-10-10 15:03:38.000000000 +0300
@@ -24,6 +24,7 @@
#include "lib/rpmal.h"
#include "lib/rpmchroot.h"
#include "lib/rpmplugins.h"
+#include "lib/rpmsecurity.h"
#include "lib/rpmts_internal.h"
#include "lib/rpmte_internal.h"
#include "lib/misc.h"
@@ -629,6 +630,9 @@ rpmts rpmtsFree(rpmts ts)
ts->plugins = rpmpluginsFree(ts->plugins);
+ /* Free security plugin here also. */
+ rpmsecurityFreePlugin();
+
if (_rpmts_stats)
rpmtsPrintStats(ts);
diff -Nuarp '--exclude=.git' rpm/lib/rpmtypes.h rpm-security/lib/rpmtypes.h
--- rpm/lib/rpmtypes.h 2011-10-10 15:25:30.621900442 +0300
+++ rpm-security/lib/rpmtypes.h 2011-10-10 15:04:14.000000000 +0300
@@ -78,6 +78,7 @@ typedef struct rpmPubkey_s * rpmPubkey;
typedef struct rpmKeyring_s * rpmKeyring;
typedef struct rpmPlugins_s * rpmPlugins;
+typedef struct rpmSecurity_s * rpmSecurity;
typedef struct rpmgi_s * rpmgi;
diff -Nuarp '--exclude=.git' rpm/lib/transaction.c
rpm-security/lib/transaction.c
--- rpm/lib/transaction.c 2011-10-10 15:25:30.625900467 +0300
+++ rpm-security/lib/transaction.c 2011-10-10 15:08:14.000000000 +0300
@@ -20,6 +20,7 @@
#include "lib/rpmte_internal.h" /* only internal apis */
#include "lib/rpmts_internal.h"
#include "rpmio/rpmhook.h"
+#include "lib/rpmsecurity.h"
/* XXX FIXME: merge with existing (broken?) tests in system.h */
/* portability fiddles */
@@ -358,6 +359,9 @@ static void handleInstInstalledFile(cons
}
}
+ /* Call security plugin to check the file conflict. */
+ rConflicts = rpmsecurityCallFileConflict(ts, p, fi, otherHeader,
otherFi, rConflicts);
+
if (rConflicts) {
char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, rpmfiFN(fi),
@@ -1421,6 +1425,13 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rp
goto exit;
}
+ /* Setup the security plugin */
+ if (rpmsecuritySetupPlugin(ts)) {
+#ifdef ENFORCE_SECURITY
+ goto exit;
+#endif
+ }
+
rpmtsSetupCollections(ts);
/* Check package set for problems */
@@ -1453,9 +1464,16 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rp
tsprobs = rpmpsFree(tsprobs);
rpmtsCleanProblems(ts);
+ /* Call security plugin */
+ rpmsecurityCallPreTsm(ts);
+
/* Actually install and remove packages, get final exit code */
rc = rpmtsProcess(ts) ? -1 : 0;
+ /* Call security plugin */
+ rpmsecurityCallPostTsm(ts);
+
+
/* Run post-transaction scripts unless disabled */
if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_NOPOST))) {
rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
diff -Nuarp '--exclude=.git' rpm/macros.in rpm-security/macros.in
--- rpm/macros.in 2011-10-10 15:25:30.625900467 +0300
+++ rpm-security/macros.in 2011-10-10 15:09:08.000000000 +0300
@@ -1050,5 +1050,7 @@ done \
%__collection_sepolicy %{__plugindir}/sepolicy.so
%__collection_sepolicy_flags 1
+%__security_plugin %{__plugindir}/msm.so
+
# \endverbatim
#*/
diff -Nuarp '--exclude=.git' rpm/Makefile.am rpm-security/Makefile.am
--- rpm/Makefile.am 2011-10-10 15:25:30.573900202 +0300
+++ rpm-security/Makefile.am 2011-10-10 15:10:41.000000000 +0300
@@ -33,7 +33,11 @@ if HAVE_FAKECHROOT
SUBDIRS += tests
endif
-DIST_SUBDIRS = po misc luaext rpmio lib sign build python scripts fileattrs
doc tests plugins
+if ENABLE_SECURITY
+SUBDIRS += security
+endif
+
+DIST_SUBDIRS = po misc luaext rpmio lib sign build python scripts fileattrs
doc tests plugins security
pkgconfigdir = $(libdir)/pkgconfig
@@ -87,6 +91,9 @@ pkginclude_HEADERS += build/rpmbuild.h
pkginclude_HEADERS += build/rpmfc.h
pkginclude_HEADERS += build/rpmspec.h
+pkginclude_HEADERS += lib/rpmplugins.h
+pkginclude_HEADERS += lib/rpmsecurity.h
+
rpmbindir = `echo $(bindir) | $(SED) -e s,usr/bin,bin,`
rpmbin_PROGRAMS = rpm
diff -Nuarp '--exclude=.git' rpm/preinstall.am rpm-security/preinstall.am
--- rpm/preinstall.am 2011-10-10 15:25:30.673900702 +0300
+++ rpm-security/preinstall.am 2011-10-10 15:12:54.000000000 +0300
@@ -114,6 +114,14 @@ include/rpm/rpmvf.h: lib/rpmvf.h include
$(INSTALL_DATA) $(top_srcdir)/lib/rpmvf.h include/rpm/rpmvf.h
BUILT_SOURCES += include/rpm/rpmvf.h
CLEANFILES += include/rpm/rpmvf.h
+include/rpm/rpmplugins.h: lib/rpmplugins.h include/rpm/$(dirstamp)
+ $(INSTALL_DATA) $(top_srcdir)/lib/rpmplugins.h
include/rpm/rpmplugins.h
+BUILT_SOURCES += include/rpm/rpmplugins.h
+CLEANFILES += include/rpm/rpmplugins.h
+include/rpm/rpmsecurity.h: lib/rpmsecurity.h include/rpm/$(dirstamp)
+ $(INSTALL_DATA) $(top_srcdir)/lib/rpmsecurity.h
include/rpm/rpmsecurity.h
+BUILT_SOURCES += include/rpm/rpmsecurity.h
+CLEANFILES += include/rpm/rpmsecurity.h
include/rpm/rpmsign.h: sign/rpmsign.h include/rpm/$(dirstamp)
$(INSTALL_DATA) $(top_srcdir)/sign/rpmsign.h include/rpm/rpmsign.h
BUILT_SOURCES += include/rpm/rpmsign.h
diff -Nuarp '--exclude=.git' rpm/rpmio/base64.c rpm-security/rpmio/base64.c
--- rpm/rpmio/base64.c 2011-10-10 15:25:30.681900744 +0300
+++ rpm-security/rpmio/base64.c 2011-10-10 15:17:31.000000000 +0300
@@ -104,7 +104,7 @@ static int base64_decode_value(unsigned
{
static const int decoding[] =
{62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4
,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1
,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,
51};
value_in -= 43;
- if (value_in > sizeof(decoding)/sizeof(int))
+ if (value_in >= sizeof(decoding)/sizeof(int))
return -1;
return decoding[value_in];
}
@@ -165,6 +165,7 @@ int b64decode(const char *in, void **out
{
size_t outcnt = 0;
const char *inptr = in;
+ char *outptr;
*out = NULL;
@@ -189,12 +190,13 @@ int b64decode(const char *in, void **out
outcnt = (outcnt / 4) * 3;
- *out = malloc(outcnt + 1); /* base64_decode_block can write one
extra character */
+ *out = outptr = malloc(outcnt + 2); /* base64_decode_block can write
one extra character, reserve one more for null termination */
if (*out == NULL)
return 4;
*outlen = base64_decode_block(in, inptr - in, *out);
+ outptr[*outlen] = '\0'; /* null terminate */
return 0;
}
diff -Nuarp '--exclude=.git' rpm/rpmio/macro.c rpm-security/rpmio/macro.c
--- rpm/rpmio/macro.c 2011-10-10 15:25:30.685900756 +0300
+++ rpm-security/rpmio/macro.c 2011-10-10 15:19:27.000000000 +0300
@@ -617,7 +617,7 @@ doDefine(MacroBuf mb, const char * se, i
exit:
_free(buf);
- _free(ebody);
+ if (ebody) _free(ebody);
return se;
}
diff -Nuarp '--exclude=.git' rpm/rpmio/rpmmalloc.c
rpm-security/rpmio/rpmmalloc.c
--- rpm/rpmio/rpmmalloc.c 2011-10-10 15:25:30.689900777 +0300
+++ rpm-security/rpmio/rpmmalloc.c 2011-10-10 15:20:15.000000000 +0300
@@ -80,6 +80,6 @@ char * rstrdup (const char *str)
void * rfree (void *ptr)
{
- free(ptr);
+ if (ptr) free(ptr);
return NULL;
}
diff -Nuarp '--exclude=.git' rpm/security/Makefile.am
rpm-security/security/Makefile.am
--- rpm/security/Makefile.am 1970-01-01 02:00:00.000000000 +0200
+++ rpm-security/security/Makefile.am 2011-09-23 11:11:22.000000000 +0300
@@ -0,0 +1,24 @@
+# Makefile for rpm library.
+
+include $(top_srcdir)/rpm.am
+
+AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/
+AM_CPPFLAGS += -I$(top_srcdir)/misc
+AM_CPPFLAGS += -DLOCALEDIR="\"$(localedir)\""
+AM_CPPFLAGS += -DSYSCONFDIR="\"$(sysconfdir)\""
+AM_CPPFLAGS += -DLOCALSTATEDIR="\"$(localstatedir)\""
+AM_CPPFLAGS += -DLIBRPMALIAS_FILENAME="\"rpmpopt-${VERSION}\""
+if MSM
+AM_CPPFLAGS += @WITH_MSM_INCLUDE@
+endif
+AM_LDFLAGS = -avoid-version -module -shared
+
+pluginsdir = $(libdir)/rpm-plugins
+
+if MSM
+plugins_LTLIBRARIES = msm.la
+endif
+if MSM
+msm_la_SOURCES = security.h msm.h msm.c msmconfig.c msmmanifest.c
msmxattr.c msmmatch.c
+msm_la_LIBADD = $(top_builddir)/lib/librpm.la
$(top_builddir)/rpmio/librpmio.la @WITH_MSM_LIB@
+endif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 7220 bytes
Desc: not available
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20111010/223f9db0/attachment-0001.p7s>
More information about the Rpm-maint
mailing list