diff options
author | Elena Reshetova <elena.reshetova@intel.com> | 2013-01-04 12:46:42 +0200 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-02-02 16:44:45 -0800 |
commit | 61613c459b741f11d26531c0795a432c11fbf4e7 (patch) | |
tree | b3867bd575902efb6388d7fb69c37ac151db3361 /lib | |
parent | 86e7c4ecfd94737f5ede5cadcc2600ea654c399f (diff) | |
download | rpm-61613c459b741f11d26531c0795a432c11fbf4e7.tar.gz rpm-61613c459b741f11d26531c0795a432c11fbf4e7.tar.bz2 rpm-61613c459b741f11d26531c0795a432c11fbf4e7.zip |
Adding security msm plugin
Diffstat (limited to 'lib')
-rw-r--r-- | lib/fsm.c | 26 | ||||
-rw-r--r-- | lib/package.c | 9 | ||||
-rw-r--r-- | lib/rpmplugins.c | 72 | ||||
-rw-r--r-- | lib/rpmplugins.h | 62 | ||||
-rw-r--r-- | lib/transaction.c | 9 |
5 files changed, 172 insertions, 6 deletions
@@ -23,6 +23,7 @@ #include "lib/rpmfi_internal.h" /* XXX fi->apath, ... */ #include "lib/rpmte_internal.h" /* XXX rpmfs */ #include "lib/rpmts_internal.h" /* rpmtsSELabelFoo() only */ +#include "lib/rpmplugins.h" /* rpm plugins hooks */ #include "lib/rpmug.h" #include "lib/cpio.h" @@ -108,6 +109,7 @@ struct fsm_s { const char * dirName; /*!< File directory name. */ const char * baseName; /*!< File base name. */ struct selabel_handle *sehandle; /*!< SELinux label handle (if any). */ + rpmPlugins plugins; /*!< Rpm plugins handle */ unsigned fflags; /*!< File flags. */ rpmFileAction action; /*!< File disposition. */ @@ -1151,9 +1153,10 @@ static int fsmMknod(const char *path, mode_t mode, dev_t dev) * Create (if necessary) directories not explicitly included in package. * @param dnli file state machine data * @param sehandle selinux label handle (bah) + * @param plugins rpm plugins handle * @return 0 on success */ -static int fsmMkdirs(rpmfi fi, rpmfs fs, struct selabel_handle *sehandle) +static int fsmMkdirs(rpmfi fi, rpmfs fs, struct selabel_handle *sehandle, rpmPlugins plugins) { DNLI_t dnli = dnlInitIterator(fi, fs, 0); struct stat sb; @@ -1221,6 +1224,10 @@ static int fsmMkdirs(rpmfi fi, rpmfs fs, struct selabel_handle *sehandle) "%s directory created with perms %04o\n", dn, (unsigned)(mode & 07777)); } + if (!rc) { + /* Run file closed hook for all plugins */ + rc = rpmpluginsCallFsmCommit(plugins, dn, mode, DIR_TYPE_UNOWNED); + } *te = '/'; } if (rc) @@ -1551,6 +1558,10 @@ static int fsmCommit(FSM_t fsm, int ix) if (!rc && !getuid()) { rc = fsmSetSELabel(fsm->sehandle, fsm->path, fsm->sb.st_mode); } + /* Call fsm commit hook for all plugins */ + if (!rc) { + rc = rpmpluginsCallFsmCommit(fsm->plugins, fsm->path, fsm->sb.st_mode, DIR_TYPE_NORMAL); + } if (S_ISLNK(st->st_mode)) { if (!rc && !getuid()) rc = fsmLChown(fsm->path, fsm->sb.st_uid, fsm->sb.st_gid); @@ -1640,12 +1651,14 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd, rc = CPIOERR_INTERNAL; fsm->sehandle = rpmtsSELabelHandle(ts); + fsm->plugins = rpmtsPlugins(ts); + /* transaction id used for temporary path suffix while installing */ rasprintf(&fsm->suffix, ";%08x", (unsigned)rpmtsGetTid(ts)); /* Detect and create directories not explicitly in package. */ if (!rc) { - rc = fsmMkdirs(fi, rpmteGetFileStates(te), fsm->sehandle); + rc = fsmMkdirs(fi, rpmteGetFileStates(te), fsm->sehandle, fsm->plugins); } while (!rc) { @@ -1684,6 +1697,15 @@ int rpmPackageFilesInstall(rpmts ts, rpmte te, rpmfi fi, FD_t cfd, break; } + /* Run fsm init hook for all plugins */ + rc = rpmpluginsCallFsmInit(fsm->plugins, fsm->path, fsm->sb.st_mode); + + /* Exit on error. */ + if (rc) { + fsm->postpone = 1; + break; + } + if (S_ISREG(fsm->sb.st_mode) && fsm->sb.st_nlink > 1) fsm->postpone = saveHardLink(fsm, &li); diff --git a/lib/package.c b/lib/package.c index b6bea09c7..157c96900 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/rpmplugins.h" /* rpm plugins hooks */ + #include "debug.h" static const unsigned int nkeyids_max = 256; @@ -495,7 +497,7 @@ rpmRC rpmReadHeader(rpmts ts, FD_t fd, Header *hdrp, char ** msg) return rc; } -static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags, +static rpmRC rpmpkgRead(rpmPlugins plugins, rpmKeyring keyring, rpmVSFlags vsflags, FD_t fd, const char * fn, Header * hdrp) { pgpDigParams sig = NULL; @@ -646,6 +648,9 @@ static rpmRC rpmpkgRead(rpmKeyring keyring, rpmVSFlags vsflags, /** @todo Implement disable/enable/warn/error/anal policy. */ rc = rpmVerifySignature(keyring, &sigtd, sig, ctx, &msg); + + /* Run verify hook for all plugins */ + rc = rpmpluginsCallVerify(plugins, keyring, &sigtd, sig, ctx, rc); switch (rc) { case RPMRC_OK: /* Signature is OK. */ @@ -714,7 +719,7 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp) rpmVSFlags vsflags = rpmtsVSFlags(ts); rpmKeyring keyring = rpmtsGetKeyring(ts, 1); - rc = rpmpkgRead(keyring, vsflags, fd, fn, hdrp); + rc = rpmpkgRead(rpmtsPlugins(ts), keyring, vsflags, fd, fn, hdrp); rpmKeyringFree(keyring); diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c index d5ab09a9d..2d4fb01cd 100644 --- a/lib/rpmplugins.c +++ b/lib/rpmplugins.c @@ -314,3 +314,75 @@ rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int ty return rc; } + +rpmRC rpmpluginsCallVerify(rpmPlugins plugins, rpmKeyring keyring, rpmtd sigtd, + pgpDigParams sig, DIGEST_CTX ctx, int res) +{ + rpmRC (*hookFunc)(rpmKeyring, rpmtd, pgpDigParams, DIGEST_CTX, int); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_VERIFY); + if (hookFunc(keyring, sigtd, sig, ctx, res) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallFsmInit(rpmPlugins plugins, const char* path, + mode_t mode) +{ + rpmRC (*hookFunc)(const char*, mode_t); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_FSM_INIT); + if (hookFunc(path, mode) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallFsmCommit(rpmPlugins plugins, const char* path, + mode_t mode, int type) +{ + rpmRC (*hookFunc)(const char*, mode_t, int); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_FSM_COMMIT); + if (hookFunc(path, mode, type) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} + +rpmRC rpmpluginsCallFileConflict(rpmPlugins plugins, rpmts ts, char* path, + Header oldHeader, rpmfi oldFi, int res) +{ + rpmRC (*hookFunc)(rpmts, char*, Header, rpmfi, int); + int i; + rpmRC rc = RPMRC_OK; + const char *name = NULL; + + for (i = 0; i < plugins->count; i++) { + name = plugins->names[i]; + RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_FILE_CONFLICT); + if (hookFunc(ts, path, oldHeader, oldFi, res) == RPMRC_FAIL) + rc = RPMRC_FAIL; + } + + return rc; +} diff --git a/lib/rpmplugins.h b/lib/rpmplugins.h index cff3e6cc1..8e35d81ab 100644 --- a/lib/rpmplugins.h +++ b/lib/rpmplugins.h @@ -22,11 +22,16 @@ extern "C" { #define PLUGINHOOK_PSM_PRE_FUNC pluginhook_psm_pre #define PLUGINHOOK_PSM_POST_FUNC pluginhook_psm_post +#define PLUGINHOOK_VERIFY_FUNC pluginhook_verify #define PLUGINHOOK_SCRIPTLET_PRE_FUNC pluginhook_scriptlet_pre #define PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC pluginhook_scriptlet_fork_post #define PLUGINHOOK_SCRIPTLET_POST_FUNC pluginhook_scriptlet_post +#define PLUGINHOOK_FSM_INIT_FUNC pluginhook_fsm_init +#define PLUGINHOOK_FSM_COMMIT_FUNC pluginhook_fsm_commit +#define PLUGINHOOK_FILE_CONFLICT pluginhook_file_conflict + enum rpmPluginHook_e { PLUGINHOOK_NONE = 0, PLUGINHOOK_INIT = 1 << 0, @@ -41,9 +46,21 @@ enum rpmPluginHook_e { PLUGINHOOK_PSM_POST = 1 << 9, PLUGINHOOK_SCRIPTLET_PRE = 1 << 10, PLUGINHOOK_SCRIPTLET_FORK_POST = 1 << 11, - PLUGINHOOK_SCRIPTLET_POST = 1 << 12 + PLUGINHOOK_SCRIPTLET_POST = 1 << 12, + PLUGINHOOK_VERIFY = 1 << 13, + PLUGINHOOK_FSM_INIT = 1 << 14, + PLUGINHOOK_FSM_COMMIT = 1 << 15, + PLUGINHOOK_FILE_CONFLICT = 1 << 16 + }; +/* indicates if a directory is part of rpm package or created by rpm itself */ +typedef enum rpmPluginDirType_e { + DIR_TYPE_NONE = 0, + DIR_TYPE_NORMAL = 1 << 0, + DIR_TYPE_UNOWNED = 1 << 1 +} rpmPluginDirType; + /* indicates the way the scriptlet is executed */ typedef enum rpmScriptletExecutionFlow_e { RPMSCRIPTLET_NONE = 0, @@ -207,6 +224,49 @@ rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int */ rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int type, int res); +/** \ingroup rpmplugins + * Call the verify hook + * @param plugins plugins structure + * @param keyring RPM keyring + * @param sigtd signature tag + * @param sig OpenPGP signature parameters + * @param res scriptlet execution result code + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallVerify(rpmPlugins plugins, rpmKeyring keyring, rpmtd sigtd, + pgpDigParams sig, DIGEST_CTX ctx, int res); + +/** \ingroup rpmplugins + * Call the fsm init hook + * @param plugins plugins structure + * @param path file full path + * @param mode file mode + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallFsmInit(rpmPlugins plugins, const char* path, mode_t mode); + +/** \ingroup rpmplugins + * Call the fsm commit hook + * @param plugins plugins structure + * @param path file full path + * @param mode file mode + * @param type file type + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallFsmCommit(rpmPlugins plugins, const char* path, mode_t mode, int type); + +/** \ingroup rpmplugins + * Call the fsm commit hook + * @param plugins plugins structure + * @param ts transaction set + * @param path new file path + * @param oldHeader old header + * @param oldFi old file + * @param res return code + * @return RPMRC_OK on success, RPMRC_FAIL otherwise + */ +rpmRC rpmpluginsCallFileConflict(rpmPlugins plugins, rpmts ts, char* path, Header oldHeader, rpmfi oldFi, int res); + #ifdef __cplusplus } #endif diff --git a/lib/transaction.c b/lib/transaction.c index 3a7cb740c..659a08656 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -421,9 +421,16 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, int fx, rState = RPMFILE_STATE_WRONGCOLOR; } + if (rConflicts) { + char *path = rpmfiFNIndex(fi, fx); + /* Call file conflict hook for all plugins */ + rpmpluginsCallFileConflict(ts->plugins, ts, path, otherHeader, otherFi, rConflicts); + } + /* Somebody used The Force, lets shut up... */ - if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES) + if (rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEOLDFILES) { rConflicts = 0; + } if (rConflicts) { char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA); |