libzypp 17.38.8
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"
17#include <zypp/PluginScript.h>
18
19#undef ZYPP_BASE_LOGGER_LOGGROUP
20#define ZYPP_BASE_LOGGER_LOGGROUP "zypp::plugin"
21
22namespace 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
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
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
126 : _pimpl { new Impl( std::move(script_r) ) }
127 {}
128
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
137 { return _pimpl->_sigExtension; }
138
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
151 {
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 plugpath = plugindir_r / "sigcheck" / strv::unBSEscape( arg );
165 } else {
166 plugargs.emplace_back( strv::unBSEscape( arg ) );
167 }
168 }
169 if ( not plugpath.empty() ) {
170 if ( plugargs.empty() )
171 _plugins.emplace_back( std::move(plugpath) );
172 else
173 _plugins.emplace_back( std::move(plugpath), std::move(plugargs) );
174 }
175 }
176 }
177
178 explicit operator bool() const
179 { return not _plugins.empty(); }
180
181 void launch( const Pathname & chroot_r = Pathname() )
182 { for ( auto & plugin : _plugins ) plugin.launch( chroot_r ); }
183
185 };
186
187 std::ostream & operator<<( std::ostream & str, const SigcheckPlugins::Impl & obj )
188 { return str << obj._plugins; }
189
191
195
196 SigcheckPlugins::SigcheckPlugins( const std::string & cmdline_r, const Pathname & plugindir_r )
197 : _pimpl { new Impl( cmdline_r, plugindir_r ) }
198 {}
199
200 SigcheckPlugins::operator bool() const
201 { return bool(*_pimpl); }
202
204 { return _pimpl->_plugins; }
205
206 void SigcheckPlugins::launch( const Pathname & chroot_r )
207 { return _pimpl->launch( chroot_r ); }
208
209 std::ostream & operator<<( std::ostream & str, const SigcheckPlugins & obj )
210 { return str << *obj._pimpl; }
211
212} // namespace zypp
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
#define pDBG
Definition LogTools.h:304
Base class for Exception.
Definition Exception.h:153
static Pathname stripprefix(const Pathname &root_r, const Pathname &path_r)
Return path_r with any root_r dir prefix striped.
Definition Pathname.cc:281
Command frame for communication with PluginScript.
Definition PluginFrame.h:42
const std::string & command() const
Return the frame command.
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.
const std::string & getHeader(const std::string &key_r) const
Return header value for key_r.
bool isAckCommand() const
Convenience to identify an ACK command.
bool hasKey(const std::string &key_r) const
Whether the header list contains at least one entry for key_r.
Interface to plugin scripts using a Stomp inspired communication protocol.
std::string sigExtension() const
Extension of a signature file to retrieve.
RW_pointer< Impl > _pimpl
SigcheckPlugin(const SigcheckPlugin &)=delete
void launch(const Pathname &chroot_r=Pathname())
Launch the plugin.
void sigcheck(const Pathname &data_r, const Pathname &sig_r=Pathname(), const Pathname &key_r=Pathname()) const
Let plugin do the signature check.
std::string keyExtension() const
Extension of a key file to retrieve.
std::vector< std::string > Args
const Plugins & plugins()
All plugins (their addresses can be captured).
SigcheckPlugins(const SigcheckPlugins &)=delete
void launch(const Pathname &chroot_r=Pathname())
Launch all plugins (optionally chrooted).
RW_pointer< Impl > _pimpl
std::vector< SigcheckPlugin > Plugins
bool empty() const
Test for an empty path.
Definition Pathname.h:117
Definition ansi.h:855
String related utilities and Regular expression matching.
std::string sprint(Args &&... args)
Print words as string.
Definition LogTools.h:266
std::vector< std::string_view > splitBSEscaped(std::string_view line_r, std::string_view chars_r, unsigned maxSplits_r)
Definition StringV.cc:243
std::string unBSEscape(std::string_view word_r)
Definition StringV.cc:213
Easy-to use interface to the ZYPP dependency resolver.
detail::Dump< Tp > dump(const Tp &obj_r)
Definition LogTools.h:762
std::string asString(const Patch::Category &obj)
relates: Patch::Category string representation.
Definition Patch.cc:122
std::ostream & operator<<(std::ostream &str, const Capabilities &obj)
relates: Capabilities Stream output
Exception thrown by SigcheckPlugins.
void sigcheck(const Pathname &data_r, const Pathname &sig_r=Pathname(), const Pathname &key_r=Pathname()) const
Impl(Pathname script_r, Args args_r)
void launch(const Pathname &chroot_r)
void launch(const Pathname &chroot_r=Pathname())
Impl(const std::string &cmdline_r, const Pathname &plugindir_r)