gensio(5)

NAME
gensio - How to specify a gensio

SYNOPSIS
<type>[(options)][,gensio|terminaloptions]

DESCRIPTION
gensio stands for GENeral Stream Input Output. It provides an abstraction for all kinds of stream I/O, and even makes some packet I/O look like stream I/O (like UDP). In particular, gensio makes it easy to create encrypted and authenticated connections. The gensio library specifies a connection (gensio) using a string format. This consists of a gensio type, optional options in parenthesis. For a terminal gensio (one that is at the bottom of the stack), it may take more options separated by a comma. For filter gensios (ones not on the bottom of the stack) another gensio must be specified after the comma. For instance:

    serialdev,/dev/ttyS0

specifies a serial port gensio. Or:

    tcp(readbuf=100),localhost,4000

specifies a TCP connection with a 100 byte read buffer, to connect to port 4000 on localhost. Or:

    telnet,tcp,localhost,4000

specifies a telnet filter on top of a TCP connection. When specifying a gensio, you can add quotes (single or double) to remove the special meaning for some characters, so you can have commas in options and such. They may also be escaped with a "\". For instance, if you are specifying a laddr in an sctp address, you need to do this. The following address:

    sctp(laddr=sctp,localhost,4001),localhost,3023

will result in a failure because the option splitting code will split at the commas. Instead, do:

    sctp(laddr="sctp,localhost,4001"),localhost,3023

and it will work. Accepter gensios, gensios used for accepting connections, as opposed to connecting gensios, are specified in the same way. Each individual type can vary, and some gensios are only connecting gensios. The options can vary from the accepter and connecting gensios of the same type. For instance, an accepting TCP gensio does not have to have a hostname, but a connecting one does. When an accepter gensio receives a connection, it will create an accepted gensio. This works mostly like a connecting gensio, except some functions may be limited. You may not be able to close and then open an accepted gensio. The gensio library has a concept of client and server. The accepted gensios are generally considered servers. Connecting gensios are generally considered clients. Some gensios may allow this to be overridden. A gensio may be reliable or not. A reliable gensio will reliably deliver all data in sequence, like TCP. An gensio that is not reliable may drop data or deliver data out of sequence, like UDP. This can be queried with gensio_is_reliable(). A gensio may be packet or not. A packet gensio will exactly match up writes and reads. So if you write 15 bytes into one side, a 15 byte read for that data will appear on the other side. A gensio that is not packet will not respect write boundaries, that 15 byte write may result in multiple reads or it may be combined with another write into more than 15 bytes. Packet I/O requires careful use to make it work correctly. Particularly, you must set the max read and write size to the same value, and you must accept all data on receipt and write complete packets all at once. A gensio may be message oriented. This implementation is stolen from SCTP (even though it's not really supported on Linux at the moment). It basically means you can explicitly mark message boundaries when sending data, and that explicit mark will be set on the read side. You do this by adding an "eom" auxdata on the write; the end of that write it assumed to be the end of a message. If the write does not accept all the data, the "eom" is ignored, you must write the remaning data again with "eom" set. You may also do partial write of messages and set "eom" at the end. On the receive side, "eom" will be set when the end of a message is delivered. The data delivered in the receive callback will be only the data for that message. If the user does not accept all the data, the data left in the message is again presented to the user with "eom" set. The options vary greatly between the different gensios. Each gensio type will be covered in a separate section. Also note that gensio types can be dynamically added by the user, so there may be gensios available that are not described here. Unless othersize noted, every gensio takes a:

readbuf=<n>
    option to specify the read buffer size.

DEFAULTS
Every option to a gensio (including the serialdev and ipmisol options), unless othersize stated, is available as a default for the gensios. You can use gensio_set_default() to set the default value used by all gensios allocated after that point. If you leave the class NULL, it will set the base default, which will affect all gensios unless they have an override. If you set the class, it will only affect gensios with that class name. Be very careful with some defaults. Setting "mode" default, for instance, could really screw things up. For string defaults, setting the default value to NULL causes the gensio to use it's backup default.

Serial gensios
Some gensio types support serial port setting options. Standard serial ports, IPMI Serial Over LAN, and telnet with RFC2217 enabled. A client serial gensio can set and get serial port options using the sergensio_xxx() functions. Server serial gensios receive requests from the client via GENSIO_EVENT_SER_xxx events in the callback.

Streams and Channels
Some gensios support the concept of a stream and/or a channel. A stream is delivered as part of the normal data stream of a gensio. The "default" stream will be treated normally. All other streams will have "stream=<x>" given in the auxdata to specify which stream to write on or which stream was read from. Streams cannot be individually flow controlled. A channel is a flow of data like a stream, but it can be individually flow controlled. It appears as a new gensio in the GENSIO_EVENT_NEW_CHANNEL callback. You can create a channel with gensio_open_channel(). Once open, a channel works like a normal gensio. If you close the main channel for a gensio, the other channels will stay open, but the resources for the main channel will still be kept around until all channels are closed. See the indvidual gensio description for more information on streams and channels.

PUBLIC KEY CRYPTOGRAPHY
The ssl and certauth gensios use public key cryptography. This section gives a little overview of how that works. You can safely skip this section if you already understand these concepts. Public key cryptography is used to authenticate and encrypt information at the beginning of a session. It is a fairly expensive operation and is not generally used to encrypt information after the beginning. In public key cryptography, you have three basic things: A private key, a certificate (or public key), and a certificate authority (CA). The private key is just that: private. You don't even send your private key to a certificate authority for signing of your certificate. Keep it private, non-readable by everyone else. Protect it, if it becomes known your certificate becomes useless to you, anyone can impersonate you. The certificate is the public key, and is mathematically associated with a single private key. It's just that, public, anyone can use it to test that you have the private key by asking you to sign some data. The data in the certificate (like the Common Name) is part of the certificate. If that data is modified, the certificate validation will fail. The CA is generally a trusted third-party that validates you and signs your certificate (generally for a fee). CAs issue their own public certificates that are well-known and generally available on your system. The CA certificates are used to prove that your certificate is valid.

  SIGNING
The process if signing has been mentioned already, but not described. Basically, you use your private key to generate a value over some given data that proves you have the private key. The certificate is ised to mathematically verify the signature. Two things are normally done with this: In a public key exchange, the entity wishing to be authorized sends a certificate. The authorizing entity will look through it's CA for a certificate that has signed the sent certificate. If the authorizing entity finds a certificate that can be used to validate the sent certificate, the sent certificate is valid. After that, the authorizing entity sends some generally random data to the other entity. The other entity will take that data, perhaps some other important data that it want to make sure is not modified in the transfer, and signs that data. It sends the signature back to the authorizing entity. The authorizing entity can then use the data and the signature to validate that the sending entity has the private key associated with the certificate. This is basically how https works. Note it is the web client that authenticates the web server, not the other way around. This proves that you are connecting to the entity you say you are connecting to. The authentication of a web client to the web server is generally done via a different mechanism (though SSL/TLS used by the ssl gensio has a way to do it, it is not generally used for that purpose). In the web server scenario, data in the certificate (specifically the Common Name and Subject Alternate Name) must match the name of the web page to which you are connecting. The ssl and certauth gensios do not do this authentication, that is up to the user if it is necessary.

  ENCRYPTING
The certificate can be used to encrypt data that can only be decrypted with the private key. When establishing an encrypted connection, this is generally used to transfer a symmetric cryptography key from one entity to another (the authorizing entity to the requesting entity in the case above). You could encrypt all the data with the public key, but that is very expensive and in our example above would require certificates and private keys on both ends.

  SELF-SIGNED CERTIFICATES
It is possible to create a certificate that can act as its own certificate authority. This is how ssh works. You create a public and private key. You put the public key in the .ssh/authorized_keys directory on systems where you want to log in. The certificate acts as both the public key (as part of the initial transfer) and the CA (in the authorized_key directory) for authorizing you use of the system you are logging in to. ssh also stores places it has connected to in .ssh/known_hosts, which is the CA in the opposite direction. This is why it asks you if you have never connected to a system before, it doesn't have the key in its CA. Or why, if you connect to a system you have connected to before and the certificates don't match or fail validation, it complains about it. So if you are using self-signed certificates, you need to be careful to put only ones you trust in the CA. This is obviously not possible in a large system like the world wide web, thus the creation of third-party trusted CAs.

  TRUST AND CRYPTOGRAPHY
The above discussions mention trust several times. Cryptography does not remove the need for trust. It just makes trust more convenient. If someone sends you a certificate, you need to validate that it was actually them that sent you the certificate, and that it was not modified in transit. If you add that certificate to your CA, you are trusting the certificate, and you better make sure (with fingerprints, generally, see the openssl docs for details) that it came from a trusted entity. The hardest part of cryptography in general is key management. Breaking cryptographic algorithms is really hard. Getting people to divulge private keys or use the wrong keys is a lot easier. For more on cryptography in general, and cryptography and trust, Bruce Schneier has some excellent books on the subject.

TCP
tcp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
hostname = [ipv4|ipv6|ipv6n4,]<name> A TCP connecting gensio must have the hostname specified. Mulitiple hostname/port pairs may be specified. For a connecting TCP gensio, each one will be tried in sequence until a connection is established. For acceptor gensios, every specified hostname/port pair will be listened to. Note that a single hostname may result in more than one address. For instance, it may have both an IPv4 and IPv6 address. These are treated just like multiple hostnames. IPv6 is generally tried first and it valls back to IPv4 if that fails. The hostname may be prefixed with ipv4 or ipv6, which will force the connections to those protocols. Specifying ipv6n4 will create a socket that is IPv6 but will accept IPv4 connections. TCP support out of band (oob) data, which is data that will be delivered out of order as soon as possible. This comes in a normal read, but with "oob" in the auxdata. You can send oob data by adding "oob" to the write auxdata, but oob writes are limited to 1 byte and writing any more than this results in undefined behavior. In addition to readbuf, the tcp gensio takes the following options:

laddr=<addr>
    An address specification to bind to on the local socket to set the local address.

  Remote Address String
The remote address will be in the format "<addr>,<port>" where the address is in numeric format, IPv4, or IPv6.

  Remote Address
TCP returns a standard struct sockaddr for gensio_get_raddr(3).

  Remote ID
Remote is not supported.

UDP
udp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
hostname = [ipv4|ipv6|ipv6n4,]<name> A UDP gensio creates a UDP socket, but it makes it look like an unrealiable stream of data. The specification is the same as a TCP socket, except that a UDP socket is created, obviously. The semantics of a UDP socket are a little bit strange. A connecting UDP socket is fairly straightforward, it opens a local socket and sends data to the remote socket. An accepter gensio is not so straightforward. The accepter gensio will create a new accepted gensio for any packet it receives from a new remote host. If you disable read on any of the accepted gensio or disable accepts on the accepting gensio, it will stop all reads on all gensios associated with that accepting gensio. UDP gensios are not reliable, but are obviously packet-oriented. In addition to readbuf, the udp gensio takes the following options:

laddr=<addr>
    An address specification to bind to on the local socket to set the local address.

  Remote Address String
The remote address will be in the format "<addr>,<port>" where the address is in numeric format, IPv4, or IPv6.

  Remote Address
UDP returns a standard struct sockaddr for gensio_get_raddr(3).

  Remote ID
Remote is not supported.

SCTP
sctp[(<options>)][,<hostname>],<port>[[,<hostname>],<port>[...]]
hostname = [ipv4|ipv6|ipv6n4,]<name> An SCTP gensio is specified like a UDP or TCP one. However, the semantics are different. For a connecting gensio, it will attempt to create a multi-homed connect with all the specified hostnames and ports. All the ports must be the same. For an accepter gensio, it will create a single socket with all the specified addresses as possible destinations. Again, all the ports must be the same. SCTP gensios are reliable. They are not, at the moment, packet oriented. There is currently no support of SCTP_EXPLICIT_EOR in the Linux implementation of SCTP, and without that it would be hard to make it packet oriented. In addition to readbuf, the sctp gensio takes the following options:

instreams=<n>

ostreams=<n>
    These specify the number of incoming and outgoing streams for the connection. The default is one. The stream is given in the auxdata for read and write in the format "stream=<n>".

laddr=<addr>
    An address specification to bind to on the local socket to set the local address. SCTP support out of band (oob) data, which is data that will be delivered out of order as soon as possible. This comes in a normal read, but with "oob" in the auxdata. You can send oob data by adding "oob" to the write auxdata. See documentation on SCTP for more details.

  Remote Address String
The remote address will be in the format "<addr>,<port>[,<addr>,<port>[...]]" where the address is in numeric format, IPv4, or IPv6. Each remote address for the SCTP connection is listed.

  Remote Address
SCTP returns a packed struct sockaddr for gensio_get_raddr(3), per SCTP semantics.

  Remote ID
Remote is not supported.

serialdev
serialdev[(<options>)],<device>[,<serialoption>[,<serialoption>]] A serialdev connection is a local serial port. The device is a /dev/xxx type, and should be real stream device of some type that normal termios work on (except for wronly). This is, no surprise, a serial gensio. One problem with serialdev and UUCP locking is that if you fork() a process while one is open, the forked process will have the serialdev but the value in the UUCP lockfile will be incorrect. There's not much that can be done about this, so be careful. In addition to readbuf, the serialdev gensio takes the following options:

nouucplock[=true|false]
    disables UUCP locking on the device. Useful for /dev/tty, which shouldn't use locking. This is not available as a default.

There are a plethora of serialoptions, available as defaults:

[speed=]<speed><parity><databits><stopbits>
    This is a normal serial port configuration specification, like "9600N81". The "speed=" at the beginning is optional, but "speed" is a default type for this.

wronly[=true|false]
    Set the device to write only. No termios definition is done on the port. This can be done to talk to a line printer port, for instance. False by default.

nobreak[=true|false]
    Clear the break line at start (or don't clear it). Default it to not clear it (false).

rs485=off|<delay rts before send>:<delay rts after send>[:<conf>[:<conf>]]
    Set up RS-485 for the serial port. The first two parameters set the RTS delay (in milliseconds) of RTS before and after sending. The conf values can be: "rts_on_send" - RTS set when sending, "rts_after_send" - RTS set after sending, "rx_during_tx" - can receive and transmit at the same time, and "terminate_bus" - enable bus termination. Using "off" will disable rs485, that is useful for overriding a default. default is "off".

xonxoff[=true|false]
    Enable/disable xon/xoff flow control. Default is false.

rtscts[=true|false]
    Enable/disable rts/cts flow control. Default is false.

local[=true|false]
    Ignore/don't ignore the modem control lines. The default it to not ignore them (false). However, if you don't ignore the modem control lines, it can result in long shutdown delays.

hangup-when-done[=true|false]
    Lower/don't lower the modem control lines when the gensio is closed. The default is to not lower the modem control lines on close (false).

  Remote Address String
The remote address string is the device and serial parms, in a format like "9600N81[,<option>[,<option>[...]]]". Options are one of: XONXOFF, RTSCTS, CLOCAL, HANGUP_WHEN_DONE, RTSHI, RTSLO, DTRHI, DRLO, offline.

  Remote Address
Remote address is not supported.

  Remote ID
The remote ID for the serial dev is the file descriptor returned as an integer.

stdio
accepter = stdio[(options)]
connecting = stdio[(options)],<program> The stdio gensio is a fairly strange one, but it's fairly useful. A connecting stdio gensio runs the given program (unless self is set as an option) and connects its standard input and output to the gensio's main channel. So it's easy to run a program and interact with it. If you want to get stderr from the gensio, open a channel on the main channel gensio, see below. For connecting gensios, in the forked process, the code will set the uid and guid to the current set effective uid and guid if the effective and real uids are different. This way a user can set the effective uid and gid to what they want the program to run under, but keep the uid and gid to the (probably root) values so they can be restored to those values after opening the pty. The group list is also set to the groups the effective userid is in. Note that nothing is done if the effective and real userids are the same. The connecting gensio support the GENSIO_CONTROL_ENVIRONMENT control to allow the environment to be set for the new process. An accepting gensio immediately does a connection when started and connection stdin and stdout of the running program to the gensio. In addition to readbuf, a connecting stdio takes the following options:

self[=true|false]
    Instead of starting a program, connect to the running program's stdio. This is the same as an accepting stdio gensio, except you don't have to go through the accept process.

stderr-to-stdout
    Send standard error output to standard out instead of having a separate channel for it.

  Channels
The stdio connecting gensio that start another program does not provide stderr as part of the main gensio. You must open a channel with gensio_open_channnel() to get stderr output. The args for gensio_open_channel() may be an optional "readbuf=<num>" and sets the size of the input buffer.

  Remote Address String
The remote address string is either "stdio" for the main channel or "stderr" for the error channel.

  Remote Address
Remote address is not supported.

  Remote ID
The remote ID is the pid for the remote device, only for connecting gensios that start a program, not for any other type.

echo
connecting = echo[(options)] The echo gensio just echos back all the data written to it. Useful for testing. In addition to readbuf, a connecting stdio takes the following options:

noecho[=true|false]
    Instead of echoing the data, just become a data sink.

  Remote Address String
The remote address string is "echo".

  Remote Address
Remote address is not supported.

  Remote ID
Remote ID is not supported.

dummy
accepter = dummy The dummy gensio accepter is useful for place holding, where you don't want a real working accepter but need to put something. As you might guess, it doesn't do anything.

  Remote Address String
The remote address string is not supported.

  Remote Address
Remote address is not supported.

  Remote ID
Remote ID is not supported.

ipmisol
ipmisol[(options)],<openipmi arguments>[,ipmisol option[,...]] An ipmisol gensio creates an IPMI Serial Over LAN connection to an IPMI server. See the OpenIPMI documentation for information on the arguments. This is a serial gensio, but the baud rate settings are fairly limited. In addition to readbuf, the ipmisol gensio takes the following options:

writebuf=<n>
    to set the size of the write buffer.

It also takes the following ipmisol options:

9600, 19200, 38400, 57600, 115200
    Baud rate, 9600 by default. Anything after the number is ignored, for compatibility with things like "N81". You cannot set those values for ipmisol, they are fixed at "N81".

nobreak[=true|false]
    Disable break processing. False by default.

authenticated[=true|false]
    Enable or disable authentication. True by default.

encrypted[=true|false]
    Enable or disable encrypted. True by default.

deassert-CTS-DCD-DSR-on-connect[=true|false]
    False by default

shared-serial-alert=fail|deferred|succeed
    Behavior of handling serial alerts. fail by default.

ack-timeout=<number>
    The time (in microseconds) when an ack times out. 1000000 by default.

ack-retries=<number>
    The number of times (ack-timeouts) an ack is re-sent before giving up. 10 by default.

  Remote Address String
The remote address string is not supported.

  Remote Address
Remote address is not supported.

  Remote ID
Remote ID is not supported.

telnet
A telnet gensio is a filter that sits on top of another gensio. It runs the standard telnet protocol andn support RFC2217. In addition to readbuf, the telnet gensio takes the following options:

writebuf=<n>
    set the size of the write buffer.

rfc2217[=true|false]
    enable or disable RFC2217 mode for this gensio. If this is enabled and the remote end of the connection supports RFC2217 also, the gensio will be set up as a serial gensio and you can do normal serial gensio handling on it.

mode=client|server
    Set the telnet mode to client or server. This lets you run a telnet server on a connecting gensio, or a telnet client on an accepter gensio.

  Remote info
telnet passes remote id, remote address, and remote string to the child gensio.

ssl
An SSL gensio runs the SSL/TLS protocol on top of another gensio. That gensio must be reliable. Use is pretty straightforward. The hardest part about using the SSL gensio is the certificates. A server SSL gensio must be given a certificate and a key. A client SSL gensio must be given a certificate authority. A client will user the certificate authority to verify that the server has the proper certificate and keys. The gensio has options to have the server request the certificate from the client and validate it. SSL gensios are reliable. They are also packet-oriented. In addition to readbuf, the SSL gensio takes the following options:

writebuf=<n>
    set the size of the write buffer.

CA=<filepath>
    Set a place to look for certificates for authorization. If this ends in a "/", then this is expected to be a directory that contains files with certificates that must be hashed per OpenSSL (see the "openssl rehash" command for details. Otherwise it is a single file that contains one or more certificates. The default CA path is used if not specified.

key=<filename>
    Specify the file to get the private key for the server. This is required for servers. It may be specified for clients, and is required for the client if the server requires a certificate (it has CA set).

cert=<filename>
    Specify the file that contains the certificate used for the connection. If this is not specified, the certificate is expected to be in the key file.

mode=client|server
    Normally an accepter gensio is in server mode and a connecting gensio is in client mode. This can be used to switch the roles and run in SSL server mode on a connecting gensio, or vice versa.

clientauth[=true|false]
    Normally a client is not authorized by the server. This requires that the client provide a certificate and authorizes that certificate. Ignored for client mode.

allow-authfail[=true|false]
    Normally if the remote end certificate is not valid, the SSL gensio will close the connection. This open allows the open to succeed with an invalid or missing certificate. Note that the user should verify that authentication is set using gensio_is_authenticated(). Verification of the common name is not done. The application should do this, it can fetch the common name and other certificate data through a control interface. You can use self-signed certificates in this interface. Just be aware of the security ramifications. This gensio is fairly flexible, but you must use it carefully to have a secure interface. The SSL gensio will call the gensio event callback (client) or the gensio acceptor event callback (server) after the certificate is received but before it is validated with the GENSIO_EVENT_PRECERT_VERIFY or GENSIO_ACC_EVENT_PRECERT_VERIFY events. This allows the user to validate data from the certificate (like common name) with GENSIO_CONTROL_GET_PEER_CERT_NAME or set a certificate authority for the validation with GENSIO_CONTROL_CERT_AUTH.

  Remote info
ssl passes remote id, remote address, and remote string to the child gensio.

certauth
An certauth gensio runs an authentication protocol to on top of another gensio. That gensio must be reliable and encrypted. This is like the reverse of SSL. The client has a key and certificate, the server has a certificate authority (CA). This also supports password authentication. Once authentication occurs, this gensio acts as a passthrough. The readbuf option is not available in the gensio. The certauth gensio takes the following options:

CA=<filepath>
    Set a place to look for certificates for authorization. If this ends in a "/", then this is expected to be a directory that contains files with certificates that must be hashed per OpenSSL, see the gensio-keygen(1) in the rehash section for details. Otherwise it is a single file that contains one or more certificates. The default CA path for openssl is used if not specified. This is used on the server only, it is ignored on clients.

key=<filename>
    Specify the file to get the private key for the client. This is required for clients. It is ignored on server.

cert=<filename>
    Specify the file to get the private key for the client. This is required for clients. It is ignored on server. If this is not specified, the certificate is expected to be in the key file.

username=<name>
    Specify a username to authenticate with on the remote end. This is required for the client. It is ignored on the server.

service=<string>
    Set the remote service requested by the client. Optional, but the other end may reject the connection if it is not supplied. Ignored on the server.

password=<string>
    Specify the password to use for password authentication. This is not recommended, the callback is more secure to use.

mode=client|server
    Normally an accepter gensio is in server mode and a connecting gensio is in client mode. This can be used to switch the roles and run in server mode on a connecting gensio, or vice versa.

allow-authfail[=true|false]
    Normally if the remote end certificate is not valid, the certauth gensio will close the connection. This open allows the open to succeed with an invalid or missing certificate. Note that the user should verify that authentication is set using gensio_is_authenticated().

use-child-auth[=true|false]
    If the child gensio is authenticated, then do not run the protocol, just go straight into passthrough mode and don't do any authentication.

enable-password[=true|false]
    On the server, allow passwords for login. On the client, send a password if asked for one. By default passwords are disabled. Use of passwords is much less secure than certificates, so this is discouraged.

Verification of the common name is not done. The application should do this, it can fetch the common name and other certificate data through a control interface. It may also use the username fetched through the control interface. You can use self-signed certificates in this interface. Just be aware of the security ramifications. This gensio is fairly flexible, but you must use it carefully to have secure authentication. The certauth gensio has 4 major callbacks dealing with authentication of the user. They may or may not be called depending on the circumstances. The normal events come in if you have allocated a gensio and are doing an open. The _ACC_ events come in if it is coming in from an accept and there is no gensio reported yet. In the _ACC_ case, be careful, do not use the given gensio for anything but checking certificate and username parameters, and do not save it. All these calls should return 0 if they want the authentication to immediately succeed, EKEYREJECTED if they reject the authentication, ENOTSUP if they want certauth to ignore that part of the authentication, or any other errno will result in the connetion being shut down. The callbacks are:

GENSIO_EVENT_AUTH_BEGIN / GENSIO_ACC_EVENT_AUTH_BEGIN
    On the server side, this is called when to authentication is requested buy the client. The username will be available if the user provided it via GENSIO_CONTROL_USERNAME.

GENSIO_EVENT_PRECERT_VERIFY / GENSIO_ACC_EVENT_PRECERT_VERIFY
    On the server side, thi is called after the certificate has been received but before it is verified. The user can use this to query the certificate and update the certificate authority based on username or certificate information.

GENSIO_EVENT_VERIFY_PASSWORD / GENSIO_ACC_EVENT_VERIFY_PASSWORD
    On the server side, this is called if the certificate verification has failed and after the password has been requested from the remote end. The password is passed in, it is cleared immediately after this call.

GENSIO_EVENT_REQUEST_PASSWORD / GENSIO_ACC_EVENT_REQUEST_PASSWORD
    On the client side, this is called if the server requests that a password be sent and the password is not already set for the gensio. The requested password is immediately cleared after being sent to the server.

  Remote info
certauth passes remote id, remote address, and remote string to the child gensio.

pty
pty[(options)],<program> Create a pty and run a program on the other end of it. This is sort of like stdio, but the program is running on a terminal. Only connection gensios are supported. pty has some unusual handling to allow execution of login shells of users from root. If the first character of the program is '-', it is removed from the execution of the command but left in argv[0]. This will cause a shell to act as a login shell. In the forked process, the pty code will set the uid and guid to the current set effective uid and guid if the effective and real uids are different. This way a user can set the effective uid and gid to what the want to pty to run under, but keep the real uid and gid to the (probably root) values so they can be restored to those values after opening the pty. The group list is also set to the groups the effective userid is in. Note that nothing is done if the effective and real userids are the same. The pty gensio support the GENSIO_CONTROL_ENVIRONMENT control to allow the environment to be set for the new process.

  Remote Address String
The remote address string the program and arguments run on the pty.

  Remote Address
Remote address is not supported.

  Remote ID
Remote ID is the pid if the process run on the pty.

Forking and gensios
Unlike normal file descriptors, when you fork with a gensio, you now have two unassociated copies of the gensios. So if you do operations on one, it might mess up the other. Even a close might cause issues, if you close an SSL connection, it sends data to the other end to close the connection, even if the other fork doesn't want that. To avoid issues with this, you should generally first make sure that no thread is in a wait, service call, or any type of thing that would examine file descriptors or timers and act on them. This is very important, and you must do it before you fork. Then you should call:

    gensio_disable(io)

on all the gensios that the fork is not using, then free the gensios. Don't use close, use free. Then you should call:

    gensio_acc_disable(acc)

on every gensio accepter you are not using, then free them. If a connection is in progress and has not been reported to the user, it will be disabled then closed. You cannot share a gensio between two different processes.

SEE ALSO
gensiotool(1), sctp(7), udp(7), tcp(7)

KNOWN PROBLEMS
None.

AUTHOR

Corey Minyard <minyard@acm.org>