libzypp 17.38.15

PluginSigcheck.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11#include <iostream>
12#include <vector>
13
14#include "PluginSigcheck.h"
15#include <zypp-core/base/StringV.h>
16#include <zypp-core/base/LogTools.h>
17#include <zypp/PluginScript.h>
18
19#undef ZYPP_BASE_LOGGER_LOGGROUP
20#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
21
22 namespace zypp
23{
24 namespace {
25 struct ProtocolError : SigcheckPluginException {
26 ProtocolError( const PluginScript & script_r, const PluginFrame & got_r, std::string_view expected_r )
27 : SigcheckPluginException(str::sprint( script_r.script(),"protocol error: got",got_r.command(),"expected",expected_r ))
28 {
29 if ( got_r.isErrorCommand() && not got_r.body().empty() ) {
30 // An artifical limit for the exception history:
31 static constexpr size_t maxErrorMessageSize = 2048;
32 addHistory( got_r.body().asString( maxErrorMessageSize ) );
33 }
34 }
35 };
36 } // namespace
37
41 struct SigcheckPlugin::Impl
42 {
43 Impl( Pathname script_r )
44 : _script( std::move(script_r) )
45 {}
46 Impl( Pathname script_r, Args args_r )
47 : _script( std::move(script_r), std::move(args_r) )
48 {}
49
50 void launch( const Pathname & chroot_r )
51 {
52 if ( _script.isOpen() )
53 ZYPP_THROW( SigcheckPluginException(str::sprint( _script.script(),"already launched" )) );
54
55 try {
56 _script.openChrooted( chroot_r );
57 {
58 // -> PLUGINBEGIN
59 PluginFrame frame( "PLUGINBEGIN", { {"version","0"} } );
60 _script.send( frame );
61 PluginFrame ret = _script.receive();
62 pDBG( dump(ret) );
63
64 // <- PLUGINSETUP (optional)
65 if ( not ret.isAckCommand() ) {
66 // Optional PLUGINSETUP
67 if ( ret.command() != "PLUGINSETUP" ) {
68 ZYPP_THROW( ProtocolError( _script, ret, "PLUGINSETUP" ) );
69 }
70 if ( ret.hasKey( "sig_extension" ) )
71 _sigExtension = ret.getHeader( "sig_extension" );
72 if ( ret.hasKey( "key_extension" ) )
73 _keyExtension = ret.getHeader( "key_extension" );
74 }
75 }
76 }
77 catch( const zypp::Exception & e ) {
78 _script.close();
79 ZYPP_THROW( SigcheckPluginException(str::sprint( "failed to launch",_script.script() ), e ) );
80 }
81 }
82
83 void sigcheck( const Pathname & data_r, const Pathname & sig_r = Pathname(), const Pathname & key_r = Pathname() ) const
84 {
85 if ( not _script.isOpen() )
86 ZYPP_THROW( SigcheckPluginException(str::sprint( _script.script(),"not launched" )) );
87
88 const Pathname & root { _script.getChroot() };
89 auto sanitizePath = [&root] ( const Pathname & path_r ) -> Pathname {
90 return Pathname::stripprefix( root, path_r );
91 };
92
93 try {
94 // -> SIGCHECK
95 PluginFrame frame( "SIGCHECK" );
96 frame.addHeader( "data", sanitizePath( data_r ).asString() );
97 if ( not sig_r.empty() )
98 frame.addHeader( "sig", sanitizePath( sig_r ).asString() );
99 if ( not key_r.empty() )
100 frame.addHeader( "key", sanitizePath( key_r ).asString() );
101
102 _script.send( frame );
103 PluginFrame ret = _script.receive();
104 pDBG( dump(ret) );
105
106 if ( not ret.isAckCommand() ) {
107 ZYPP_THROW( ProtocolError( _script, ret, "ACK" ) );
108 }
109 }
110 catch( const zypp::Exception & e ) {
111 ZYPP_THROW( SigcheckPluginException(str::sprint( _script.script(),"FAILED" ), e ) );
112 }
113 }
114
115 PluginScript _script;
116 std::string _sigExtension;
117 std::string _keyExtension;
118 };
119
120 std::ostream & operator<<( std::ostream & str, const SigcheckPlugin::Impl & obj )
121 { return str << obj._script; }
122
124
125 SigcheckPlugin::SigcheckPlugin( Pathname script_r )
126 : _pimpl { new Impl( std::move(script_r) ) }
127 {}
128
129 SigcheckPlugin::SigcheckPlugin( Pathname script_r, Args args_r )
130 : _pimpl { new Impl( std::move(script_r), std::move(args_r) ) }
131 {}
132
133 void SigcheckPlugin::launch( const Pathname & chroot_r )
134 { return _pimpl->launch( chroot_r ); }
135
136 std::string SigcheckPlugin::sigExtension() const
137 { return _pimpl->_sigExtension; }
138
139 std::string SigcheckPlugin::keyExtension() const
140 { return _pimpl->_keyExtension; }
141
142 void SigcheckPlugin::sigcheck( const Pathname & data_r, const Pathname & sig_r, const Pathname & key_r ) const
143 { return _pimpl->sigcheck( data_r, sig_r, key_r ); }
144
145 std::ostream & operator<<( std::ostream & str, const SigcheckPlugin & obj )
146 { return str << *obj._pimpl; }
147
149
150 struct SigcheckPlugins::Impl
151 {
152 Impl()
153 {}
154
155 Impl( const std::string & cmdline_r, const Pathname & plugindir_r )
156 {
157 for ( std::string_view cmd : strv::splitBSEscaped( cmdline_r, ";" ) ) {
158 Pathname plugpath;
159 SigcheckPlugin::Args plugargs;
160 for ( std::string_view arg : strv::splitBSEscaped( cmd /*blank*/ ) ) {
161 if ( arg.empty() )
162 continue;
163 if ( plugpath.empty() ) {
164 // Prevent configured arg from escaping the sigcheck directory (bsc#1265223)
165 plugpath = Pathname::assertprefix( plugindir_r / "sigcheck", strv::unBSEscape( arg ) );
166 } else {
167 plugargs.emplace_back( strv::unBSEscape( arg ) );
168 }
169 }
170 if ( not plugpath.empty() ) {
171 if ( plugargs.empty() )
172 _plugins.emplace_back( std::move(plugpath) );
173 else
174 _plugins.emplace_back( std::move(plugpath), std::move(plugargs) );
175 }
176 }
177 }
178
179 explicit operator bool() const
180 { return not _plugins.empty(); }
181
182 void launch( const Pathname & chroot_r = Pathname() )
183 { for ( auto & plugin : _plugins ) plugin.launch( chroot_r ); }
184
185 Plugins _plugins;
186 };
187
188 std::ostream & operator<<( std::ostream & str, const SigcheckPlugins::Impl & obj )
189 { return str << obj._plugins; }
190
192
193 SigcheckPlugins::SigcheckPlugins()
194 : _pimpl { new Impl() }
195 {}
196
197 SigcheckPlugins::SigcheckPlugins( const std::string & cmdline_r, const Pathname & plugindir_r )
198 : _pimpl { new Impl( cmdline_r, plugindir_r ) }
199 {}
200
201 SigcheckPlugins::operator bool() const
202 { return bool(*_pimpl); }
203
204 const SigcheckPlugins::Plugins & SigcheckPlugins::plugins()
205 { return _pimpl->_plugins; }
206
207 void SigcheckPlugins::launch( const Pathname & chroot_r )
208 { return _pimpl->launch( chroot_r ); }
209
210 std::ostream & operator<<( std::ostream & str, const SigcheckPlugins & obj )
211 { return str << *obj._pimpl; }
212
213} // namespace zypp
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
LogTools.h
pDBG
#define pDBG
Definition LogTools.h:314
PluginScript.h
PluginSigcheck.h
StringV.h
bool
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zypp::Pathname::stripprefix
static Pathname stripprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r with any root_r dir prefix striped.
Definition Pathname.cc:293
zypp::Pathname::Pathname
Pathname()
Default ctor: an empty path.
Definition Pathname.h:51
zypp::Pathname::assertprefix
static Pathname assertprefix(const Pathname &root_r, const Pathname &path_r)
Unless path_r does not already denote a path below root_r, combine them.
Definition Pathname.cc:272
zypp::PluginFrame
Command frame for communication with PluginScript.
Definition PluginFrame.h:42
zypp::PluginFrame::command
const std::string & command() const
Return the frame command.
Definition PluginFrame.cc:439
zypp::PluginFrame::addHeader
void addHeader(const std::string &key_r, const std::string &value_r=std::string())
Add header for key_r leaving already existing headers for key_r unchanged.
Definition PluginFrame.cc:481
zypp::PluginFrame::getHeader
const std::string & getHeader(const std::string &key_r) const
Return header value for key_r.
Definition PluginFrame.cc:469
zypp::PluginFrame::isAckCommand
bool isAckCommand() const
Convenience to identify an ACK command.
Definition PluginFrame.h:114
zypp::PluginFrame::hasKey
bool hasKey(const std::string &key_r) const
Whether the header list contains at least one entry for key_r.
Definition PluginFrame.h:184
zypp::PluginScript
Interface to plugin scripts using a Stomp inspired communication protocol.
Definition PluginScript.h:63
zypp::PluginScript::receive
PluginFrame receive() const
Receive a PluginFrame.
Definition PluginScript.cc:556
zypp::PluginScript::getChroot
Pathname getChroot() const
Return a connected scripts chroot or an empty Pathname.
Definition PluginScript.cc:523
zypp::PluginScript::openChrooted
void openChrooted(const Pathname &chroot_r)
Like open() but runs the script chrooted into chroot_r.
Definition PluginScript.cc:547
zypp::PluginScript::send
void send(const PluginFrame &frame_r) const
Send a PluginFrame.
Definition PluginScript.cc:553
zypp::PluginScript::close
int close()
Close any open connection.
Definition PluginScript.cc:550
zypp::PluginScript::script
const Pathname & script() const
Return the script path if set.
Definition PluginScript.cc:511
zypp::PluginScript::isOpen
bool isOpen() const
Whether we are connected to a script.
Definition PluginScript.cc:517
zypp::SigcheckPlugin::sigExtension
std::string sigExtension() const
Extension of a signature file to retrieve.
Definition PluginSigcheck.cc:136
zypp::SigcheckPlugin::_pimpl
RW_pointer< Impl > _pimpl
Definition PluginSigcheck.h:90
zypp::SigcheckPlugin::SigcheckPlugin
SigcheckPlugin(const SigcheckPlugin &)=delete
zypp::SigcheckPlugin::launch
void launch(const Pathname &chroot_r=Pathname())
Launch the plugin.
Definition PluginSigcheck.cc:133
zypp::SigcheckPlugin::sigcheck
void sigcheck(const Pathname &data_r, const Pathname &sig_r=Pathname(), const Pathname &key_r=Pathname()) const
Let plugin do the signature check.
Definition PluginSigcheck.cc:142
zypp::SigcheckPlugin::keyExtension
std::string keyExtension() const
Extension of a key file to retrieve.
Definition PluginSigcheck.cc:139
zypp::SigcheckPlugin::operator<<
friend std::ostream & operator<<(std::ostream &str, const SigcheckPlugin &obj)
Definition PluginSigcheck.cc:145
zypp::SigcheckPlugin::Args
std::vector< std::string > Args
Definition PluginSigcheck.h:62
zypp::SigcheckPlugins::plugins
const Plugins & plugins()
All plugins (their addresses can be captured).
Definition PluginSigcheck.cc:204
zypp::SigcheckPlugins::SigcheckPlugins
SigcheckPlugins(const SigcheckPlugins &)=delete
zypp::SigcheckPlugins::launch
void launch(const Pathname &chroot_r=Pathname())
Launch all plugins (optionally chrooted).
Definition PluginSigcheck.cc:207
zypp::SigcheckPlugins::_pimpl
RW_pointer< Impl > _pimpl
Definition PluginSigcheck.h:141
zypp::SigcheckPlugins::SigcheckPlugins
SigcheckPlugins()
No plugins.
Definition PluginSigcheck.cc:193
zypp::SigcheckPlugins::operator<<
friend std::ostream & operator<<(std::ostream &str, const SigcheckPlugins &obj)
Definition PluginSigcheck.cc:210
zypp::SigcheckPlugins::Plugins
std::vector< SigcheckPlugin > Plugins
Definition PluginSigcheck.h:114
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:48
zypp::filesystem::Pathname::empty
bool empty() const
Test for an empty path.
Definition Pathname.h:117
std
Definition ansi.h:855
str
String related utilities and Regular expression matching.
zypp::str::sprint
std::string sprint(Args &&... args)
Print words as string.
Definition LogTools.h:266
zypp::strv::splitBSEscaped
std::vector< std::string_view > splitBSEscaped(std::string_view line_r, std::string_view chars_r, unsigned maxSplits_r)
Definition StringV.cc:243
zypp::strv::unBSEscape
std::string unBSEscape(std::string_view word_r)
Definition StringV.cc:213
zypp
Easy-to use interface to the ZYPP dependency resolver.
Definition CodePitfalls.doc:2
zypp::dump
detail::Dump< Tp > dump(const Tp &obj_r)
Definition LogTools.h:772
zypp::asString
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
zypp::operator<<
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Definition Capabilities.cc:65
zypp::SigcheckPluginException::SigcheckPluginException
SigcheckPluginException(const Exception &history_r)
Definition PluginSigcheck.h:36
zypp::SigcheckPlugin::Impl
Definition PluginSigcheck.cc:42
zypp::SigcheckPlugin::Impl::_script
PluginScript _script
Definition PluginSigcheck.cc:115
zypp::SigcheckPlugin::Impl::sigcheck
void sigcheck(const Pathname &data_r, const Pathname &sig_r=Pathname(), const Pathname &key_r=Pathname()) const
Definition PluginSigcheck.cc:83
zypp::SigcheckPlugin::Impl::_keyExtension
std::string _keyExtension
Definition PluginSigcheck.cc:117
zypp::SigcheckPlugin::Impl::_sigExtension
std::string _sigExtension
Definition PluginSigcheck.cc:116
zypp::SigcheckPlugin::Impl::Impl
Impl(Pathname script_r, Args args_r)
Definition PluginSigcheck.cc:46
zypp::SigcheckPlugin::Impl::Impl
Impl(Pathname script_r)
Definition PluginSigcheck.cc:43
zypp::SigcheckPlugin::Impl::launch
void launch(const Pathname &chroot_r)
Definition PluginSigcheck.cc:50
zypp::SigcheckPlugins::Impl
Definition PluginSigcheck.cc:151
zypp::SigcheckPlugins::Impl::launch
void launch(const Pathname &chroot_r=Pathname())
Definition PluginSigcheck.cc:182
zypp::SigcheckPlugins::Impl::Impl
Impl()
Definition PluginSigcheck.cc:152
zypp::SigcheckPlugins::Impl::Impl
Impl(const std::string &cmdline_r, const Pathname &plugindir_r)
Definition PluginSigcheck.cc:155
zypp::SigcheckPlugins::Impl::_plugins
Plugins _plugins
Definition PluginSigcheck.cc:185