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