1RPC::PlServer(3) User Contributed Perl Documentation RPC::PlServer(3)
2
3
4
6 RPC::PlServer - Perl extension for writing PlRPC servers
7
9 # Create a subclass of RPC::PlServer
10 use RPC::PlServer;
11
12 package MyServer;
13 $MyServer::VERSION = '0.01';
14 @MyServer::ISA = qw(RPC::PlServer);
15
16 # Overwrite the Run() method to handle a single connection
17 sub Run {
18 my $self = shift;
19 my $socket = $self->{'socket'};
20 }
21
22 # Create an instance of the MyServer class
23 package main;
24 my $server = MyServer->new({'localport' => '1234'}, \@ARGV);
25
26 # Bind the server to its port to make it actually running
27 $server->Bind();
28
30 PlRPC (Perl RPC) is a package for implementing servers and clients that
31 are written in Perl entirely. The name is borrowed from Sun's RPC
32 (Remote Procedure Call), but it could as well be RMI like Java's
33 "Remote Method Interface), because PlRPC gives you the complete power
34 of Perl's OO framework in a very simple manner.
35
36 RPC::PlServer is the package used on the server side, and you guess
37 what RPC::PlClient is for. Both share the package RPC::PlServer::Comm
38 for communication purposes. See PlRPC::Client(3) and
39 RPC::PlServer::Comm for these parts.
40
41 PlRPC works by defining a set of methods that may be executed by the
42 client. For example, the server might offer a method "multiply" to the
43 client. Now the clients method call
44
45 @result = $client->multiply($a, $b);
46
47 will be immediately mapped to a method call
48
49 @result = $server->multiply($a, $b);
50
51 on the server. The arguments and results will be transferred to or from
52 the server automagically. (This magic has a name in Perl: It's the
53 Storable module, my thanks to Raphael Manfredi for this excellent
54 package.) Simple, eh? :-)
55
56 The RPC::PlServer and RPC::PlClient are abstract servers and clients:
57 You have to derive your own classes from it.
58
59 Additional options
60 The RPC::PlServer inherits all of Net::Daemon's options and attributes
61 and adds the following:
62
63 cipher The attribute value is an instance of Crypt::DES, Crypt::IDEA
64 or any other class with the same API for block encryption. If
65 you supply such an attribute, the traffic between client and
66 server will be encrypted using this option.
67
68 maxmessage (--maxmessage=size)
69 The size of messages exchanged between client and server is
70 restricted, in order to omit denial of service attacks. By
71 default the limit is 65536 bytes.
72
73 users This is an attribute of the client object used for Permit/Deny
74 rules in the config file. It's value is an array ref of user
75 names that are allowed to connect from the given client. See
76 the example config file below. "CONFIGURATION FILE".
77
78 Error Handling
79 Error handling is simple with the RPC package, because it is based on
80 Perl exceptions completely. Thus your typical code looks like this:
81
82 eval {
83 # Do something here. Don't care for errors.
84 ...
85 };
86 if ($@) {
87 # An error occurred.
88 ...
89 }
90
91 Server Constructors
92 my $server = RPC::PlServer(\%options, \@args);
93
94 (Class method) This constructor is immediately inherited from the
95 Net::Daemon package. See Net::Daemon(3) for details.
96
97 Access Control
98 $ok = $self->AcceptApplication($app);
99 $ok = $self->AcceptVersion($version);
100 $ok = $self->AcceptUser($user, $password);
101
102 The RPC::PlServer package has a very detailed access control scheme:
103 First of all it inherits Net::Daemon's host based access control. It
104 adds version control and user authorization. To achieve that, the
105 method Accept from Net::Daemon is split into three methods,
106 AcceptApplication, AcceptVersion and AcceptUser, each of them returning
107 TRUE or FALSE. The client receives the arguments as the attributes
108 application, version, user and password. A client is accepted only if
109 all of the above methods are returning TRUE.
110
111 The default implementations are as follows: The AcceptApplication
112 method returns TRUE, if $self is a subclass of $app. The AcceptVersion
113 method returns TRUE, if the requested version is less or equal to
114 ${$class}::VERSION, $self being an instance of $class. Whether a user
115 is permitted to connect depends on the client configuration. See
116 "CONFIGURATION FILE" below for examples.
117
118 Method based access control
119 Giving a client the ability to invoke arbitrary methods can be a
120 terrible security hole. Thus the server has a methods attribute. This
121 is a hash ref of class names as keys, the values being hash refs again
122 with method names as the keys. That is, if your hash looks as follows:
123
124 $self->{'methods'} = {
125 'CalcServer' => {
126 'NewHandle' => 1,
127 'CallMethod' => 1 },
128 'Calculator' => {
129 'new' => 1,
130 'multiply' => 1,
131 'add' => 1,
132 'divide' => 1,
133 'subtract' => 1 }
134 };
135
136 then the client may use the CalcServer's NewHandle method to create
137 objects, but only via the permitted constructor Calculator->new. Once a
138 Calculator object is created, the server may invoke the methods
139 multiply, add, divide and subtract.
140
142 The server config file is inherited from Net::Daemon. It adds the users
143 and cipher attribute to the client list. Thus a typical config file
144 might look as follows:
145
146 # Load external modules; this is not required unless you use
147 # the chroot() option.
148 #require DBD::mysql;
149 #require DBD::CSV;
150
151 # Create keys
152 my $myhost_key = Crypt::IDEA->new('83fbd23390ade239');
153 my $bob_key = Crypt::IDEA->new('be39893df23f98a2');
154
155 {
156 # 'chroot' => '/var/dbiproxy',
157 'facility' => 'daemon',
158 'pidfile' => '/var/dbiproxy/dbiproxy.pid',
159 'user' => 'nobody',
160 'group' => 'nobody',
161 'localport' => '1003',
162 'mode' => 'fork',
163
164 # Access control
165 'clients' => [
166 # Accept the local LAN (192.168.1.*)
167 {
168 'mask' => '^192\.168\.1\.\d+$',
169 'accept' => 1,
170 'users' => [ 'bob', 'jim' ],
171 'cipher' => $myhost_key
172 },
173 # Accept myhost.company.com
174 {
175 'mask' => '^myhost\.company\.com$',
176 'accept' => 1,
177 'users' => [ {
178 'name' => 'bob',
179 'cipher' => $bob_key
180 } ]
181 },
182 # Deny everything else
183 {
184 'mask' => '.*',
185 'accept' => 0
186 }
187 ]
188 }
189
190 Things you should note: The user list of 192.168.1.* contains scalar
191 values, but the user list of myhost.company.com contains hash refs:
192 This is required, because the user configuration is more specific for
193 user based encryption.
194
196 Enough wasted time, spread the example, not the word. :-) Let's write a
197 simple server, say a server for MD5 digests. The server uses the
198 external package MD5, but the client doesn't need to install the
199 package. MD5(3). We present the server source here, the client is part
200 of the RPC::PlClient man page. See RPC::PlClient(3).
201
202 #!/usr/bin/perl -wT
203 # Note the -T switch! This is always recommended for Perl servers.
204
205 use strict; # Always a good choice.
206
207 require RPC::PlServer;
208 require MD5;
209
210
211 package MD5_Server; # Clients need to request application
212 # "MD5_Server"
213
214 $MD5_Server::VERSION = '1.0'; # Clients will be refused, if they
215 # request version 1.1
216 @MD5_Server::ISA = qw(RPC::PlServer);
217
218 eval {
219 # Server options below can be overwritten in the config file or
220 # on the command line.
221 my $server = MD5_Server->new({
222 'pidfile' => '/var/run/md5serv.pid',
223 'configfile' => '/etc/md5serv.conf',
224 'facility' => 'daemon', # Default
225 'user' => 'nobody',
226 'group' => 'nobody',
227 'localport' => 2000,
228 'logfile' => 0, # Use syslog
229 'mode' => 'fork', # Recommended for Unix
230 'methods' => {
231 'MD5_Server' => {
232 'ClientObject' => 1,
233 'CallMethod' => 1,
234 'NewHandle' => 1
235 },
236 'MD5' => {
237 'new' => 1,
238 'add' => 1,
239 'hexdigest' => 1
240 },
241 }
242 });
243 $server->Bind();
244 };
245
247 It has to be said: PlRPC based servers are a potential security
248 problem! I did my best to avoid security problems, but it is more than
249 likely, that I missed something. Security was a design goal, but not
250 *the* design goal. (A well known problem ...)
251
252 Due to implementation of PlRPC, it's hard to use internal
253 authentication mechanisms properly to achieve secured remote calls.
254 Therefore users are advised to use an external authentication mechanism
255 like TLS or IPsec.
256
257 I highly recommend the following design principles:
258
259 Protection against "trusted" users
260 perlsec
261 Read the perl security FAQ ("perldoc perlsec") and use the "-T"
262 switch.
263
264 taintperl
265 Use the "-T" switch. I mean it!
266
267 Verify data
268 Never untaint strings withouth verification, better verify twice.
269 For example the CallMethod function first checks, whether an object
270 handle is valid before coercing a method on it.
271
272 Be restrictive
273 Think twice, before you give a client access to a method.
274
275 Use of Storable
276 Storable module used for serialization and deserialization
277 underneath is inherently insecure. Deserialized data can contain
278 objects which lead to loading foreign modules and executing
279 possible attached destructors. Do not accept host-based
280 unauthorized connections. The Storable module is exercised before
281 checking user password.
282
283 perlsec
284 And just in case I forgot it: Read the "perlsec" man page. :-)
285
286 Protection against untrusted users
287 Host based authorization
288 PlRPC has a builtin host based authorization scheme; use it! See
289 "CONFIGURATION FILE".
290
291 User based authorization
292 PlRPC has a builtin user based authorization scheme; use it! See
293 "CONFIGURATION FILE".
294
295 Encryption
296 Using encryption with PlRPC is extremely easy. There is absolutely
297 no reason for communicating unencrypted with the clients. Even
298 more: I recommend two phase encryption: The first phase is the
299 login phase, where to use a host based key. As soon as the user has
300 authorized, you should switch to a user based key. See the
301 DBI::ProxyServer for an example.
302
303 Please note PlRPC encryption does not protect from reply attacks.
304 You should have implement it on the application or the cipher
305 level.
306
308 The PlRPC-modules are
309
310 Copyright (C) 1998, Jochen Wiedmann
311 Email: jochen.wiedmann at freenet.de
312
313 All rights reserved.
314
315 You may distribute this package under the terms of either the GNU
316 General Public License or the Artistic License, as specified in the
317 Perl README file.
318
320 RPC::PlClient(3), RPC::PlServer::Comm(3), Net::Daemon(3),
321 Net::Daemon::Log(3), Storable(3), Sys::Syslog(3), Win32::EventLog(3)
322
323 See DBI::ProxyServer(3) for an example application.
324
325
326
327perl v5.16.3 2014-06-10 RPC::PlServer(3)