Home | History | Annotate | Line # | Download | only in dist
PLUGINS revision 1.1
      1  1.1  christos Starting with version 2.3.10, pppd includes support for `plugins' -
      2  1.1  christos pieces of code which can be loaded into pppd at runtime and which can
      3  1.1  christos affect its behaviour in various ways.  The idea of plugins is to
      4  1.1  christos provide a way for people to customize the behaviour of pppd without
      5  1.1  christos having to either apply local patches to each version or get their
      6  1.1  christos patches accepted into the standard distribution.
      7  1.1  christos 
      8  1.1  christos A plugin is a standard shared library object, typically with a name
      9  1.1  christos ending in .so.  They are loaded using the standard dlopen() library
     10  1.1  christos call, so plugins are only supported on systems which support shared
     11  1.1  christos libraries and the dlopen call.  At present pppd is compiled with
     12  1.1  christos plugin support only under Linux and Solaris.
     13  1.1  christos 
     14  1.1  christos Plugins are loaded into pppd using the `plugin' option, which takes
     15  1.1  christos one argument, the name of a shared object file.  The plugin option is
     16  1.1  christos a privileged option.  If the name given does not contain a slash, pppd
     17  1.1  christos will look in the /usr/lib/pppd/<version> directory for the file, where
     18  1.1  christos <version> is the version number of pppd, for example, 2.4.2.  I
     19  1.1  christos suggest that you either give the full path name of the shared object
     20  1.1  christos file or just the base name; if you don't, it may be possible for
     21  1.1  christos unscrupulous users to substitute another shared object file for the
     22  1.1  christos one you mean to load, e.g. by setting the LD_LIBRARY_PATH variable.
     23  1.1  christos 
     24  1.1  christos Plugins are usually written in C and compiled and linked to a shared
     25  1.1  christos object file in the appropriate manner for your platform.  Using gcc
     26  1.1  christos under Linux, a plugin called `xyz' could be compiled and linked with
     27  1.1  christos the following commands:
     28  1.1  christos 
     29  1.1  christos 	gcc -c -O xyz.c
     30  1.1  christos 	gcc -shared -o xyz.so xyz.o
     31  1.1  christos 
     32  1.1  christos There are some example plugins in the pppd/plugins directory in the
     33  1.1  christos ppp distribution.  Currently there is one example, minconn.c, which
     34  1.1  christos implements a `minconnect' option, which specifies a minimum connect
     35  1.1  christos time before the idle timeout applies.
     36  1.1  christos 
     37  1.1  christos Plugins can access global variables within pppd, so it is useful for
     38  1.1  christos them to #include "pppd.h" from the pppd source directory.
     39  1.1  christos 
     40  1.1  christos Every plugin must contain a global procedure called `plugin_init'.
     41  1.1  christos This procedure will get called (with no arguments) immediately after
     42  1.1  christos the plugin is loaded.  Every plugin should also contain a variable
     43  1.1  christos called pppd_version declared as follows:
     44  1.1  christos 
     45  1.1  christos char pppd_version[] = VERSION;
     46  1.1  christos 
     47  1.1  christos If this declaration is included, pppd will not load the module if its
     48  1.1  christos version number differs from that compiled into the plugin binary.
     49  1.1  christos 
     50  1.1  christos Plugins can affect the behaviour of pppd in at least four ways:
     51  1.1  christos 
     52  1.1  christos 1. They can add extra options which pppd will then recognize.  This is
     53  1.1  christos    done by calling the add_options() procedure with a pointer to an
     54  1.1  christos    array of option_t structures.  The last entry in the array must
     55  1.1  christos    have its name field set to NULL.
     56  1.1  christos 
     57  1.1  christos 2. Pppd contains `hook' variables which are procedure pointers.  If a
     58  1.1  christos    given hook is not NULL, pppd will call the procedure it points to
     59  1.1  christos    at the appropriate point in its processing.  The plugin can set any
     60  1.1  christos    of these hooks to point to its own procedures.  See below for a
     61  1.1  christos    description of the hooks which are currently implemented.
     62  1.1  christos 
     63  1.1  christos 3. Plugin code can call any global procedures and access any global
     64  1.1  christos    variables in pppd.
     65  1.1  christos 
     66  1.1  christos 4. Plugins can register procedures to be called when particular events
     67  1.1  christos    occur, using the `notifier' mechanism in pppd.  The differences
     68  1.1  christos    between hooks and notifiers are that a hook will only call one
     69  1.1  christos    function, whereas a notifier can call an arbitrary number, and that
     70  1.1  christos    a hook usually returns some value to pppd, whereas a notifier
     71  1.1  christos    function returns nothing.
     72  1.1  christos 
     73  1.1  christos Here is a list of the currently implemented hooks in pppd.
     74  1.1  christos 
     75  1.1  christos 
     76  1.1  christos int (*idle_time_hook)(struct ppp_idle *idlep);
     77  1.1  christos 
     78  1.1  christos The idle_time_hook is called when the link first comes up (i.e. when
     79  1.1  christos the first network protocol comes up) and at intervals thereafter.  On
     80  1.1  christos the first call, the idlep parameter is NULL, and the return value is
     81  1.1  christos the number of seconds before pppd should check the link activity, or 0
     82  1.1  christos if there is to be no idle timeout.
     83  1.1  christos 
     84  1.1  christos On subsequent calls, idlep points to a structure giving the number of
     85  1.1  christos seconds since the last packets were sent and received.  If the return
     86  1.1  christos value is > 0, pppd will wait that many seconds before checking again.
     87  1.1  christos If it is <= 0, that indicates that the link should be terminated due
     88  1.1  christos to lack of activity.
     89  1.1  christos 
     90  1.1  christos 
     91  1.1  christos int (*holdoff_hook)(void);
     92  1.1  christos 
     93  1.1  christos The holdoff_hook is called when an attempt to bring up the link fails,
     94  1.1  christos or the link is terminated, and the persist or demand option was used.
     95  1.1  christos It returns the number of seconds that pppd should wait before trying
     96  1.1  christos to reestablish the link (0 means immediately).
     97  1.1  christos 
     98  1.1  christos 
     99  1.1  christos int (*pap_check_hook)(void);
    100  1.1  christos int (*pap_passwd_hook)(char *user, char *passwd);
    101  1.1  christos int (*pap_auth_hook)(char *user, char *passwd, char **msgp,
    102  1.1  christos 		     struct wordlist **paddrs,
    103  1.1  christos 		     struct wordlist **popts);
    104  1.1  christos void (*pap_logout_hook)(void);
    105  1.1  christos 
    106  1.1  christos These hooks are designed to allow a plugin to replace the normal PAP
    107  1.1  christos password processing in pppd with something different (e.g. contacting
    108  1.1  christos an external server).
    109  1.1  christos 
    110  1.1  christos The pap_check_hook is called to check whether there is any possibility
    111  1.1  christos that the peer could authenticate itself to us.  If it returns 1, pppd
    112  1.1  christos will ask the peer to authenticate itself.  If it returns 0, pppd will
    113  1.1  christos not ask the peer to authenticate itself (but if authentication is
    114  1.1  christos required, pppd may exit, or terminate the link before network protocol
    115  1.1  christos negotiation).  If it returns -1, pppd will look in the pap-secrets
    116  1.1  christos file as it would normally.
    117  1.1  christos 
    118  1.1  christos The pap_passwd_hook is called to determine what username and password
    119  1.1  christos pppd should use in authenticating itself to the peer with PAP.  The
    120  1.1  christos user string will already be initialized, by the `user' option, the
    121  1.1  christos `name' option, or from the hostname, but can be changed if necessary.
    122  1.1  christos MAXNAMELEN bytes of space are available at *user, and MAXSECRETLEN
    123  1.1  christos bytes of space at *passwd.  If this hook returns 0, pppd will use the
    124  1.1  christos values at *user and *passwd; if it returns -1, pppd will look in the
    125  1.1  christos pap-secrets file, or use the value from the +ua or password option, as
    126  1.1  christos it would normally.
    127  1.1  christos 
    128  1.1  christos The pap_auth_hook is called to determine whether the username and
    129  1.1  christos password supplied by the peer are valid.  user and passwd point to
    130  1.1  christos null-terminated strings containing the username and password supplied
    131  1.1  christos by the peer, with non-printable characters converted to a printable
    132  1.1  christos form.  The pap_auth_hook function should set msg to a string to be
    133  1.1  christos returned to the peer and return 1 if the username/password was valid
    134  1.1  christos and 0 if not.  If the hook returns -1, pppd will look in the
    135  1.1  christos pap-secrets file as usual.
    136  1.1  christos 
    137  1.1  christos If the username/password was valid, the hook can set *paddrs to point
    138  1.1  christos to a wordlist containing the IP address(es) which the peer is
    139  1.1  christos permitted to use, formatted as in the pap-secrets file.  It can also
    140  1.1  christos set *popts to a wordlist containing any extra options for this user
    141  1.1  christos which pppd should apply at this point.
    142  1.1  christos 
    143  1.1  christos The pap_logout_hook is called when the link is terminated, instead of
    144  1.1  christos pppd's internal `plogout' function.  It can be used for accounting
    145  1.1  christos purposes.  This hook is deprecated and will be replaced by a notifier.
    146  1.1  christos 
    147  1.1  christos 
    148  1.1  christos int (*chap_check_hook)(void);
    149  1.1  christos int (*chap_passwd_hook)(char *user, char *passwd);
    150  1.1  christos int (*chap_verify_hook)(char *name, char *ourname, int id,
    151  1.1  christos 			struct chap_digest_type *digest,
    152  1.1  christos 			unsigned char *challenge, unsigned char *response,
    153  1.1  christos 			char *message, int message_space)
    154  1.1  christos 
    155  1.1  christos These hooks are designed to allow a plugin to replace the normal CHAP
    156  1.1  christos password processing in pppd with something different (e.g. contacting
    157  1.1  christos an external server).
    158  1.1  christos 
    159  1.1  christos The chap_check_hook is called to check whether there is any possibility
    160  1.1  christos that the peer could authenticate itself to us.  If it returns 1, pppd
    161  1.1  christos will ask the peer to authenticate itself.  If it returns 0, pppd will
    162  1.1  christos not ask the peer to authenticate itself (but if authentication is
    163  1.1  christos required, pppd may exit, or terminate the link before network protocol
    164  1.1  christos negotiation).  If it returns -1, pppd will look in the chap-secrets
    165  1.1  christos file as it would normally.
    166  1.1  christos 
    167  1.1  christos The chap_passwd_hook is called to determine what password
    168  1.1  christos pppd should use in authenticating itself to the peer with CHAP.  The
    169  1.1  christos user string will already be initialized, by the `user' option, the
    170  1.1  christos `name' option, or from the hostname, but can be changed if necessary.
    171  1.1  christos This hook is called only if pppd is a client, not if it is a server.
    172  1.1  christos 
    173  1.1  christos MAXSECRETLEN bytes of space are available at *passwd.  If this hook
    174  1.1  christos returns 0, pppd will use the value *passwd; if it returns -1, pppd
    175  1.1  christos will fail to authenticate.
    176  1.1  christos 
    177  1.1  christos The chap_verify_hook is called to determine whether the peer's
    178  1.1  christos response to our CHAP challenge is valid -- it should return 1 if valid
    179  1.1  christos or 0 if not.  The parameters are:
    180  1.1  christos 
    181  1.1  christos * name points to a null-terminated string containing the username
    182  1.1  christos   supplied by the peer, or the remote name specified with the
    183  1.1  christos   "remotename" option.
    184  1.1  christos * ourname points to a null-terminated string containing the name of
    185  1.1  christos   the local machine (the hostname, or the name specified with the
    186  1.1  christos   "name" option).
    187  1.1  christos * id is the value of the id field from the challenge.
    188  1.1  christos * digest points to a chap_digest_type struct, which contains an
    189  1.1  christos   identifier for the type of digest in use plus function pointers for
    190  1.1  christos   functions for dealing with digests of that type.
    191  1.1  christos * challenge points to the challenge as a counted string (length byte
    192  1.1  christos   followed by the actual challenge bytes).
    193  1.1  christos * response points to the response as a counted string.
    194  1.1  christos * message points to an area of message_space bytes in which to store
    195  1.1  christos   any message that should be returned to the peer.
    196  1.1  christos 
    197  1.1  christos 
    198  1.1  christos int (*null_auth_hook)(struct wordlist **paddrs,
    199  1.1  christos 		      struct wordlist **popts);
    200  1.1  christos 
    201  1.1  christos This hook allows a plugin to determine what the policy should be if
    202  1.1  christos the peer refuses to authenticate when it is requested to.  If the
    203  1.1  christos return value is 0, the link will be terminated; if it is 1, the
    204  1.1  christos connection is allowed to proceed, and in this case *paddrs and *popts
    205  1.1  christos can be set as for pap_auth_hook, to specify what IP addresses are
    206  1.1  christos permitted and any extra options to be applied.  If the return value is
    207  1.1  christos -1, pppd will look in the pap-secrets file as usual.
    208  1.1  christos 
    209  1.1  christos 
    210  1.1  christos void (*ip_choose_hook)(u_int32_t *addrp);
    211  1.1  christos 
    212  1.1  christos This hook is called at the beginning of IPCP negotiation.  It gives a
    213  1.1  christos plugin the opportunity to set the IP address for the peer; the address
    214  1.1  christos should be stored in *addrp.  If nothing is stored in *addrp, pppd will
    215  1.1  christos determine the peer's address in the usual manner.
    216  1.1  christos 
    217  1.1  christos 
    218  1.1  christos int (*allowed_address_hook)(u_int32_t addr)
    219  1.1  christos 
    220  1.1  christos This hook is called to see if a peer is allowed to use the specified
    221  1.1  christos address.  If the hook returns 1, the address is accepted.  If it returns
    222  1.1  christos 0, the address is rejected.  If it returns -1, the address is verified
    223  1.1  christos in the normal away against the appropriate options and secrets files.
    224  1.1  christos 
    225  1.1  christos 
    226  1.1  christos void (*snoop_recv_hook)(unsigned char *p, int len)
    227  1.1  christos void (*snoop_send_hook)(unsigned char *p, int len)
    228  1.1  christos 
    229  1.1  christos These hooks are called whenever pppd receives or sends a packet.  The
    230  1.1  christos packet is in p; its length is len.  This allows plugins to "snoop in"
    231  1.1  christos on the pppd conversation.  The hooks may prove useful in implmenting
    232  1.1  christos L2TP.
    233  1.1  christos 
    234  1.1  christos 
    235  1.1  christos void (*multilink_join_hook)();
    236  1.1  christos 
    237  1.1  christos This is called whenever a new link completes LCP negotiation and joins
    238  1.1  christos the bundle, if we are doing multilink.
    239  1.1  christos 
    240  1.1  christos 
    241  1.1  christos A plugin registers itself with a notifier by declaring a procedure of
    242  1.1  christos the form:
    243  1.1  christos 
    244  1.1  christos void my_notify_proc(void *opaque, int arg);
    245  1.1  christos 
    246  1.1  christos and then registering the procedure with the appropriate notifier with
    247  1.1  christos a call of the form
    248  1.1  christos 
    249  1.1  christos 	add_notifier(&interesting_notifier, my_notify_proc, opaque);
    250  1.1  christos 
    251  1.1  christos The `opaque' parameter in the add_notifier call will be passed to
    252  1.1  christos my_notify_proc every time it is called.  The `arg' parameter to
    253  1.1  christos my_notify_proc depends on the notifier.
    254  1.1  christos 
    255  1.1  christos A notify procedure can be removed from the list for a notifier with a
    256  1.1  christos call of the form
    257  1.1  christos 
    258  1.1  christos 	remove_notifier(&interesting_notifier, my_notify_proc, opaque);
    259  1.1  christos 
    260  1.1  christos Here is a list of the currently-implemented notifiers in pppd.
    261  1.1  christos 
    262  1.1  christos * pidchange.  This notifier is called in the parent when pppd has
    263  1.1  christos   forked and the child is continuing pppd's processing, i.e. when pppd
    264  1.1  christos   detaches from its controlling terminal.  The argument is the pid of
    265  1.1  christos   the child.
    266  1.1  christos 
    267  1.1  christos * phasechange.  This is called when pppd moves from one phase of
    268  1.1  christos   operation to another.  The argument is the new phase number.
    269  1.1  christos 
    270  1.1  christos * exitnotify.  This is called just before pppd exits.  The argument is
    271  1.1  christos   the status with which pppd will exit (i.e. the argument to exit()).
    272  1.1  christos 
    273  1.1  christos * sigreceived.  This is called when a signal is received, from within
    274  1.1  christos   the signal handler.  The argument is the signal number.
    275  1.1  christos 
    276  1.1  christos * ip_up_notifier.  This is called when IPCP has come up.
    277  1.1  christos 
    278  1.1  christos * ip_down_notifier.  This is called when IPCP goes down.
    279  1.1  christos 
    280  1.1  christos * auth_up_notifier.  This is called when the peer has successfully
    281  1.1  christos   authenticated itself.
    282  1.1  christos 
    283  1.1  christos * link_down_notifier.  This is called when the link goes down.
    284  1.1  christos 
    285  1.1  christos 
    286  1.1  christos 
    287  1.1  christos ## Id: PLUGINS,v 1.8 2008/06/15 07:02:18 paulus Exp  ##
    288