-
-
Notifications
You must be signed in to change notification settings - Fork 233
/
Copy pathREADME.plugins.html
287 lines (287 loc) · 15.2 KB
/
README.plugins.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice 4.1.2 (Unix)">
<META NAME="CREATED" CONTENT="20130417;16154700">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<META NAME="CHANGED" CONTENT="20160407;19330500">
<META NAME="CHANGEDBY" CONTENT="Alex Peshkoff">
<STYLE TYPE="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</STYLE>
</HEAD>
<BODY LANG="en-US" DIR="LTR">
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Firebird plugins.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Since version 3, Firebird
supports plugins architecture. This means that for a number of
predefined points in Firebird code, user can write his own fragment
of code which will be executed when needed. Plugin is not necessarily
always written by user - Firebird already has a number of plugins
which are its native part. Moreover, as you will see later, some core
parts of Firebird are implemented as plugins. </FONT>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>First of all a few words
about the term “plugin”. Unfortunately, it's often used to define
related but different things. Plugin is used to name:</FONT></P>
<UL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>dynamic library,
containing code to be loaded as plugin (often called plugin module)
and stored in $FIREBIRD/plugins directory;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>code implementing
plugin – slightly different from the library cause single dynamic
library may contain code for more than one plugin;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>plugin's factory - an
object created by that code (pure virtual C++ class), creating
plugin instances on Firebird request;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>instance of plugin,
created by factory.</FONT></P>
</UL>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>In most cases it's clear
from context what “plugin” do we talk about. If not it will be
clarified explicitly.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Firebird plugin
architecture supports creation of any plugin type for any purpose –
but first of all this requires changes in Firebird code. Plugin can't
be added at any desired point “magically”. To be able to have
plugin (for example) encrypting database on the disk, Firebird code
should be prepared for it – must have a point from which plugin is
called. I.e. each version has a fixed set of plugins which are
supported. To add one more type, first of all Firebird code should be
modified. What DOES our plugin architecture – it helps to make both
adding new types of plugins and writing plugin code simple and as
universal between plugins as possible.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Firebird 3 has a following
set of plugin types:</FONT></P>
<UL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>user authentication
related: AuthServer (validates user's credentials on server when use
logins), AuthClient (prepares credentials to be passed over the
wire) and AuthUserManagement (maintains a list of users on a server
in a form, known to AuthServer);</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>ExternalEngine
controls use of various engines, see README.external_routines;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>Trace plugin is known
from Firebird 2.5, but a way how it interacts with engine was
changed to match new generic rules; </FONT>
</P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>encrypting plugins
are for network (WireCrypt) and disk (DbCrypt), there is also helper
plugin KeyHolder, which is used to help maintaining secret key(s)
for DbCrypt;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>and probably the most
important kind – Provider. Firebird 3 supports providers as a kind
of plugins, which has nothing outstanding compared with others. See
README.Providers for more information about providers. </FONT>
</P>
</UL>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Plugins are using a set of
special Firebird interfaces (see Using_OO_API for details). All
plugin-specific interfaces are reference counted, i.e. have
explicitly controlled lifetime. Interfaces are declared in
Interfaces.h include file. There is an example of writing plugin
module – fbSampleDbCrypt. It does not perform any actual encryption
– just a sample of how to write plugin. Complete instruction of how
to write plugins is out of this document's scope. Here is provided a
short list of plugin features:</FONT></P>
<UL>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>plugin may be written
using any language, supporting function pointers in a
structure/record (or at least arrays of function pointers);</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>currently interfaces
description is available only for C++ and Pascal(Delphi), you will
need to write your interfaces declarations generator for your
language if you need something else;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>like with UDFs you
are free to add any reasonable code to your plugin, but pay
attention to word “reasonable” - asking a question from plugin
at server's console is hardly good idea;</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>it's OK to use
Firebird API calls in your plugin if needed (for example, default
authentication server and user manager are using Firebird database
to store accounts);</FONT></P>
<LI><P STYLE="margin-bottom: 0in"><FONT SIZE=4>additionally Firebird
provides a set of interfaces, helping you to configure your plugins
(certainly, you are not forced to use them – plugin is generic
code, which may use any way of providing configuration information,
but with standard tools you get common for the rest of Firebird
configuration style and sooner of all save you efforts).</FONT></P>
</UL>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Configuring plugins has 2
parts – first, engine should be instructed what plugins it should
load, and next plugins themselves sometimes need some configuration.
What plugins to be loaded is defined in main configuration file –
firebird.conf for each type of plugin. Like any other value in
firebird.conf the have defaults:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>AuthServer = Srp</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>AuthClient = Srp,
Win_Sspi, Legacy_Auth</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>UserManager = Srp</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>TracePlugin = fbtrace</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Providers =
Remote,Engine14,Loopback</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>WireCryptPlugin = Arc4</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>This provides normal
operation in server, client and embedded cases. If you want to add
other plugins, you must mention them in firebird.conf – except
other this is security measure to avoid loading unknown code. But
what does for example fbtrace mean here? Is it a name of dynamic
library to load? In trivial case yes, but exact answer is more
complicated.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>As it was already
mentioned, single plugin module may implement more than single
plugin. Moreover, single plugin may have at the same time more than
one configuration – and for each configuration separate plugin's
factory is created. Each of this 3 objects (module – implementation
– factory) has it's own name. Name of a module is a file name of
dynamic library. Plugin implementation's name is one given to it by
plugin developer and hard-coded inside module. Factory's name by
default equals to plugin implementation's name (and it's factory name
which is actually used in firebird.conf). Certainly in typical case,
module contains one plugin, and that plugin works with only one
configuration, and all 3 names are equal, and no more configuration
is needed – for example libEngine14.so or Engine14.dll contains
implementation of provider Engine14, and nothing else except record </FONT>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Providers = Engine14</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>in firebird.conf is needed
to load it. But if you have something complex – configuration file
plugins.conf will help you to have such plugin factories which you
really want.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>File plugins.conf has 2
types of records – config and plugin. Plugin record is a set of
rules for plugin's loading and activating. Plugin record has the
following format:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Plugin = PlugName ##
this is name to be referenced in firebird.conf</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Module = LibName ##
name of dynamic library</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>RegisterName = RegName
## name given to plugin by it's developer</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Config = ConfName ##
name of config record to be used</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>ConfigFile = ConfFile
## name of a file, containing plugin's configuration</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>i.e. when plugin PlugName
is needed Firebird loads library LibName, finds in it plugin
registered with name RegName and passes it configuration from config
record ConfName or config file ConfFile (config record is used if
both are given). Each parameter in this record may be missing, in
that case the default PlugName is used. The only exception is
ConfigFile – by default, file with same name as module's dynamic
library but .conf extension is used. ConfigFile is expected to have
format Key=Value (like other Firebird configuration files), same
format is used for plugin record:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Config = ConfName</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Key1 = Value1</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Key2 = Value2</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>...</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Let's have a sample.
Suppose some clients of your server trust wire encryption from one
vendor and others – from another one (and have different licenses
for appropriate client parts), but each vendor calls his plugin
BestCrypt. Certainly, first of all you have to rename libraries to
something like Crypt1 and Crypt2 – one can't have 2 files with same
name in one directory. But after it, modules stop to load
automatically – they are not named BestCrypt any more. To fix it,
plugins.conf should contain something like this:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Plugin = Crypt1</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>RegisterName =
BestCrypt</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>Plugin = Crypt2</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>{</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>RegisterName =
BestCrypt</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>}</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Module names will be
automatically set to Crypt1 and Crypt2 and found. Certainly you may
add some configuration info for plugins if needed. Also don't forget
to modify firebird.conf:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>WireCryptPlugin =
Crypt1, Crypt2</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>After it server will
automatically select appropriate plugin to talk to client.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Another sample may be
found in distributed with Firebird plugins.conf. One of standard
plugins, UDR, is written to use non-default configuration. Therefore
module name and one configuration parameter are given explicitly.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Questions and answers.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Q. There are plugins named
Remote, Loopback, Arc4 in default configuration, but no libraries
with such names. How do they work?</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>A. That are so-called
'built-in' plugins. They are built into fbclient library, and
therefore are always present. Arrival of such plugins is due to old
ability to distribute windows Firebird client as single dll. It was
decided to keep such feature at least for a case when standard set of
plugins is used.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Q. What do names of Srp
and Arc4 plugins mean?</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>A. Srp implements Secure
Remote Passwords protocol which is default way of authenticating
users in Firebird 3. It has efficient password’s length equal to 20
bytes, resistant to most of attacks (including man in the middle) and
does not require exchanging any keys between client and server to
work. Arc4 means Alleged RC4 - an implementation of RC4 cypher. The
advantage of SRP is that it can generate unique cryptographically
strong key on both client and server and it's impossible to guess it
capturing data transferred over the wire during password validation
by SRP. That key is used after SRP handshake by Arc4, which makes
wire encryption secure without need to exchange any keys between
client and server explicitly.</FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>Q. And what do Win_Sspi
and Legacy_Auth mean?</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>A. Windows SSPI was used
since FB 2.1 for windows trusted authentication. Legacy_Auth is
compatibility plugin. It's enabled by default on client to let it
connect to pre-FB3 servers. (Yes – it still transfers almost plain
passwords over the wire. Compatibility...) On server it works with
security database from FB 2.5, and should be avoided except cases
when you understand well what are you doing. To use Legacy_Auth on
server you should set lower level of network traffic encryption in
firebird.conf:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>WireCrypt = Enabled</I></FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4>or in the worst case:</FONT></P>
<P STYLE="margin-bottom: 0in"><FONT SIZE=4><I>WireCrypt = Disabled</I></FONT></P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
</BODY>
</HTML>