pNETagent - a Perl agent for the DBI network driver DBD::pNET


  pNETagent -p <port> [<other options>]


pNETagent is an agent for the DBI network driver, DBD::pNET. It allows access to databases over the network if the DBMS does not offer networked operations. But pNETagent might be useful for you, even if you have a DBMS with integrated network functionality: It can be used as a DBI proxy in a firewalled environment.

pNETagent runs as a daemon on the machine with the DBMS or on the firewall. The client connects to the agent using the DBI driver DBD::pNET, thus in the exactly same way than using DBD::mysql, DBD::mSQL or any other DBI driver.

The agent is implemented as a RPC::pServer application. Thus you have access to all the possibilities of this module, in particular encryption and a similar configuration file. pNETagent adds the possibility of query restrictions: You can define a set of queries that a client may execute and restrict access to these. See "CONFIGURATION FILE".


The following options can be used when starting pNETagent:

-cf filename
-configFile filename
--configFile filename

The pNETagent can use a configuration file for authorizing clients. The file is almost identical to that of DBD::pNET::Server, with the exception of an additional attribute users. See "CONFIGURATION FILE".


Turns on debugging mode. Debugging messages will usually be logged to syslog with facility daemon unless you use the option -stderr. See below.


Tells the pNETagent to print a help message and exit immediately.

-i ip-number
-ip ip-number
--ip ip-number

Tells the pNETagent, on which ip number he should bind. The default is, to bind to INADDR_ANY or any ip number of the local host. You might use this option, for example, on a firewall with two network interfaces. If your LAN has non public IP numbers and you bind the pNET agent to the inner network interface, then you will easily disable the access from the outer network or the Internet.

-p port
-port port
--port port

This option tells the pNETagent, on which port number he should bind. Unlike other applications, pNETagent has no builtin default, so you using this option is required.

-pf filename
-pidFile filename
--pidFile filename

Tells the daemon, where to store its PID file. The default is /tmp/ pNETagent's PID file looks like this:

    IP number, port 3334
    pNETagent -ip -p 3334

The first line is the process number. The second line are IP number and port number, so that they can be used by local clients and the third line is the command line. These can be used in administrative scripts, for example to first kill the pNETagent and then restart it with the same options you do a

    kill `head -1 /tmp/`
    `tail -1 /tmp/`

Forces printing of messages to stderr. The default is sending messages to syslog with facility daemon.


Forces the pNETagent to print its version number and copyright message and exit immediately.


pNETagent's configuration file is just that of RPC::pServer with some additional attributes. Currently its own use is authorization and encryption.


Empty lines and comment lines (starting with hashes, # charactes) are ignored. All other lines have the syntax

    var value

White space at the beginning and the end of the line will be removed, so will white space between var and val be ignored. On the other hand value may contain white space, for example

    description Free form text

would be valid with value = Free form text.

Accepting and refusing hosts

Semantically the configuration file is a collection of host definitions, each of them starting with

    accept|deny mask

where mask is a Perl regular expression matching host names or IP numbers (in particular this means that you have to escape dots), accept tells the server to accept connections from mask and deny forces to refuse connections from mask. The first match is used, thus the following will accept connections from 192.168.1.* only

    accept 192\.168\.1\.
    deny .*

and the following will accept all connections except those from

    deny evil\.guys\.com
    accept .*

Default is to refuse connections, thus the deny .* in the first example is redundant, but of course good style.

Host based encryption

You can force a client to use encryption. The following example will accept connections from 192.168.1.* only, if they are encrypted with the DES algorithm and the key 0123456789abcdef:

    accept 192\.168\.1\.
        encryption DES
        key 0123456789abcdef
        encryptModule Crypt::DES

    deny .*

You are by no means bound to use DES. pNETagent just expects a certain API, namely the methods new, keysize, blocksize, encrypt and decrypt. For example IDEA is another choice. The above example will be mapped to this Perl source:

    $encryptModule = "Crypt::DES";
    $encryption = "DES";
    $key = "0123456789abcdef";

    eval "use $encryptModule;"
       . "$crypt = \$encryption->new(pack('H*', \$key));";

encryptModule defaults to <encryption>, this is only needed because of the brain damaged design of Crypt::IDEA and Crypt::DES, where module name and class name differ.

User based authorization

The users attribute allows to restrict access to certain users. For example the following allows only the users joe and jack from host alpha and joe and mike from beta:

    accept alpha
        users joe jack

    accept beta
        users joe mike

User based encryption

Although host based encryption is fine, you might still wish to force different users to use different encryption secrets. Here's how it goes:

    accept alpha
        users joe jack
        jack encrypt="Crypt::DES,DES,fedcba9876543210"
        joe encrypt="Crypt::IDEA,IDEA,0123456789abcdef0123456789abcdef"

This would force jack to encrypt with DES and key fedcba9876543210 and joe with IDEA and 0123456789abcdef0123456789abcdef. The three fields of the encrypt entries correspond to the encryptionModule, encryption and key attributes of the host based encryption.

You note the problem: Of course user based encryption can only be used when the user has already logged in. Thus we recommend to use both host based and user based encryption: The former will be used in the authorization phase and the latter once the client has logged in. Without user based secrets the host based secret (if any) will be used for the complete session.

Query restrictions

You have the possibility to restrict the queries a client may execute to a predefined set.

Suggest the following lines in the configuration file:

    accept alpha
        sqlRestrict 1
        insert1 INSERT INTO foo VALUES (?, ?)
        insert2 INSERT INTO bla VALUES (?, ?, ?)

    accept beta
        sqlRestrict 0

This allows users connecting from beta to execute any SQL query, but users from alpha can only insert values into the tables foo and bar. Clients select the query by just passing the query name (insert1 and insert2 in the example above) as an SQL statement and binding parameters to the statement. Of course the client side must know how much parameters should be passed. Thus you should use the following for inserting values into foo from the client:

    my $dbh;
    my $sth = $dbh->prepare("insert1 (?, ?)");
    $sth->execute(1, "foo");
    $sth->execute(2, "bar");


    Copyright (c) 1997    Jochen Wiedmann
                          Am Eisteich 9
                          72555 Metzingen

                          Phone: +49 7123 14881

You may distribute DBD::pNET and pNETagent under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file, with the exception that it cannot be placed on a CD-ROM or similar media for commercial distribution without the prior approval of the author.


DBI(3), DBD::pNET(3), RPC::pServer(3), RPC::pClient(3), Sys::Syslog(3), syslog(2)


# # End of pNETagent #

close OUT or die "Can't close $file: $!"; chmod 0755, $file or die "Can't reset permissions for $file: $!\n";