#
SET(LIBZYPP_MAJOR "17")
SET(LIBZYPP_COMPATMINOR "12")
-SET(LIBZYPP_MINOR "18")
-SET(LIBZYPP_PATCH "1")
+SET(LIBZYPP_MINOR "19")
+SET(LIBZYPP_PATCH "0")
#
-# LAST RELEASED: 17.18.1 (12)
+# LAST RELEASED: 17.19.0 (12)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
-------------------------------------------------------------------
+Wed Dec 11 09:51:10 CET 2019 - ma@suse.de
+
+- MediaCurl: assert cookie file has mode 0600 (bsc#1158763, CVE-2019-18900)
+- version 17.19.0 (12)
+
+-------------------------------------------------------------------
Mon Dec 9 10:22:56 CET 2019 - ma@suse.de
- dup: fix removing orphaned packages dropped by to-be-installed
history.clear();
parser.readAll();
- BOOST_CHECK_EQUAL( history.size(), 8 );
+ BOOST_CHECK_EQUAL( history.size(), 9 );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRepoAdd> ( history[0] ) );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataInstall> ( history[1] ) );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataInstall> ( history[2] ) );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataRemove> ( history[5] ) );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogData> ( history[6] ) );
BOOST_CHECK( dynamic_pointer_cast<HistoryLogDataStampCommand> ( history[7] ) );
+ BOOST_CHECK( dynamic_pointer_cast<HistoryLogPatchStateChange> ( history[8] ) );
BOOST_CHECK_EQUAL( (*history[1])[HistoryLogDataInstall::USERDATA_INDEX], "trans|ID" ); // properly (un)escaped?
HistoryLogDataInstall::Ptr p = dynamic_pointer_cast<HistoryLogDataInstall>( history[1] );
discard\|one field
discard|to fields but bad date
2015-08-11 18:42:49|command|root@fibonacci|'/Local/ma/zypp/BUILD/zypper/src/zypper' 'in' '-f' 'xteddy'|
+2011-07-18 18:08:09|pstate|patch-name|2.6.37.6-0.5.1|noarch|repo-update|moderate|security|needed|satisfied
void HistoryLog::install( const PoolItem & pi )
{
+ if ( ! pi.isKind<Package>() ) return;
const Package::constPtr p = asKind<Package>(pi.resolvable());
- if (!p)
- return;
_log
<< timestamp() // 1 timestamp
void HistoryLog::remove( const PoolItem & pi )
{
+ if ( ! pi.isKind<Package>() ) return;
const Package::constPtr p = asKind<Package>(pi.resolvable());
- if (!p)
- return;
_log
<< timestamp() // 1 timestamp
}
}
+ void HistoryLog::patchStateChange( const PoolItem & pi, const std::string &oldstate )
+ {
+ if ( ! pi.isKind<Patch>() ) return;
+ const Patch::constPtr p = asKind<Patch>(pi.resolvable());
+
+ _log
+ << timestamp() // 1 timestamp
+ << _sep << HistoryActionID::PATCH_STATE_CHANGE.asString(true) // 2 action
+ << _sep << p->name() // 3 name
+ << _sep << p->edition() // 4 evr
+ << _sep << p->arch() // 5 arch
+ << _sep << p->repoInfo().alias() // 6 repo alias
+ << _sep << p->severity() // 7 severity
+ << _sep << p->category() // 8 category
+ << _sep << oldstate // 9 old state
+ << _sep << pi.patchStatusAsString() // 10 new state
+ << _sep << str::escape(ZConfig::instance().userData(), _sep) // 11 userdata
+ << endl;
+ }
+
///////////////////////////////////////////////////////////////////
} // namespace zypp
* \param newrepo info about the new repository
*/
void modifyRepository( const RepoInfo & oldrepo, const RepoInfo & newrepo );
+
+ /**
+ * Log state changes in patches
+ *
+ * \param oldstate info about the old state
+ */
+ void patchStateChange ( const PoolItem & pi, const std::string &oldstate );
+
};
///////////////////////////////////////////////////////////////////
const HistoryActionID HistoryActionID::REPO_CHANGE_ALIAS (HistoryActionID::REPO_CHANGE_ALIAS_e);
const HistoryActionID HistoryActionID::REPO_CHANGE_URL (HistoryActionID::REPO_CHANGE_URL_e);
const HistoryActionID HistoryActionID::STAMP_COMMAND (HistoryActionID::STAMP_COMMAND_e);
+ const HistoryActionID HistoryActionID::PATCH_STATE_CHANGE (HistoryActionID::PATCH_STATE_CHANGE_e);
HistoryActionID::HistoryActionID(const std::string & strval_r)
: _id(parse(strval_r))
_table["ralias"] = REPO_CHANGE_ALIAS_e;
_table["rurl"] = REPO_CHANGE_URL_e;
_table["command"] = STAMP_COMMAND_e;
+ _table["pstate"] = PATCH_STATE_CHANGE_e;
_table["NONE"] = _table["none"] = NONE_e;
}
_table[REPO_CHANGE_ALIAS_e] = PairType( "ralias" , "ralias " );
_table[REPO_CHANGE_URL_e] = PairType( "rurl" , "rurl " );
_table[STAMP_COMMAND_e] = PairType( "command" , "command" );
+ _table[PATCH_STATE_CHANGE_e]= PairType( "pstate" , "pstate " );
_table[NONE_e] = PairType( "NONE" , "NONE " );
}
OUTS( REPO_CHANGE_ALIAS_e, HistoryLogDataRepoAliasChange );
OUTS( REPO_CHANGE_URL_e, HistoryLogDataRepoUrlChange );
OUTS( STAMP_COMMAND_e, HistoryLogDataStampCommand );
+ OUTS( PATCH_STATE_CHANGE_e, HistoryLogPatchStateChange );
#undef OUTS
// intentionally no default:
case HistoryActionID::NONE_e:
CheckSum HistoryLogDataInstall::checksum() const { return optionalAt( CHEKSUM_INDEX ); }
std::string HistoryLogDataInstall::userdata() const { return optionalAt( USERDATA_INDEX ); }
+ ///////////////////////////////////////////////////////////////////
+ // class HistoryLogPatchStateChange
+ ///////////////////////////////////////////////////////////////////
+ HistoryLogPatchStateChange::HistoryLogPatchStateChange( FieldVector & fields_r )
+ : HistoryLogData( fields_r )
+ {}
+ std::string HistoryLogPatchStateChange::name() const { return optionalAt( NAME_INDEX ); }
+ Edition HistoryLogPatchStateChange::edition() const { return Edition( optionalAt( EDITION_INDEX ) ); }
+ Arch HistoryLogPatchStateChange::arch() const { return Arch( optionalAt( ARCH_INDEX ) ); }
+ std::string HistoryLogPatchStateChange::repoAlias() const { return optionalAt( REPOALIAS_INDEX ); }
+ Patch::SeverityFlag HistoryLogPatchStateChange::severity() const { return Patch::severityFlag( optionalAt( SEVERITY_INDEX ) ); }
+ Patch::Category HistoryLogPatchStateChange::category() const { return Patch::categoryEnum( optionalAt( CATEGORY_INDEX ) ); }
+ string HistoryLogPatchStateChange::oldstate() const { return optionalAt( OLDSTATE_INDEX ); }
+ string HistoryLogPatchStateChange::newstate() const { return optionalAt( NEWSTATE_INDEX ); }
+ std::string HistoryLogPatchStateChange::userdata() const { return optionalAt( USERDATA_INDEX ); }
+
///////////////////////////////////////////////////////////////////
// class HistoryLogDataRemove
///////////////////////////////////////////////////////////////////
#include "zypp/Arch.h"
#include "zypp/CheckSum.h"
#include "zypp/Url.h"
+#include "zypp/Patch.h"
#define HISTORY_LOG_DATE_FORMAT "%Y-%m-%d %H:%M:%S"
static const HistoryActionID REPO_CHANGE_ALIAS;
static const HistoryActionID REPO_CHANGE_URL;
static const HistoryActionID STAMP_COMMAND;
+ static const HistoryActionID PATCH_STATE_CHANGE;
enum ID
{
REPO_REMOVE_e,
REPO_CHANGE_ALIAS_e,
REPO_CHANGE_URL_e,
- STAMP_COMMAND_e
+ STAMP_COMMAND_e,
+ PATCH_STATE_CHANGE_e
};
HistoryActionID() : _id(NONE_e) {}
std::string userdata() const; ///< userdata/transactionID
};
+ //PATCH SEVERITY CATEGORY OLDSTATE NEWSTATE
+ ///////////////////////////////////////////////////////////////////
+ /// \class HistoryLogPatchStateChange
+ /// \brief A zypp history log line for an installed packaged.
+ /// \ingroup g_ZyppHistory
+ ///////////////////////////////////////////////////////////////////
+ class HistoryLogPatchStateChange : public HistoryLogData
+ {
+ public:
+ typedef shared_ptr<HistoryLogPatchStateChange> Ptr;
+ typedef shared_ptr<const HistoryLogPatchStateChange> constPtr;
+ /** Ctor \b moving \a FieldVector (via swap).
+ * \throws ParseException if \a fields_r has the wrong \ref HistoryActionID or number of fields.
+ */
+ HistoryLogPatchStateChange( FieldVector & fields_r );
+
+ public:
+ enum Index ///< indices of known fields
+ {
+ DATE_INDEX = HistoryLogData::DATE_INDEX,
+ ACTION_INDEX = HistoryLogData::ACTION_INDEX,
+ NAME_INDEX, ///< patch name
+ EDITION_INDEX, ///< patch edition
+ ARCH_INDEX, ///< patch architecture
+ REPOALIAS_INDEX, ///< repository providing the patch
+ SEVERITY_INDEX, ///< patch severity
+ CATEGORY_INDEX, ///< patch category
+ OLDSTATE_INDEX, ///< the state of the patch before the change
+ NEWSTATE_INDEX, ///< the state of the patch after the change
+ USERDATA_INDEX, ///< userdata/transactionID
+ };
+
+ public:
+ std::string name() const; ///< package name
+ Edition edition() const; ///< package edition
+ Arch arch() const; ///< package architecture
+ std::string repoAlias() const; ///< repository providing the package
+ Patch::SeverityFlag severity() const;
+ Patch::Category category() const;
+ std::string oldstate() const;
+ std::string newstate() const;
+ std::string userdata() const; ///< userdata/transactionID
+ };
+
+
///////////////////////////////////////////////////////////////////
/// \class HistoryLogDataRemove
/// \brief A zypp history log line for a removed packge.
return logResult( 0 );
}
+ int assert_file_mode( const Pathname & path, unsigned mode )
+ {
+ int ret = assert_dir( path.dirname() );
+ MIL << "assert_file_mode " << str::octstring( mode ) << " " << path;
+ if ( ret != 0 )
+ return logResult( ret );
+
+ PathInfo pi( path );
+ if ( pi.isExist() )
+ {
+ if ( ! pi.isFile() )
+ return logResult( EEXIST );
+
+ mode = applyUmaskTo( mode );
+ if ( pi.st_mode() != mode )
+ return chmod( path, mode );
+
+ return logResult( 0 );
+ }
+
+ int fd = ::creat( path.c_str(), mode );
+ if ( fd == -1 )
+ return logResult( errno );
+ ::close( fd );
+ return logResult( 0 );
+ }
+
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : touch
* @return 0 on success, errno on failure
**/
int assert_file( const Pathname & path, unsigned mode = 0644 );
+ /**
+ * Like \ref assert_file but enforce \a mode even if the file already exists.
+ */
+ int assert_file_mode( const Pathname & path, unsigned mode = 0644 );
/**
* Change file's modification and access times.
return isBroken() && status().isLocked();
}
+ std::string patchStatusAsString() const
+ {
+ if ( isUndetermined() ) return "undetermined";
+ if ( isRelevant() ) return "relevant";
+ if ( isSatisfied() ) return "satisfied";
+ if ( isBroken() ) return "broken";
+ if ( isNeeded() ) return "needed";
+ if ( isUnwanted() ) return "unwanted";
+ return "none";
+ }
+
private:
mutable ResStatus _status;
ResObject::constPtr _resolvable;
bool PoolItem::isBroken() const { return _pimpl->isBroken(); }
bool PoolItem::isNeeded() const { return _pimpl->isNeeded(); }
bool PoolItem::isUnwanted() const { return _pimpl->isUnwanted(); }
+ std::string PoolItem::patchStatusAsString() const { return _pimpl->patchStatusAsString(); }
+
void PoolItem::saveState() const { _pimpl->saveState(); }
void PoolItem::restoreState() const { _pimpl->restoreState(); }
bool PoolItem::sameState() const { return _pimpl->sameState(); }
/** Broken (needed) but locked patches. */
bool isUnwanted() const;
+
+ std::string patchStatusAsString () const;
+
//@}
//@}
*---------------------------------------------------------------*/
_currentCookieFile = _cookieFile.asString();
+ filesystem::assert_file_mode( _currentCookieFile, 0600 );
if ( str::strToBool( _url.getQueryParam( "cookies" ), true ) )
SET_OPTION(CURLOPT_COOKIEFILE, _currentCookieFile.c_str() );
else