[Rpm-maint] [PATCH 1/3] Security plugin interface

ext-tero.aho at nokia.com ext-tero.aho at nokia.com
Fri Jan 21 09:34:51 UTC 2011


- Create security subdirectory for security plugins, and add
  empty makefile there.
- The actual interface is in lib/rpmsecurity.h and lib/rpmsecurity.c
  and it follows the style of collections plugins interface
  (except that there can be only one active security plugin for now).
- The other source files have hooks to call the security plugin
  if that is specified (macro __security_plugin is defined).
---
 Makefile.am          |    8 ++-
 configure.ac         |    6 +
 lib/Makefile.am      |    3 +-
 lib/fsm.c            |   16 +++
 lib/package.c        |    7 +-
 lib/rpmscript.c      |    8 ++
 lib/rpmsecurity.c    |  250 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/rpmsecurity.h    |  160 ++++++++++++++++++++++++++++++++
 lib/rpmte.c          |    9 ++-
 lib/rpmts.c          |    3 +
 lib/rpmtypes.h       |    1 +
 lib/transaction.c    |   14 +++
 preinstall.am        |    8 ++
 security/Makefile.am |   14 +++
 14 files changed, 503 insertions(+), 4 deletions(-)
 create mode 100644 lib/rpmsecurity.c
 create mode 100644 lib/rpmsecurity.h
 create mode 100644 security/Makefile.am

diff --git a/Makefile.am b/Makefile.am
index f1bcd7c..b3106c5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,7 +29,11 @@ if ENABLE_PLUGINS
 SUBDIRS += plugins
 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

@@ -76,6 +80,8 @@ pkginclude_HEADERS += lib/rpmte.h
 pkginclude_HEADERS += lib/rpmts.h
 pkginclude_HEADERS += lib/rpmtypes.h
 pkginclude_HEADERS += lib/rpmvf.h
+pkginclude_HEADERS += lib/rpmplugins.h
+pkginclude_HEADERS += lib/rpmsecurity.h

 pkginclude_HEADERS += sign/rpmsign.h

diff --git a/configure.ac b/configure.ac
index 2aa190b..16148ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -733,6 +733,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])])
@@ -879,5 +884,6 @@ AC_CONFIG_FILES([Makefile
      luaext/Makefile
      tests/Makefile
      plugins/Makefile
+     security/Makefile
   ])
 AC_OUTPUT
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 356c258..35d3fdb 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -36,7 +36,8 @@ librpm_la_SOURCES = \
     verify.c rpmlock.c rpmlock.h misc.h \
     rpmscript.h rpmscript.c legacy.c merge.c \
     rpmliblua.c rpmliblua.h 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 --git a/lib/fsm.c b/lib/fsm.c
index 3c3cfa2..6939de4 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -28,6 +28,8 @@
 #include "lib/rpmts_internal.h"    /* rpmtsSELabelFoo() only */
 #include "lib/rpmug.h"

+#include "lib/rpmsecurity.h"
+
 #include "debug.h"

 #define    _FSM_DEBUG    0
@@ -800,6 +802,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;
@@ -1639,6 +1646,13 @@ static int fsmStage(FSM_t fsm, fileStage stage)
         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) {
@@ -1650,6 +1664,8 @@ static int fsmStage(FSM_t fsm, fileStage stage)
         (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 --git a/lib/package.c b/lib/package.c
index e1795dd..f13ddf8 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -18,6 +18,8 @@
 #include "rpmio/rpmio_internal.h"    /* fd digest bits */
 #include "lib/header_internal.h"    /* XXX headerCheck */

+#include "lib/rpmsecurity.h"
+
 #include "debug.h"

 static int _print_pkts = 0;
@@ -698,7 +700,10 @@ static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags,

     /** @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. */
     rpmlog(RPMLOG_DEBUG, "%s: %s", fn, msg);
diff --git a/lib/rpmscript.c b/lib/rpmscript.c
index ed52608..52af5d3 100644
--- a/lib/rpmscript.c
+++ b/lib/rpmscript.c
@@ -14,6 +14,8 @@
 #include "rpmio/rpmlua.h"
 #include "lib/rpmscript.h"

+#include "lib/rpmsecurity.h"
+
 #include "debug.h"

 /**
@@ -228,6 +230,12 @@ static rpmRC runExtScript(int selinux, ARGV_const_t prefixes,
     goto exit;
     }

+    if (fn) {
+    // Call security plugin to set policy for the script.
+    if (rpmsecurityCallScriptExec(*argvp))
+        goto exit;
+    }
+
     xx = rpmsqFork(&sq);
     if (sq.child == 0) {
     rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n",
diff --git a/lib/rpmsecurity.c b/lib/rpmsecurity.c
new file mode 100644
index 0000000..88e7a9b
--- /dev/null
+++ b/lib/rpmsecurity.c
@@ -0,0 +1,250 @@
+#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;
+    rpmSecurityHook hooks;
+    int count;
+    rpmts ts;
+};
+
+static rpmSecurity securityPlugin = NULL;
+
+rpmRC rpmsecurityCallInit(const char *opts);
+rpmRC rpmsecurityCallCleanup(void);
+
+static rpmRC rpmsecurityAdd(const char *path, const char *opts, rpmts ts)
+{
+    rpmSecurityHook *supportedHooks;
+    char *error;
+
+    void *handle = dlopen(path, RTLD_LAZY);
+    if (!handle) {
+    rpmlog(RPMLOG_ERR, _("Failed to dlopen %s %s\n"), path, dlerror());
+    return RPMRC_FAIL;
+    }
+
+    /* make sure the plugin has the supported hooks flag */
+    supportedHooks = (rpmSecurityHook *) dlsym(handle, STR(SECURITY_HOOKS));
+    if ((error = dlerror()) != NULL) {
+    rpmlog(RPMLOG_ERR, _("Failed to resolve symbol %s: %s\n"),
+           STR(SECURITY_HOOKS), error);
+    dlclose(handle);
+    return RPMRC_FAIL;
+    }
+
+    securityPlugin = xcalloc(1, sizeof(*securityPlugin));
+    if (!securityPlugin) {
+    rpmlog(RPMLOG_ERR, _("Failed to allocate security plugin %s\n"), path);
+    dlclose(handle);
+    return RPMRC_FAIL;
+    }
+
+    securityPlugin->handle = handle;
+    securityPlugin->hooks = *supportedHooks;
+    securityPlugin->count++;
+    securityPlugin->ts = ts;
+
+    return rpmsecurityCallInit(opts);
+}
+
+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, "")) {
+    rpmlog(RPMLOG_INFO, _("Failed to expand %%__security_plugin macro\n"));
+    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;
+}
+
+/* Common define for all rpmsecurityCall* hook functions */
+#define RPMSECURITY_SET_HOOK_FUNC(hook)                    \
+    char *error;                            \
+    if (!securityPlugin->handle) {                    \
+    rpmlog(RPMLOG_ERR, _("Security plugin not loaded\n"));        \
+    return RPMRC_FAIL;                        \
+    }                                    \
+    if (!(securityPlugin->hooks & hook)) {                \
+    return RPMRC_OK;                        \
+    }                                    \
+    *(void **)(&hookFunc) = dlsym(securityPlugin->handle, STR(hook##_FUNC)); \
+    if ((error = dlerror()) != NULL) {                    \
+    rpmlog(RPMLOG_ERR, _("Failed to resolve security plugin symbol %s: %s\n"), STR(hook##_FUNC), error); \
+    return RPMRC_FAIL;                        \
+    }                                    \
+    if (rpmtsFlags(securityPlugin->ts) & RPMTRANS_FLAG_TEST) {        \
+    return RPMRC_OK;                        \
+    }                                    \
+    rpmlog(RPMLOG_DEBUG, "Security: calling hook %s in security plugin\n", STR(hook##_FUNC));
+
+rpmRC rpmsecurityCallInit(const char *opts)
+{
+    rpmRC (*hookFunc)(rpmts, const char *);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_INIT);
+    return hookFunc(securityPlugin->ts, opts);
+}
+
+rpmRC rpmsecurityCallCleanup(void)
+{
+    rpmRC (*hookFunc)(void);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_CLEANUP);
+    return hookFunc();
+}
+
+rpmRC rpmsecurityCallPreTsm(rpmts ts)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(rpmts);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_PRE_TSM);
+    return hookFunc(ts);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallPostTsm(rpmts ts)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(rpmts);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_POST_TSM);
+    return hookFunc(ts);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallPrePsm(rpmte te)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(rpmte);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_PRE_PSM);
+    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);
+    return hookFunc(te, rpmrc);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallScriptExec(ARGV_const_t argv)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(ARGV_const_t);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_SCRIPT_EXEC);
+    return hookFunc(argv);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallFsmOpened(FSM_t fsm)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(FSM_t);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FSM_OPENED);
+    return hookFunc(fsm);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallFsmUpdated(FSM_t fsm)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(FSM_t);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_FSM_UPDATED);
+    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);
+    return hookFunc(fsm, rpmrc);
+    }
+    return RPMRC_OK;
+}
+
+rpmRC rpmsecurityCallVerify(rpmKeyring keyring, rpmtd sigtd,
+                pgpDig dig, rpmRC rpmrc)
+{
+    if (securityPlugin) {
+    rpmRC (*hookFunc)(rpmKeyring, rpmtd, pgpDig, rpmRC);
+    RPMSECURITY_SET_HOOK_FUNC(SECURITYHOOK_VERIFY);
+    return hookFunc(keyring, sigtd, dig, rpmrc);
+    }
+    return RPMRC_OK;
+}
+
+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);
+    return hookFunc(ts, te, fi, oldHeader, oldFi, rpmrc);
+    }
+    return RPMRC_OK;
+}
diff --git a/lib/rpmsecurity.h b/lib/rpmsecurity.h
new file mode 100644
index 0000000..1f2a1ba
--- /dev/null
+++ b/lib/rpmsecurity.h
@@ -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
+
+#define SECURITY_HOOKS    security_hooks
+
+#define SECURITYHOOK_PRE_TSM_FUNC        securityhook_pre_tsm
+#define SECURITYHOOK_POST_TSM_FUNC        securityhook_post_tsm
+#define SECURITYHOOK_PRE_PSM_FUNC        securityhook_pre_psm
+#define SECURITYHOOK_POST_PSM_FUNC        securityhook_post_psm
+#define SECURITYHOOK_SCRIPT_EXEC_FUNC        securityhook_script_exec
+#define SECURITYHOOK_FSM_OPENED_FUNC        securityhook_fsm_opened
+#define SECURITYHOOK_FSM_UPDATED_FUNC        securityhook_fsm_updated
+#define SECURITYHOOK_FSM_CLOSED_FUNC        securityhook_fsm_closed
+#define SECURITYHOOK_VERIFY_FUNC        securityhook_verify
+#define SECURITYHOOK_FILE_CONFLICT_FUNC        securityhook_file_conflict
+
+enum rpmSecurityhook_e {
+    SECURITYHOOK_NONE        = 0,
+    SECURITYHOOK_INIT        = 1 << 1,
+    SECURITYHOOK_CLEANUP    = 1 << 2,
+    SECURITYHOOK_PRE_TSM    = 1 << 3,
+    SECURITYHOOK_POST_TSM    = 1 << 4,
+    SECURITYHOOK_PRE_PSM    = 1 << 5,
+    SECURITYHOOK_POST_PSM    = 1 << 6,
+    SECURITYHOOK_SCRIPT_EXEC    = 1 << 7,
+    SECURITYHOOK_FSM_OPENED    = 1 << 8,
+    SECURITYHOOK_FSM_UPDATED    = 1 << 9,
+    SECURITYHOOK_FSM_CLOSED    = 1 << 10,
+    SECURITYHOOK_VERIFY        = 1 << 11,
+    SECURITYHOOK_FILE_CONFLICT    = 1 << 12
+};
+
+typedef rpmFlags rpmSecurityHook;
+
+/** \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
+ * Determine if a security plugin has been added already.
+ * @return        1 if security plugin has already been added, 0 otherwise
+ */
+int rpmsecurityPluginAdded(void);
+
+/** \ingroup rpmsecurity
+ * Destroy a plugins structure, calls SECURITYHOOK_CLEANUP_FUNC.
+ * Plugin can save new state and new configuration in cleanup.
+ * @return        NULL always
+ */
+rpmSecurity rpmsecurityFreePlugin(void);
+
+/** \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 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
+ * 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 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 script exec plugin hook.
+ * Here plugin can set security policy for the script before it's executed.
+ * @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 verify plugin hook.
+ * This hook is called right after RPM has verified the 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 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);
+
+#ifdef __cplusplus
+}
+#endif
+#endif    /* _SECURITY_H */
diff --git a/lib/rpmte.c b/lib/rpmte.c
index 860b3f4..2e15e24 100644
--- a/lib/rpmte.c
+++ b/lib/rpmte.c
@@ -14,6 +14,7 @@
 #include <rpm/rpmlog.h>

 #include "lib/rpmplugins.h"
+#include "lib/rpmsecurity.h"
 #include "lib/rpmte_internal.h"

 #include "debug.h"
@@ -908,7 +909,13 @@ int rpmteProcess(rpmte te, pkgGoal goal)
     rpmteRunAllCollections(te, PLUGINHOOK_COLL_PRE_REMOVE);

     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 --git a/lib/rpmts.c b/lib/rpmts.c
index d782ecf..4f83845 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -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"
@@ -630,6 +631,8 @@ rpmts rpmtsFree(rpmts ts)
     ts->installLangs = argvFree(ts->installLangs);

     ts->plugins = rpmpluginsFree(ts->plugins);
+    /* Free security plugin here also. */
+    rpmsecurityFreePlugin();

     if (_rpmts_stats)
     rpmtsPrintStats(ts);
diff --git a/lib/rpmtypes.h b/lib/rpmtypes.h
index 28ee5a9..c4da550 100644
--- a/lib/rpmtypes.h
+++ b/lib/rpmtypes.h
@@ -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 --git a/lib/transaction.c b/lib/transaction.c
index ed6f738..b55bbb5 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -21,6 +21,8 @@
 #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 */
 #if STATFS_IN_SYS_STATVFS
@@ -353,6 +355,9 @@ static int handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi,
         }
     }

+    /* 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),
@@ -1413,6 +1418,9 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
     goto exit;
     }

+    /* Setup the security plugin */
+    rpmsecuritySetupPlugin(ts);
+
     rpmtsSetupCollections(ts);

     /* Check package set for problems */
@@ -1445,9 +1453,15 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
     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 --git a/preinstall.am b/preinstall.am
index 170c94c..caa4543 100644
--- a/preinstall.am
+++ b/preinstall.am
@@ -114,6 +114,14 @@ include/rpm/rpmvf.h: lib/rpmvf.h include/rpm/$(dirstamp)
     $(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 --git a/security/Makefile.am b/security/Makefile.am
new file mode 100644
index 0000000..722793c
--- /dev/null
+++ b/security/Makefile.am
@@ -0,0 +1,14 @@
+# 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}\""
+
+AM_LDFLAGS = -avoid-version -module -shared
+
+pluginsdir = $(libdir)/rpm-plugins
--
1.7.2.3

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rpm.org/pipermail/rpm-maint/attachments/20110121/7ff43b09/attachment-0001.html>


More information about the Rpm-maint mailing list