• Home
  • History
  • Annotate
  • only in this directory
NameDateSize

..11-Apr-2013244

ChangeLogH A D20-Feb-20134.4 KiB

lib/H05-Apr-20134

Makefile.PLH A D20-Feb-20132.3 KiB

MANIFESTH A D20-Feb-2013325

META.ymlH A D20-Feb-2013380

READMEH A D20-Feb-201311.1 KiB

t/H11-Apr-20139

README

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