net/0001755000000000000000000000000011025276022010340 5ustar rootrootnet/ipsvd-1.0.0/0000755000000000000000000000000011025276022012116 5ustar rootrootnet/ipsvd-1.0.0/doc/0000755000000000000000000000000011025276022012663 5ustar rootrootnet/ipsvd-1.0.0/doc/benefits.html0000644000000000000000000001152411025276022015353 0ustar rootroot ipsvd - benefits G. Pape
ipsvd

ipsvd - benefits


One daemon for each service
Powerful client-based instructions
Secure DNS client library
Reliable service management and logging
Small footprint SSL support (on Linux and MacOSX)
Small code size

One daemon for each service

Unlike other projects also handling IP services through inetd-compatible server programs that provide one daemon to handle several services on multiple server addresses (ipaddress:port), ipsvd provides daemons that handle one server address only. Setting up one service daemon for each server address separates the configurations of services, allows to apply different memory and other resource limits easily, and supports running in changed root directories. ipsvd instructions optionally can be shared.

Powerful client-based instructions

ipsvd allows flexible dynamic instructions and fast static instructions. Dynamic instructions defined through a directory can be adjusted on the fly through other programs and the administrator. The filesystem's file and directory permissions can be used to grant and restrict access to the configuration. For mostly static instructions, an instructions directory can be compiled into a constant data base for faster lookup.

Based on ipsvd's client-based instructions, the process state of the server program can be altered, the per-client concurrency can be adjusted, connections can be denied, and even a completely different server program can be started for special clients, see some examples.

Clients are identified by their IP address and through IP address ranges, by the fully qualified domain name the client's IP address reverse-resolves and parts if it, and by host names currently resolving to the client's IP address (to identify clients through dynamic DNS names), see ipsvd instructions for details.


Secure DNS client library

The ipsvd programs use the djbdns client library to query the DNS. This DNS client library is known to be secure yet very convenient.

Reliable service management and logging

The daemons provided by the ipsvd package normally are run by a runsv supervisor process, and started and managed through its control interface. The runit packages provides service supervision and a reliable logging facility.

Small footprint SSL support

On Linux and MacOSX the ipsvd package optionally provides the sslio program to encrypt a network connection using the SSLv3 implementation of the matrixssl library. This can be used to add SSLv3 functionality to server programs that do not support SSL, and to replace a built-in SSL support of a server program. See the examples.

If linked statically with the SSL library and the diet libc, the sslio program is less than 70k of size and has this ps xuw output on my system:

 USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
 nobody   22906  0.2  0.0   192  160 ?        S    13:22   0:00 sslio

Small code size

One of the ipsvd project's principles is to keep the code size small. This minimizes the possibility of bugs introduced by programmer's fault, and makes it more easy for security related people to proofread the source code. As of version 0.9.2 of ipsvd, the source is about 1400 lines of C code.

The small size and memory footprint of the programs makes the ipsvd package well suited for embedded systems.


Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/doc/examples.html0000644000000000000000000001173211025276022015373 0ustar rootroot ipsvd - examples G. Pape
ipsvd

ipsvd - examples


TCP/IP services
UDP/IP services
ipsvd instructions

TCP/IP service examples

This run script provides an identd service on 0.0.0.0:113
 #!/bin/sh
 exec tcpsvd -l0 0 113 identd
This run script provides a smtpfront-qmail service on 192.168.2.1:25, with per-host instructions through the constant database ./peers.cdb.
 #!/bin/sh
 exec 2>&1
 MAXSMTPD="`cat /var/qmail/control/concurrencyincoming`"
 exec softlimit -m2000000 \
   env SMTPGREETING=smarden.org \
       MAILRULES=/etc/mailfront/smtp/mailrules \
   tcpsvd -vp -uqmaild -c"$MAXSMTPD" -x./peers.cdb 192.168.2.1 25 \
     smtpfront-qmail
This run script provides a bincimaps service on 10.0.0.14:993, with per-host concurrency limit, and with per-host instructions through the directory ./peers.
 #!/bin/sh
 exec 2>&1
 exec tcpsvd -vvp -c40 -C10 -l0 -i./peers 10.0.0.14 993 \
   bincimap-up --logtype=multilog --conf=/etc/bincimap/bincimap.conf --ssl -- \
     /usr/bin/checkpw /usr/sbin/bincimapd
This run script provides a bincimaps service on 10.0.0.14:993, but using the sslio program, and so the matrixssl library, instead of bincimap's builtin OpenSSL support.
 #!/bin/sh
 exec 2>&1
 exec tcpsvd -v -c40 -l0 10.0.0.14 993 \
   sslio -vv -C/imapd.pem -unobody -//etc/bincimap/bincimaps/jail \
     bincimap-up --conf=/etc/bincimap/bincimap.conf -a -- \
       /usr/bin/checkpw /usr/sbin/bincimapd
This run script provides a qmail-smtpd service on 192.168.14.6:25, with per-host concurrency limit, and with per-host instructions through the directory ./peers.
 #!/bin/sh
 exec 2>&1
 exec softlimit -m2000000 \
  tcpsvd -vvh -i./peers -uqmaild \
    -c40 -C'10:421 per host concurrency limit reached\r\n' \
      192.168.14.6 25 qmail-smtpd
This run script provides a fnord https service on 10.0.5.4.
 #!/bin/sh
 exec 2>&1
 cd /public/10.0.5.4
 exec chpst -m300000 -Uwwwuser tcpsvd -v 10.0.5.4 443 \
   sslio -v -unobody -//etc/fnord/jail -C./cert.pem fnord

UDP/IP service examples

This run script provides a talkd service on 192.168.1.1:517
 #!/bin/sh
 exec udpsvd -unobody:tty 192.168.1.1 517 in.talkd
This run script provides a tftpd service on 0.0.0.0:69 with per-IP-address instructions through the directory /etc/tftpd/peers
 #!/bin/sh
 cd /
 exec 2>&1
 exec udpsvd -v -lbootserver -unobody -i/etc/tftpd/peers 0 69 \
   in.tftpd -s /boot/tftpboot/

ipsvd instruction examples

This run script provides a telnetd TCP/IP service, with per-IP-address instructions through the directory ./peers
 #!/bin/sh
 exec tcpsvd -i./peers 0.0.0.0 23 in.telnetd
Per default any client IP address is allowed to connect to this service. To allow connections from 192.168.1.17, and to deny connections from anywhere else, do
 # touch ./peers/192.168.1.17; chmod 644 ./peers/192.168.1.17
 # touch ./peers/0; chmod 0 ./peers/0
To allow connections from 192.168.3.0-255, do
 # touch ./peers/192.168.3; chmod 644 ./peers/192.168.3
To deny connections from 10.0.*.* explicitly, do
 # touch ./peers/10.0; chmod 0 ./peers/10.0
To have TRUST=true set in the environment when running in.telnetd for a connection from 192.168.14.2, do
 # echo '+TRUST=true' >./peers/192.168.14.2; chmod 644 ./peers/192.168.14.2
To provide a sshd login for connections from 10.2.0.14 on port 23, and the usual telnetd service for all others, do
 # echo 'sshd -i' >./peers/10.2.0.14; chmod 744 ./peers/10.2.0.14
To allow only connections from IP addresses the (dynamic) hostnames floyd.dyn.smarden.org and greg.dyn.smarden.org currently resolve to, do
 # echo '=floyd.dyn.smarden.org' >./peers/0
 # echo '=greg.dyn.smarden.org' >>./peers/0
 # chmod 644 ./peers/0
See ipsvd instructions for details.
Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/doc/index.html0000644000000000000000000000625111025276022014664 0ustar rootroot ipsvd - internet protocol service daemons G. Pape

ipsvd - internet protocol service daemons


How to install ipsvd
Upgrading from previous versions of ipsvd

Benefits
How to use dietlibc

Examples

The ipsvd interface
The tcpsvd program
The sslsvd program (on Linux and MacOSX)
The udpsvd program

The ipsvd instructions
The ipsvd-cdb program

The sslio program (on Linux and MacOSX)


ipsvd is a set of internet protocol service daemons for Unix. It currently includes a TCP/IP service daemon, an SSLv3 TCP/IP service daemon (Linux and MacOSX), and an UDP/IP service daemon.

An internet protocol service (ipsv) daemon waits for incoming connections on a local socket; for new connections, it conditionally runs an arbitrary program with standard input reading from the socket, and standard output writing to the socket (if connected), to handle the connection. Standard error is used for logging.

ipsv daemons can be told to read and follow pre-defined instructions on how to handle incoming connections; based on the client's IP address or hostname, they can run different programs, set a different environment, deny a connection, or set a per host concurrency limit.

Normally the ipsv daemons are run by a supervisor process, such as runsv from the runit package, or supervise from the daemontools package.

ipsvd can be used to run services normally run by inetd, xinetd, or tcpserver.


ipsvd is discussed on the <misc@list.smarden.org> mailing list. To subscribe send an empty email to <misc-subscribe@list.smarden.org>. Send an empty email to <misc-help@list.smarden.org> for more information about this list.

A mailing list archive is available at gmane.org.


Related links:
Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/doc/install.html0000644000000000000000000000345111025276022015222 0ustar rootroot ipsvd - installation G. Pape
ipsvd

ipsvd - installation


ipsvd installs into /package. If you don't have a /package directory, create it now:
 # mkdir -p /package
 # chmod 1755 /package
Download ipsvd-1.0.0.tar.gz into /package and unpack the archive
 # cd /package
 # gunzip ipsvd-1.0.0.tar
 # tar -xpf ipsvd-1.0.0.tar
 # rm ipsvd-1.0.0.tar
 # cd net/ipsvd-1.0.0
If you are installing on Linux or MacOSX, and want to make the sslsvd and sslio programs available, download the matrixssl library version 1.8.3 (newer versions probably work too) and copy the archive to the src/matrixssl.tar.gz (alternatively download from the Debian archive)
 # cp matrixssl-1-8-3-open.tar.gz src/matrixssl.tar.gz
Now compile and install the ipsvd programs
 # package/install
If you want to make the man pages available in the /usr/local/man/ hierarchy, do
 # package/install-man
To report success:
 # mail pape-ipsvd-1.0.0@smarden.org <compile/sysdeps
If you use ipsvd regularly, please contribute to the project.

Refer to the examples to learn how to set up services with ipsvd.


Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/doc/ipsvd.7.html0000644000000000000000000000776011025276022015055 0ustar rootroot ipsvd(7) manual page G. Pape
ipsvd

Name

ipsvd - Internet protocol service daemon

Synopsis

ipsvd [-hp] [-l name] [-u user] [-i dir|-x cdb] [-t sec] host port prog

Description

An implementation of an internet protocol service daemon provides the command line interface as shown in SYNOPSIS above (additional options are possible), and supports pre-defined instructions for handling connections through files in a instructions directory, and through a constant database, as described in ipsvd-instruct(5).

Currently there are two implementations of an internet protocol service daemon: a TCP/IP service daemon, tcpsvd(8), and an UDP/IP service daemon, udpsvd(8). More internet protocol service daemons may appear in the future.

Options

-i dir
read instructions for handling new connections from the instructions directory dir. See ipsvd-instruct(5) for details.
-x cdb
read instructions for handling new connections from the constant database cdb. The constant database normally is created from an instructions directory by running ipsvd-cdb(8).
-t sec
timeout. This option only takes effect if the -i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn’t accessed within the last sec seconds; ipsvd does not discard or remove a file if the user’s write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled.
-l name
local hostname. Do not look up the local hostname in DNS, but use name as hostname.
-u [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running prog. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed.
-h
Look up the client’s hostname in DNS.
-p
paranoid. After looking up the client’s hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client’s IP address. You should set this option if you use hostname based instructions. The -p option implies the -h option.

Signals

If an ipsvd receives a TERM signal, it exists with 0.

See Also

tcpsvd(8), sslsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/tcpsvd.8.html0000644000000000000000000001427611025276022015234 0ustar rootroot tcpsvd(8) manual page G. Pape
ipsvd

Name

tcpsvd - TCP/IP service daemon

Synopsis

tcpsvd [-hpEvv] [-c n] [-C n:msg] [-b n] [-u user] [-l name] [-i dir|-x cdb] [ -t sec] host port prog

Description

tcpsvd creates a TCP/IP socket, binds it to the address host:port, and listens on the socket for incoming connections.

On each incoming connection, tcpsvd conditionally runs a program, with standard input reading from the socket, and standard output writing to the socket, to handle this connection. tcpsvd keeps listening on the socket for new connections, and can handle multiple connections simultaneously.

tcpsvd optionally checks for special instructions depending on the IP address or hostname of the client that initiated the connection, see ipsvd-instruct(5).

Options

host
host either is a hostname, or a dotted-decimal IP address, or 0. If host is 0, tcpsvd accepts connections to any local IP address.
port
tcpsvd accepts connections to host:port. port may be a name from /etc/services or a number.
prog
prog consists of one or more arguments. For each connection, tcpsvd normally runs prog, with file descriptor 0 reading from the network, and file descriptor 1 writing to the network. By default it also sets up TCP-related environment variables, see tcp-environ(5)
-i dir
read instructions for handling new connections from the instructions directory dir. See ipsvd-instruct(5) for details.
-x cdb
read instructions for handling new connections from the constant database cdb. The constant database normally is created from an instructions directory by running ipsvd-cdb(8).
-t sec
timeout. This option only takes effect if the -i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn’t accessed within the last sec seconds; tcpsvd does not discard or remove a file if the user’s write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled.
-l name
local hostname. Do not look up the local hostname in DNS, but use name as hostname. This option must be set if tcpsvd listens on port 53 to avoid loops.
-u [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running prog. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed.
-c n
concurrency. Handle up to n connections simultaneously. Default is 30. If there are n connections active, tcpsvd defers acceptance of a new connection until an active connection is closed.
-C n[:msg]
per host concurrency. Allow only up to n connections from the same IP address simultaneously. If there are n active connections from one IP address, new incoming connections from this IP address are closed immediately. If n is followed by :msg, the message msg is written to the client if possible, before closing the connection. By default msg is empty. See ipsvd-instruct(5) for supported escape sequences in msg.

For each accepted connection, the current per host concurrency is available through the environment variable TCPCONCURRENCY. n and msg can be overwritten by ipsvd(7) instructions, see ipsvd-instruct(5). By default tcpsvd doesn’t keep track of connections.

-h
Look up the client’s hostname in DNS.
-p
paranoid. After looking up the client’s hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client’s IP address. You should set this option if you use hostname based instructions. The -p option implies the -h option.
-b n
backlog. Allow a backlog of approximately n TCP SYNs. On some systems n is silently limited. Default is 20.
-E
no special environment. Do not set up TCP-related environment variables.
-v
verbose. Print verbose messsages to standard output.
-vv
more verbose. Print more verbose messages to standard output.

See Also

ipsvd(7), sslsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8), sslio(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/udpsvd.8.html0000644000000000000000000001354411025276022015233 0ustar rootroot udpsvd(8) manual page G. Pape
ipsvd

Name

udpsvd - UDP/IP service daemon

Synopsis

udpsvd [-hpvv] [-u user] [-l name] [-i dir|-x cdb] [-t sec] host port prog

Description

udpsvd creates an UDP/IP socket, binds it to the address host:port, and listens on the socket for incoming datagrams.

If a datagram is available on the socket, udpsvd conditionally starts a program, with standard input reading from the socket, and standard output redirected to standard error, to handle this, and possibly more datagrams. udpsvd does not start the program if another program that it has started before still is running. If the program exits, udpsvd again listens to the socket until a new datagram is available. If there are still datagrams available on the socket, the program is restarted immediately.

udpsvd optionally checks for special intructions depending on the IP address or hostname of the client sending the datagram which not yet was handled by a running program, see ipsvd-instruct(5) for details.

Attention:

UDP is a connectionless protocol. Most programs that handle user datagrams, such as talkd(8), keep running after receiving a datagram, and process subsequent datagrams sent to the socket until a timeout is reached. udpsvd only checks special instructions for a datagram that causes a startup of the program; not if a program handling datagrams already is running. It doesn’t make much sense to restrict access through special instructions when using such a program.

On the other hand, it makes perfectly sense with programs like tftpd(8), that fork to establish a separate connection to the client when receiving the datagram. In general it’s adequate to set up special instructions for programs that support being run by tcpwrapper.

Options

host
host either is a hostname, or a dotted-decimal IP address, or 0. If host is 0, udpsvd accepts datagrams to any local IP address.
port
udpsvd accepts datagrams to host:port. port may be a name from /etc/services or a number.
prog
prog consists of one or more arguments. udpsvd normally runs prog to handle a datagram, and possibly more, that is sent to the socket, if there is no program that was started before by udpsvd still running and handling datagrams.
-i dir
read instructions for handling new connections from the instructions directory dir. See ipsvd-instruct(5) for details.
-x cdb
read instructions for handling new connections from the constant database cdb. The constant database normally is created from an instructions directory by running ipsvd-cdb(8).
-t sec
timeout. This option only takes effect if the -i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn’t accessed within the last sec seconds; udpsvd does not discard or remove a file if the user’s write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled.
-l name
local hostname. Do not look up the local hostname in DNS, but use name as hostname. By default udpsvd looks up the local hostname once at startup.
-u [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running prog. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed.
-h
Look up the client’s hostname in DNS.
-p
paranoid. After looking up the client’s hostname in DNS, look up the IP addresses in DNS for that hostname, and forget the hostname if none of the addresses match the client’s IP address. You should set this option if you use hostname based instructions. The -p option implies the -h option.
-v
verbose. Print verbose messages to standard output.
-vv
more verbose. Print more verbose messages to standard output.

See Also

ipsvd(7), tcpsvd(8), sslsvd(8), ipsvd-instruct(5), ipsvd-cdb(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/ipsvd-cdb.8.html0000644000000000000000000000302111025276022015566 0ustar rootroot ipsvd-cdb(8) manual page G. Pape
ipsvd

Name

ipsvd-cdb - create constant database from ipsvd instructions directory

Synopsis

ipsvd-cdb cdb cdb.tmp dir

Description

ipsvd-cdb scans the directory dir, and compiles all relevant information for an internet protocol service daemon, ipsvd(7), into the newly created constant database cdb.tmp. If cdb.tmp exists, it will be destroyed. ipsvd-cdb then renames cdb.tmp to cdb. If cdb exists, it will be destroyed.

ipsvd-cdb skips filenames starting with two dots.

If ipsvd-cdb has trouble building the constant database, it exits with an error message, and leaves cdb unchanged.

See Also

ipsvd(7), tcpsvd(8), sslsvd(8), udpsvd(8), ipsvd-instruct(5)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/ipsvd-instruct.5.html0000644000000000000000000001656611025276022016730 0ustar rootroot ipsvd-instruct(5) manual page G. Pape
ipsvd

Name

ipsvd-instruct - format of the ipsvd(8) instructions directory

Description

The internet protocol service daemons, ipsvd(7), can be told to read and follow instructions from a directory on incoming connections to the socket they listen on.

For mostly static instructions or for performance reasons, it is possible to compile the instructions from a directory into a constant database (cdb) with ipsvd-cdb(8) for faster lookup, and to tell ipsvd(7) to read the instructions from there.

Matching

On each incoming connection, the ipsvd(7) matches the client’s IP address against files in the instructions directory. For example, the IP address a.b.c.d which reverse resolves to moa.bit.smarden.org is matched against the following files in the instructions directory, in this order, first match wins:
    .
  1. a.b.c.d
  2. .
  3. a.b.c
  4. .
  5. a.b
  6. .
  7. a

If the client’s hostname has been successfully looked up in DNS:

    .
  1. moa.bit.smarden.org
  2. .
  3. bit.smarden.org
  4. .
  5. smarden.org
  6. .
  7. org

And finally the catchall file ‘‘0’’ (zero):

    .
  1. 0

After successfully matching a client’s IP address or hostname against the instructions directory, ipsvd(7) examines the file that matched the IP address or hostname, and acts accordingly:

    .
  1. If neither the user’s read permission, nor the user’s execute permission is set for the file, the connection is closed immediately.
  2. .
  3. If the file has the user’s execute permission set, ipsvd(7) reads the contents of the file and runs /bin/sh -c ’<contents>’ instead of the default program prog given at the command line for this connection.
  4. .
  5. If the file has the user’s read permission set, ipsvd(7) reads the contents of the file and interprets each line as an instruction for this connection (see below).

If the client’s IP address or hostname doesn’t match any file in the instructions directory, the default action is taken (the program prog is run to handle the connection).

Instructions

If ipsvd(7) is given instructions for an incoming connection, it reads the corresponding file and interprets each line as follows. The file may be empty, meaning that there is no special instruction.

Empty lines and lines starting with ‘‘#’’ are ignored.

+VAR=VALUE
environment. If the line starts with a plus (‘‘+’’), and the string following the plus contains a ‘‘=’’, ipsvd(7) puts the string following the plus into the environment before starting prog to handle the connection. If the string following the plus doesn’t contain a ‘‘=’’, ipsvd(7) makes sure that the environment variable with the name string is not set.
Cnum[:msg]
concurrency. If the line starts with a ‘‘C’’, and is followed by a number, the per host concurrency limit for the IP address that initiated the connection is set to this number. If num is zero, per host concurrency limit is disabled. If num is followed by ‘‘:msg’’, the message msg is written to this client if possible, if the per host concurrency limit is reached.

msg may contain backslash-escaped characters as follows: ‘‘\\’’ is converted to a single backslash, ‘‘\n’’ is converted to a new line character, and ‘‘\r’’ is converted to a carriage return.

On multiple concurrency instructions the last processed concurrency instruction is considered. Not all ipsvd(7)’s support per host concurrency.

=hostname[:forward]
check hostname. If the line starts with a ‘‘=’’, and is followed by a hostname, ipsvd(7) looks up the IP addresses for hostname in DNS and checks if the client’s IP address matches one of these IP addresses. If so, ipsvd(7) stops processing the instructions here and runs prog. If hostname is followed a colon and forward, ipsvd(7) now examines the file forward and acts accordingly, instead of running prog. All check hostname instructions in forward are ignored. If forward does not exist, the connection is closed.

hostname may be ‘‘0’’ (zero), matching any IP address.

Note: Using check hostname instructions can cause significant delay while responding to connection attempts, caused by DNS lookups.

If ipsvd(7) cannot interpret a line, it prints a warning, discards the line, and continues with the next instruction if any.

After processing all instructions, ipsvd(7) runs prog. If the file contains at least one check hostname instruction, and none was successful, it closes the connection instead of running prog.

Example Instructions

+MEMORY=20000
This instruction causes the environment variable ‘‘MEMORY’’ with the value ‘‘20000’’ to be available to the program prog that handles the connection.
+DEBUG=
This instruction adds the variable ‘‘DEBUG’’ with an empty value to the environment.
+LOGNAME
This instructions makes sure that the environment variable ‘‘LOGNAME’’ is unset when running prog.
C16
Set the per host concurrency to 16. A connection will be closed silently if there are already 16 active connections from this client’s IP address.
=floyd.dyn.smarden.org:127.0.0.1
Check IP address of the dynamic hostname floyd.dyn.smarden.org. If one of the IP addresses floyd.dyn.smarden.org currently resolves to matches the client’s IP address, handle the connection through the file 127.0.0.1 in the instructions directory.

See Also

ipsvd(7), ipsvd-cdb(8), tcpsvd(8), sslsvd(8), udpsvd(8), sslio(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/sslio.8.html0000644000000000000000000001505111025276022015052 0ustar rootroot sslio(8) manual page G. Pape
ipsvd

Name

sslio - SSL input/output for service programs

Synopsis

sslio [-cv] [-u user] [-U user] [-/ root] [-C cert] [-K key] [-A ca] prog

Description

sslio provides SSL encrypted network connections for service programs started by tcpsvd(8) or tcpserver(1), and tcpclient(1).

Normally sslio is started by tcpsvd(8) or tcpclient(1), in turn starts the service program prog, and runs as child process of the service program. After performing the SSL handshake, sslio reads SSL encrypted data from the network, and writes decrypted data to the service program prog; it reads data from the service program prog, and writes SSL encrypted data to the network. sslio should run under a different user ID than the service program, and with a changed root directory. When started by root, the -u option must be given, and the -U and -/ options should be given.

The sslio program uses the SSLv3 implementation of the matrixssl library.

Options

prog
prog consists of one or more arguments, specifying the service program normally run directly by tcpsvd(8), or tcpserver(1).
-u [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before reading data from, or writing data to the network. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option must be set when sslio is started by root, and cannot be set otherwise.
-U [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running prog. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option should be set when sslio is started by root, and cannot be set otherwise.
-/ root
chroot. Change the root directory to root before reading data from, or writing data to the network. This option should be set when sslio is started by root, and cannot be set otherwise.
-C cert
cert file (server mode). Read the certificate from the file cert (default is ‘‘./cert.pem’’). If the -/ option is given, first the root directory is changed, then the cert file is read.
-K key
private key (server mode). Read the private key from the file key (default is cert). If the -/ option is given, first the root directory is changed, then the private key is read.
-A ca
ca file (client mode). Read the trusted root certificate from the file ca. Multiple files can be specified, using a semicolon as delimiter. If the -/ option is given, first the root directory is changed, then the ca file is read.
-c
client mode. This option must be given when running sslio under tcpclient(1). In client mode, filedescriptors 6 and 7 are used instead of standard input and standard ouput to read from and write to the network and the service program. If the -A option is given, sslio refuses to connect to a servers which’s certificates cannot be verified by the root certificates, it accepts any server certificate otherwise.
-v
verbose. Print verbose messages to standard error.
-vv
more verbose. Print more verbose messages to standard error.
-vvv
even more verbose. Print even more verbose messages to standard error.

Environment

SSLIO_BUFIN
The environment variable SSLIO_BUFIN overrides the default input buffer size for sslio (8192).
SSLIO_BUFOU
The environment variable SSLIO_BUFOU overrides the default output buffer size for sslio (12288). If the output buffer is too small to hold encrypted or decrypted data, sslio automatically blows up the buffer to SSLIO_BUFOU more bytes.
SSLIO_BAD_CERTIFICATE
(client mode) If the environment variable SSLIO_BAD_CERTIFICATE is set, sslio -c accepts server ceritificates it would normally reject with fatal: ssl decode error: bad certificate
SSLIO_HANDSHAKE_TIMOUT
The environment variable SSLIO_HANDSHAKE_TIMEOUT overrides the default number of seconds sslio will try to complete the ssl handshake (300). If the handshake isn’t completed after this number of seconds, sslio exits.

See Also

sslsvd(8), tcpsvd(8), udpsvd(8), ipsvd(7), ipsvd-instruct(5), ipsvd-cdb(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/sslsvd.8.html0000644000000000000000000002130111025276022015232 0ustar rootroot sslsvd(8) manual page G. Pape
ipsvd

Name

sslsvd - SSLv3 TCP/IP service daemon

Synopsis

sslsvd [-hpEvv] [-c n] [-C n:msg] [-b n] [-u user] [-l name] [-i dir|-x cdb] [-t sec] [-U ssluser] [-/ root] [-Z cert] [-K key] host port prog

Description

sslsvd creates a TCP/IP socket, binds it to the address host:port, and listens on the socket for incoming SSLv3 connections.

On each incoming connection, sslsvd conditionally runs a program, with standard input reading from the socket, and standard output writing to the socket, to handle this connection. The data read and written to the socket will automatically decrypted and encrypted respectively by sslsvd. sslsvd keeps listening on the socket for new connections, and can handle multiple connections simultaneously.

sslsvd optionally checks for special instructions depending on the IP address or hostname of the client that initiated the connection, see ipsvd-instruct(5).

Options

host
host either is a hostname, or a dotted-decimal IP address, or 0. If host is 0, sslsvd accepts connections to any local IP address.
port
sslsvd accepts connections to host:port. port may be a name from /etc/services or a number.
prog
prog consists of one or more arguments. For each connection, sslsvd normally runs prog, with file descriptor 0 reading decrypted data from the network, and file descriptor 1 writing to be encrypted data to the network. By default it also sets up TCP-related environment variables, see tcp-environ(5)
-i dir
read instructions for handling new connections from the instructions directory dir. See ipsvd-instruct(5) for details.
-x cdb
read instructions for handling new connections from the constant database cdb. The constant database normally is created from an instructions directory by running ipsvd-cdb(8).
-t sec
timeout. This option only takes effect if the -i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn’t accessed within the last sec seconds; sslsvd does not discard or remove a file if the user’s write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled.
-l name
local hostname. Do not look up the local hostname in DNS, but use name as hostname.
-u [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running prog. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed.
-c n
concurrency. Handle up to n connections simultaneously. Default is 30. If there are n connections active, sslsvd defers acceptance of a new connection until an active connection is closed.
-C n[:msg]
per host concurrency. Allow only up to n connections from the same IP address simultaneously. If there are n active connections from one IP address, new incoming connections from this IP address are closed immediately. If n is followed by :msg, the message msg is written to the client if possible, before closing the connection. By default msg is empty. See ipsvd-instruct(5) for supported escape sequences in msg.

For each accepted connection, the current per host concurrency is available through the environment variable TCPCONCURRENCY. n and msg can be overwritten by ipsvd(7) instructions, see ipsvd-instruct(5). By default sslsvd doesn’t keep track of connections.

-h
Look up the client’s hostname in DNS.
-p
paranoid. After looking up the client’s hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client’s IP address. You should set this option if you use hostname based instructions. The -p option implies the -h option.
-b n
backlog. Allow a backlog of approximately n TCP SYNs. On some systems n is silently limited. Default is 20.
-E
no special environment. Do not set up TCP-related environment variables.
-v
verbose. Print verbose messsages to standard output.
-vv
more verbose. Print more verbose messages to standard output.

Ssl Options

-U [:]user[:group]
drop permissions. Set uid and gid to the user’s uid and gid, as found in /etc/passwd, before running the SSLv3 encrypt/decrypt process. If user is followed by a colon and a group, set the gid to group’s gid, as found in /etc/group, instead of user’s gid. If group consists of a colon-separated list of group names, set the group ids of all listed groups. If user is prefixed with a colon, the user and all group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option must be set when sslsvd is started by root.
-/ root
chroot. Change the root directory to root before running the SSLv3 encrypt/decrypt process. This option should be set when sslsvd is started by root.
-Z cert
cert file. Read the certificate from the file cert (default is ‘‘./cert.pem’’). If the -/ option is given, first the cert file is read, then the root directory is changed.
-K key
private key. Read the private key from the file key (default is cert). If the -/ option is given, first the cert file is read, then the root directory is changed.

Environment

SSLIO_BUFIN
The environment variable SSLIO_BUFIN overrides the default input buffer size for sslsvd (8192).
SSLIO_BUFOU
The environment variable SSLIO_BUFOU overrides the default output buffer size for sslsvd (12288). If the output buffer is too small to hold encrypted or decrypted data, sslio automatically blows up the buffer to SSLIO_BUFOU more bytes.
SSLIO_HANDSHAKE_TIMOUT
The environment variable SSLIO_HANDSHAKE_TIMEOUT overrides the default number of seconds sslsvd will try to complete the ssl handshake (300). If the handshake isn’t completed after this number of seconds, the client will be disconnected.

See Also

ipsvd(7), tcpsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8), sslio(8)

http://smarden.org/ipsvd/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

net/ipsvd-1.0.0/doc/upgrade.html0000644000000000000000000000612311025276022015202 0ustar rootroot ipsvd - upgrading from previous versions G. Pape
ipsvd

ipsvd - upgrading from previous versions


0.14.0 to 1.0.0

No further action from you is required.

0.13.0 to 0.14.0

The command line options to tell the tcpsvd, udpsvd, sslsvd, and sslio programs to drop permissions have been made more flexible to allow specifying numerial uids and gids, as well as a list of multiple groups or gids.

0.12.0 or 0.12.1 to 0.13.0

The ssl programs have been improved slightly, and build against the matrixssl library version 1.8.3.

0.11.x to 0.12.0 or 0.12.1

This version introduces the new sslsvd SSLv3 TCP/IP service daemon. sslsvd integrates the sslio program into tcpsvd, so that initializing the SSL session and reading the SSL key and certificate doesn't need to be done for each incoming connection, but only once on startup of the service daemon.

0.10.1 to 0.11.0 or 0.11.1

The sslio program also runs on MacOSX, see the installation insructions on how to enable it in the build and testing process.

0.9.x to 0.10.1

Client support has been added to the sslio program to have it run under tcpclient. The logging, especially for ssl warnings and errors, has been improved, and the documentation updated.

Here's a sample on how to use sslio in client mode with tcpclient, a https@ program derived from ucspi-tcp's http@ program:

 #!/bin/sh
 echo "GET /${2-} HTTP/1.0
 Host: ${1-0}:${3-443}
 " | tcpclient -RHl0 -- "${1-0}" "${3-443}" sslio -c sh -c '
   addcr >&7
   exec delcr <&6
 ' | awk '/^$/ { body=1; next } { if (body) print }'

0.8.0 or 0.8.2 to 0.9.x

This version introduces the new sslio program (for Linux only), which can be used to encrypt network connections using SSLv3. A new web page describing some of ipsvd's benefits has been added to the documentation.

0.7.0 or 0.7.1 to 0.8.0 or 0.8.2

No further action from you is required.

0.6.1 to 0.7.0 or 0.7.1

A new type of instruction has been added. ipsvd now can be told to look up IP addresses of (dynamic) hostnames on incoming connections, and to handle a connection through different instructions if the client's IP address matches one of these addresses. See ipsvd-instruct for details. The examples have been updated slightly, and additionally includes an example of the new check host instructions.
Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/doc/usedietlibc.html0000644000000000000000000000162411025276022016050 0ustar rootroot ipsvd - use dietlibc G. Pape
ipsvd

ipsvd - use dietlibc


To recompile the ipsvd programs with the diet libc, check that you have the recent version of dietlibc installed.

Change to the package directory of ipsvd

 # cd /package/net/ipsvd/
Change the conf-cc and conf-ld to use diet
 # echo 'diet -Os gcc -O2 -Wall' >src/conf-cc
 # echo 'diet -Os gcc -s -Os -pipe' >src/conf-ld
Rebuild and install the ipsvd programs:
 # package/install

Gerrit Pape <pape@smarden.org>
net/ipsvd-1.0.0/man/0000755000000000000000000000000011025276022012671 5ustar rootrootnet/ipsvd-1.0.0/man/ipsvd-cdb.80000644000000000000000000000145711025276022014644 0ustar rootroot.TH ipsvd-cdb 8 .SH NAME ipsvd-cdb \- create constant database from ipsvd instructions directory .SH SYNOPSIS .B ipsvd-cdb .I cdb .I cdb.tmp .I dir .SH DESCRIPTION .B ipsvd-cdb scans the directory .IR dir , and compiles all relevant information for an internet protocol service daemon, .BR ipsvd (7), into the newly created constant database .IR cdb.tmp . If .I cdb.tmp exists, it will be destroyed. .B ipsvd-cdb then renames .I cdb.tmp to .IR cdb . If .I cdb exists, it will be destroyed. .P .B ipsvd-cdb skips filenames starting with two dots. .P If .B ipsvd-cdb has trouble building the constant database, it exits with an error message, and leaves .I cdb unchanged. .SH SEE ALSO ipsvd(7), tcpsvd(8), sslsvd(8), udpsvd(8), ipsvd-instruct(5) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/ipsvd-instruct.50000644000000000000000000001301111025276022015751 0ustar rootroot.TH ipsvd-instruct 5 .SH NAME ipsvd-instruct \- format of the ipsvd(8) instructions directory .SH DESCRIPTION The internet protocol service daemons, .BR ipsvd (7), can be told to read and follow instructions from a directory on incoming connections to the socket they listen on. .P For mostly static instructions or for performance reasons, it is possible to compile the instructions from a directory into a constant database (cdb) with .BR ipsvd-cdb (8) for faster lookup, and to tell .BR ipsvd (7) to read the instructions from there. .SH MATCHING On each incoming connection, the .BR ipsvd (7) matches the client's IP address against files in the instructions directory. For example, the IP address .I a.b.c.d which reverse resolves to .I moa.bit.smarden.org is matched against the following files in the instructions directory, in this order, first match wins: .TP 1. .I a.b.c.d .TP 2. .I a.b.c .TP 3. .I a.b .TP 4. .I a .P If the client's hostname has been successfully looked up in DNS: .TP 5. .I moa.bit.smarden.org .TP 6. .I bit.smarden.org .TP 7. .I smarden.org .TP 8. .I org .P And finally the catchall file ``0'' (zero): .TP 9. .I 0 .P After successfully matching a client's IP address or hostname against the instructions directory, .BR ipsvd (7) examines the file that matched the IP address or hostname, and acts accordingly: .TP 1. If neither the user's read permission, nor the user's execute permission is set for the file, the connection is closed immediately. .TP 2. If the file has the user's execute permission set, .BR ipsvd (7) reads the contents of the file and runs .I /bin/sh \-c '' instead of the default program .I prog given at the command line for this connection. .TP 3. If the file has the user's read permission set, .BR ipsvd (7) reads the contents of the file and interprets each line as an instruction for this connection (see below). .P If the client's IP address or hostname doesn't match any file in the instructions directory, the default action is taken (the program .I prog is run to handle the connection). .SH INSTRUCTIONS If .BR ipsvd (7) is given instructions for an incoming connection, it reads the corresponding file and interprets each line as follows. The file may be empty, meaning that there is no special instruction. .P Empty lines and lines starting with ``#'' are ignored. .TP .BI + VAR=VALUE environment. If the line starts with a plus (``+''), and the string following the plus contains a ``='', .BR ipsvd (7) puts the string following the plus into the environment before starting .IR prog to handle the connection. If the string following the plus doesn't contain a ``='', .BR ipsvd (7) makes sure that the environment variable with the name string is not set. .TP .BI C num\fR[:\fImsg\fR] concurrency. If the line starts with a ``C'', and is followed by a number, the per host concurrency limit for the IP address that initiated the connection is set to this number. If .I num is zero, per host concurrency limit is disabled. If .I num is followed by .RI ``: msg\fR'', the message .I msg is written to this client if possible, if the per host concurrency limit is reached. .I msg may contain backslash-escaped characters as follows: ``\\\\'' is converted to a single backslash, ``\\n'' is converted to a new line character, and ``\\r'' is converted to a carriage return. On multiple concurrency instructions the last processed concurrency instruction is considered. Not all .BR ipsvd (7)'s support per host concurrency. .TP .BI = hostname\fR[:\fIforward\fR] check hostname. If the line starts with a ``='', and is followed by a hostname, .BR ipsvd (7) looks up the IP addresses for .I hostname in DNS and checks if the client's IP address matches one of these IP addresses. If so, .IR ipsvd (7) stops processing the instructions here and runs .IR prog . If .I hostname is followed a colon and .IR forward , .BR ipsvd (7) now examines the file .I forward and acts accordingly, instead of running .IR prog . All check hostname instructions in .I forward are ignored. If .I forward does not exist, the connection is closed. .I hostname may be ``0'' (zero), matching any IP address. Note: Using check hostname instructions can cause significant delay while responding to connection attempts, caused by DNS lookups. .P If .BR ipsvd (7) cannot interpret a line, it prints a warning, discards the line, and continues with the next instruction if any. .P After processing all instructions, .BR ipsvd (7) runs .IR prog . If the file contains at least one check hostname instruction, and none was successful, it closes the connection instead of running .IR prog . .SH EXAMPLE INSTRUCTIONS .TP +MEMORY=20000 This instruction causes the environment variable ``MEMORY'' with the value ``20000'' to be available to the program .I prog that handles the connection. .TP +DEBUG= This instruction adds the variable ``DEBUG'' with an empty value to the environment. .TP +LOGNAME This instructions makes sure that the environment variable ``LOGNAME'' is unset when running .IR prog . .TP C16 Set the per host concurrency to 16. A connection will be closed silently if there are already 16 active connections from this client's IP address. .TP =floyd.dyn.smarden.org:127.0.0.1 Check IP address of the dynamic hostname .IR floyd.dyn.smarden.org . If one of the IP addresses .I floyd.dyn.smarden.org currently resolves to matches the client's IP address, handle the connection through the file .I 127.0.0.1 in the instructions directory. .SH SEE ALSO ipsvd(7), ipsvd-cdb(8), tcpsvd(8), sslsvd(8), udpsvd(8), sslio(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/ipsvd.70000644000000000000000000000554611025276022014120 0ustar rootroot.TH ipsvd 7 .SH NAME ipsvd \- Internet protocol service daemon .SH SYNOPSIS .I ipsvd [\-hp] [\-l .IR name ] [\-u .IR user ] [\-i .IR dir |\-x .IR cdb ] [\-t .IR sec ] .I host .I port .I prog .SH DESCRIPTION An implementation of an internet protocol service daemon provides the command line interface as shown in SYNOPSIS above (additional options are possible), and supports pre-defined instructions for handling connections through files in a instructions directory, and through a constant database, as described in .BR ipsvd-instruct (5). .P Currently there are two implementations of an internet protocol service daemon: a TCP/IP service daemon, .BR tcpsvd (8), and an UDP/IP service daemon, .BR udpsvd (8). More internet protocol service daemons may appear in the future. .SH OPTIONS .TP .B \-i \fIdir read instructions for handling new connections from the instructions directory .IR dir . See .BR ipsvd-instruct (5) for details. .TP .B \-x \fIcdb read instructions for handling new connections from the constant database .IR cdb . The constant database normally is created from an instructions directory by running .BR ipsvd-cdb (8). .TP .B \-t \fIsec timeout. This option only takes effect if the \-i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn't accessed within the last .I sec seconds; .B ipsvd does not discard or remove a file if the user's write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled. .TP .B \-l \fIname local hostname. Do not look up the local hostname in DNS, but use .I name as hostname. .TP .B \-u \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running .IR prog . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. .TP .B \-h Look up the client's hostname in DNS. .TP .B \-p paranoid. After looking up the client's hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client's IP address. You should set this option if you use hostname based instructions. The \-p option implies the \-h option. .SH SIGNALS If an .B ipsvd receives a TERM signal, it exists with 0. .SH SEE ALSO tcpsvd(8), sslsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/sslio.80000644000000000000000000001211011025276022014106 0ustar rootroot.TH sslio 8 .SH NAME sslio \- SSL input/output for service programs .SH SYNOPSIS .B sslio [\-cv] [\-u .IR user ] [\-U .IR user ] [\-/ .IR root ] [\-C .IR cert ] [\-K .IR key ] [\-A .IR ca ] .I prog .SH DESCRIPTION .B sslio provides SSL encrypted network connections for service programs started by .BR tcpsvd (8) or .BR tcpserver (1), and .BR tcpclient (1). .P Normally .B sslio is started by .BR tcpsvd (8) or .BR tcpclient(1), in turn starts the service program .IR prog , and runs as child process of the service program. After performing the SSL handshake, .B sslio reads SSL encrypted data from the network, and writes decrypted data to the service program .IR prog ; it reads data from the service program .IR prog , and writes SSL encrypted data to the network. .B sslio should run under a different user ID than the service program, and with a changed root directory. When started by root, the \-u option must be given, and the \-U and \-/ options should be given. .P The .B sslio program uses the SSLv3 implementation of the matrixssl library. .SH OPTIONS .TP .I prog .I prog consists of one or more arguments, specifying the service program normally run directly by .BR tcpsvd (8), or .BR tcpserver (1). .TP .B \-u \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before reading data from, or writing data to the network. If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option must be set when .B sslio is started by root, and cannot be set otherwise. .TP .B \-U \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running .IR prog . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option should be set when .B sslio is started by root, and cannot be set otherwise. .TP .B \-/ \fIroot chroot. Change the root directory to .I root before reading data from, or writing data to the network. This option should be set when .B sslio is started by root, and cannot be set otherwise. .TP .B \-C \fIcert cert file (server mode). Read the certificate from the file .I cert (default is ``./cert.pem''). If the \-/ option is given, first the root directory is changed, then the cert file is read. .TP .B \-K \fIkey private key (server mode). Read the private key from the file .I key (default is .IR cert ). If the \-/ option is given, first the root directory is changed, then the private key is read. .TP .B \-A \fIca ca file (client mode). Read the trusted root certificate from the file .IR ca . Multiple files can be specified, using a semicolon as delimiter. If the \-/ option is given, first the root directory is changed, then the ca file is read. .TP .B \-c client mode. This option must be given when running .B sslio under .BR tcpclient (1). In client mode, filedescriptors 6 and 7 are used instead of standard input and standard ouput to read from and write to the network and the service program. If the \-A option is given, .B sslio refuses to connect to a servers which's certificates cannot be verified by the root certificates, it accepts any server certificate otherwise. .TP .B \-v verbose. Print verbose messages to standard error. .TP .B \-vv more verbose. Print more verbose messages to standard error. .TP .B \-vvv even more verbose. Print even more verbose messages to standard error. .SH ENVIRONMENT .TP SSLIO_BUFIN The environment variable .I SSLIO_BUFIN overrides the default input buffer size for .B sslio (8192). .TP SSLIO_BUFOU The environment variable .I SSLIO_BUFOU overrides the default output buffer size for .B sslio (12288). If the output buffer is too small to hold encrypted or decrypted data, .B sslio automatically blows up the buffer to .I SSLIO_BUFOU more bytes. .TP SSLIO_BAD_CERTIFICATE (client mode) If the environment variable .I SSLIO_BAD_CERTIFICATE is set, .B sslio \-c accepts server ceritificates it would normally reject with . fatal: ssl decode error: bad certificate .TP SSLIO_HANDSHAKE_TIMOUT The environment variable .I SSLIO_HANDSHAKE_TIMEOUT overrides the default number of seconds .B sslio will try to complete the ssl handshake (300). If the handshake isn't completed after this number of seconds, .B sslio exits. .SH SEE ALSO sslsvd(8), tcpsvd(8), udpsvd(8), ipsvd(7), ipsvd-instruct(5), ipsvd-cdb(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/sslsvd.80000644000000000000000000001551511025276022014307 0ustar rootroot.TH sslsvd 8 .SH NAME sslsvd \- SSLv3 TCP/IP service daemon .SH SYNOPSIS .B sslsvd [\-hpEvv] [\-c .IR n ] [\-C .IR n\fR:\fImsg ] [\-b .IR n ] [\-u .IR user ] [\-l .IR name ] [\-i .IR dir |\-x .IR cdb ] [\-t .IR sec ] [\-U .IR ssluser ] [\-/ .IR root ] [\-Z .IR cert ] [\-K .IR key ] .I host .I port .I prog .SH DESCRIPTION .B sslsvd creates a TCP/IP socket, binds it to the address .IR host :\fIport\fR, and listens on the socket for incoming SSLv3 connections. .P On each incoming connection, .B sslsvd conditionally runs a program, with standard input reading from the socket, and standard output writing to the socket, to handle this connection. The data read and written to the socket will automatically decrypted and encrypted respectively by .BR sslsvd . .B sslsvd keeps listening on the socket for new connections, and can handle multiple connections simultaneously. .P .B sslsvd optionally checks for special instructions depending on the IP address or hostname of the client that initiated the connection, see .BR ipsvd-instruct (5). .SH OPTIONS .TP .I host .I host either is a hostname, or a dotted-decimal IP address, or 0. If .I host is 0, .B sslsvd accepts connections to any local IP address. .TP .I port .B sslsvd accepts connections to .IR host :\fIport\fR. .I port may be a name from /etc/services or a number. .TP .I prog .I prog consists of one or more arguments. For each connection, .B sslsvd normally runs .IR prog , with file descriptor 0 reading decrypted data from the network, and file descriptor 1 writing to be encrypted data to the network. By default it also sets up TCP-related environment variables, see .BR tcp-environ (5) .TP .B \-i \fIdir read instructions for handling new connections from the instructions directory .IR dir . See .BR ipsvd-instruct (5) for details. .TP .B \-x \fIcdb read instructions for handling new connections from the constant database .IR cdb . The constant database normally is created from an instructions directory by running .BR ipsvd-cdb (8). .TP .B \-t \fIsec timeout. This option only takes effect if the \-i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn't accessed within the last .I sec seconds; .B sslsvd does not discard or remove a file if the user's write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled. .TP .B \-l \fIname local hostname. Do not look up the local hostname in DNS, but use .I name as hostname. .TP .B \-u \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running .IR prog . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. .TP .B \-c \fIn concurrency. Handle up to .I n connections simultaneously. Default is 30. If there are .I n connections active, .B sslsvd defers acceptance of a new connection until an active connection is closed. .TP .B \-C \fIn\fR[:\fImsg\fR] per host concurrency. Allow only up to .I n connections from the same IP address simultaneously. If there are .I n active connections from one IP address, new incoming connections from this IP address are closed immediately. If .I n is followed by .RI : msg\fR, the message .I msg is written to the client if possible, before closing the connection. By default .I msg is empty. See .BR ipsvd-instruct (5) for supported escape sequences in .IR msg . For each accepted connection, the current per host concurrency is available through the environment variable .IR TCPCONCURRENCY . .I n and .I msg can be overwritten by .BR ipsvd (7) instructions, see .BR ipsvd-instruct (5). By default .B sslsvd doesn't keep track of connections. .TP .B \-h Look up the client's hostname in DNS. .TP .B \-p paranoid. After looking up the client's hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client's IP address. You should set this option if you use hostname based instructions. The \-p option implies the \-h option. .TP .B \-b \fIn backlog. Allow a backlog of approximately .I n TCP SYNs. On some systems .I n is silently limited. Default is 20. .TP .B \-E no special environment. Do not set up TCP-related environment variables. .TP .B \-v verbose. Print verbose messsages to standard output. .TP .B \-vv more verbose. Print more verbose messages to standard output. .SS SSL OPTIONS .TP .B \-U \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running the SSLv3 encrypt/decrypt process. If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. This option must be set when .B sslsvd is started by root. .TP .B \-/ \fIroot chroot. Change the root directory to .I root before running the SSLv3 encrypt/decrypt process. This option should be set when .B sslsvd is started by root. .TP .B \-Z \fIcert cert file. Read the certificate from the file .I cert (default is ``./cert.pem''). If the \-/ option is given, first the cert file is read, then the root directory is changed. .TP .B \-K \fIkey private key. Read the private key from the file .I key (default is .IR cert ). If the \-/ option is given, first the cert file is read, then the root directory is changed. .SH ENVIRONMENT .TP SSLIO_BUFIN The environment variable .I SSLIO_BUFIN overrides the default input buffer size for .B sslsvd (8192). .TP SSLIO_BUFOU The environment variable .I SSLIO_BUFOU overrides the default output buffer size for .B sslsvd (12288). If the output buffer is too small to hold encrypted or decrypted data, .B sslio automatically blows up the buffer to .I SSLIO_BUFOU more bytes. .TP SSLIO_HANDSHAKE_TIMOUT The environment variable .I SSLIO_HANDSHAKE_TIMEOUT overrides the default number of seconds .B sslsvd will try to complete the ssl handshake (300). If the handshake isn't completed after this number of seconds, the client will be disconnected. .SH SEE ALSO ipsvd(7), tcpsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8), sslio(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/tcpsvd.80000644000000000000000000001145311025276022014271 0ustar rootroot.TH tcpsvd 8 .SH NAME tcpsvd \- TCP/IP service daemon .SH SYNOPSIS .B tcpsvd [\-hpEvv] [\-c .I n\fR] [\-C .I n\fR:\fImsg\fR] [\-b .I n\fR] [\-u .I user\fR] [\-l .I name\fR] [\-i .IR dir |\-x .IR cdb ] [ \-t .IR sec ] .I host .I port .I prog .SH DESCRIPTION .B tcpsvd creates a TCP/IP socket, binds it to the address .IR host :\fIport\fR, and listens on the socket for incoming connections. .P On each incoming connection, .B tcpsvd conditionally runs a program, with standard input reading from the socket, and standard output writing to the socket, to handle this connection. .B tcpsvd keeps listening on the socket for new connections, and can handle multiple connections simultaneously. .P .B tcpsvd optionally checks for special instructions depending on the IP address or hostname of the client that initiated the connection, see .BR ipsvd-instruct (5). .SH OPTIONS .TP .I host .I host either is a hostname, or a dotted-decimal IP address, or 0. If .I host is 0, .B tcpsvd accepts connections to any local IP address. .TP .I port .B tcpsvd accepts connections to .IR host :\fIport\fR. .I port may be a name from /etc/services or a number. .TP .I prog .I prog consists of one or more arguments. For each connection, .B tcpsvd normally runs .IR prog , with file descriptor 0 reading from the network, and file descriptor 1 writing to the network. By default it also sets up TCP-related environment variables, see .BR tcp-environ (5) .TP .B \-i \fIdir read instructions for handling new connections from the instructions directory .IR dir . See .BR ipsvd-instruct (5) for details. .TP .B \-x \fIcdb read instructions for handling new connections from the constant database .IR cdb . The constant database normally is created from an instructions directory by running .BR ipsvd-cdb (8). .TP .B \-t \fIsec timeout. This option only takes effect if the \-i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn't accessed within the last .I sec seconds; .B tcpsvd does not discard or remove a file if the user's write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled. .TP .B \-l \fIname local hostname. Do not look up the local hostname in DNS, but use .I name as hostname. This option must be set if .B tcpsvd listens on port 53 to avoid loops. .TP .B \-u \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running .IR prog . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. .TP .B \-c \fIn concurrency. Handle up to .I n connections simultaneously. Default is 30. If there are .I n connections active, .B tcpsvd defers acceptance of a new connection until an active connection is closed. .TP .B \-C \fIn\fR[:\fImsg\fR] per host concurrency. Allow only up to .I n connections from the same IP address simultaneously. If there are .I n active connections from one IP address, new incoming connections from this IP address are closed immediately. If .I n is followed by .RI : msg\fR, the message .I msg is written to the client if possible, before closing the connection. By default .I msg is empty. See .BR ipsvd-instruct (5) for supported escape sequences in .IR msg . For each accepted connection, the current per host concurrency is available through the environment variable .IR TCPCONCURRENCY . .I n and .I msg can be overwritten by .BR ipsvd (7) instructions, see .BR ipsvd-instruct (5). By default .B tcpsvd doesn't keep track of connections. .TP .B \-h Look up the client's hostname in DNS. .TP .B \-p paranoid. After looking up the client's hostname in DNS, look up the IP addresses in DNS for that hostname, and forget about the hostname if none of the addresses match the client's IP address. You should set this option if you use hostname based instructions. The \-p option implies the \-h option. .TP .B \-b \fIn backlog. Allow a backlog of approximately .I n TCP SYNs. On some systems .I n is silently limited. Default is 20. .TP .B \-E no special environment. Do not set up TCP-related environment variables. .TP .B \-v verbose. Print verbose messsages to standard output. .TP .B \-vv more verbose. Print more verbose messages to standard output. .SH SEE ALSO ipsvd(7), sslsvd(8), udpsvd(8), ipsvd-instruct(5), ipsvd-cdb(8), sslio(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/man/udpsvd.80000644000000000000000000001102611025276022014267 0ustar rootroot.TH udpsvd 8 .SH NAME udpsvd \- UDP/IP service daemon .SH SYNOPSIS .B udpsvd [\-hpvv] [\-u .I user\fR] [\-l .I name\fR] [\-i .IR dir |\-x .IR cdb ] [\-t .IR sec ] .I host .I port .I prog .SH DESCRIPTION .B udpsvd creates an UDP/IP socket, binds it to the address .IR host :\fIport\fR, and listens on the socket for incoming datagrams. .P If a datagram is available on the socket, .B udpsvd conditionally starts a program, with standard input reading from the socket, and standard output redirected to standard error, to handle this, and possibly more datagrams. .B udpsvd does not start the program if another program that it has started before still is running. If the program exits, .B udpsvd again listens to the socket until a new datagram is available. If there are still datagrams available on the socket, the program is restarted immediately. .P .B udpsvd optionally checks for special intructions depending on the IP address or hostname of the client sending the datagram which not yet was handled by a running program, see .BR ipsvd-instruct (5) for details. .P .SS ATTENTION: UDP is a connectionless protocol. Most programs that handle user datagrams, such as .BR talkd (8), keep running after receiving a datagram, and process subsequent datagrams sent to the socket until a timeout is reached. .B udpsvd only checks special instructions for a datagram that causes a startup of the program; not if a program handling datagrams already is running. It doesn't make much sense to restrict access through special instructions when using such a program. .P On the other hand, it makes perfectly sense with programs like .BR tftpd (8), that fork to establish a separate connection to the client when receiving the datagram. In general it's adequate to set up special instructions for programs that support being run by tcpwrapper. .SH OPTIONS .TP .I host .I host either is a hostname, or a dotted-decimal IP address, or 0. If .I host is 0, .B udpsvd accepts datagrams to any local IP address. .TP .I port .B udpsvd accepts datagrams to .IR host :\fIport\fR. .I port may be a name from /etc/services or a number. .TP .I prog .I prog consists of one or more arguments. .B udpsvd normally runs .I prog to handle a datagram, and possibly more, that is sent to the socket, if there is no program that was started before by .B udpsvd still running and handling datagrams. .TP .B \-i \fIdir read instructions for handling new connections from the instructions directory .IR dir . See .BR ipsvd-instruct (5) for details. .TP .B \-x \fIcdb read instructions for handling new connections from the constant database .IR cdb . The constant database normally is created from an instructions directory by running .BR ipsvd-cdb (8). .TP .B \-t \fIsec timeout. This option only takes effect if the \-i option is given. While checking the instructions directory, check the time of last access of the file that matches the clients address or hostname if any, discard and remove the file if it wasn't accessed within the last .I sec seconds; .B udpsvd does not discard or remove a file if the user's write permission is not set, for those files the timeout is disabled. Default is 0, which means that the timeout is disabled. .TP .B \-l \fIname local hostname. Do not look up the local hostname in DNS, but use .I name as hostname. By default .B udpsvd looks up the local hostname once at startup. .TP .B \-u \fI[:]user[:group] drop permissions. Set uid and gid to the .IR user 's uid and gid, as found in .IR /etc/passwd , before running .IR prog . If .I user is followed by a colon and a .IR group , set the gid to .IR group 's gid, as found in .IR /etc/group , instead of .IR user 's gid. If .I group consists of a colon-separated list of group names, set the group ids of all listed groups. If .I user is prefixed with a colon, the .I user and all .I group arguments are interpreted as uid and gids respectively, and not looked up in the password or group file. All supplementary groups are removed. .TP .B \-h Look up the client's hostname in DNS. .TP .B \-p paranoid. After looking up the client's hostname in DNS, look up the IP addresses in DNS for that hostname, and forget the hostname if none of the addresses match the client's IP address. You should set this option if you use hostname based instructions. The \-p option implies the \-h option. .TP .B \-v verbose. Print verbose messages to standard output. .TP .B \-vv more verbose. Print more verbose messages to standard output. .SH SEE ALSO ipsvd(7), tcpsvd(8), sslsvd(8), ipsvd-instruct(5), ipsvd-cdb(8) .P http://smarden.org/ipsvd/ .SH AUTHOR Gerrit Pape net/ipsvd-1.0.0/src/0000755000000000000000000000000011025276022012705 5ustar rootrootnet/ipsvd-1.0.0/src/Makefile0000644000000000000000000004544511025276022014361 0ustar rootrootIT=tcpsvd udpsvd ipsvd-cdb default: command.ssl $(IT) $(MAKE) `cat command.ssl` check: check-tcpsvd check-udpsvd check-ipsvd-cdb ./check-local $(IT) `grep -v nossl matrixConfig.h && \ mv -f matrixConfig.h matrixssl/src/matrixConfig.h echo '#ifndef CLK_TCK' >>matrixssl/src/os/osLayer.h echo '#define CLK_TCK CLOCKS_PER_SEC' >>matrixssl/src/os/osLayer.h echo '#endif' >>matrixssl/src/os/osLayer.h touch matrixssl check-tcpsvd: load check-tcpsvd.o unix.a byte.a socket.lib ./load check-tcpsvd unix.a byte.a `cat socket.lib` check-udpsvd: load check-udpsvd.o unix.a byte.a socket.lib ./load check-udpsvd unix.a byte.a `cat socket.lib` check-ipsvd-cdb: load check-ipsvd-cdb.o uint32_unpack.o unix.a byte.a ./load check-ipsvd-cdb uint32_unpack.o unix.a byte.a tcpsvd.o: compile sysdeps tcpsvd.c ipsvd_log.h ./compile tcpsvd.c sslsvd.o: compile sysdeps tcpsvd.c ssl_io.c ipsvd_log.h matrixssl ./compile -I./matrixssl sslsvd.c ssl_io.o: compile sysdeps ssl_io.c matrixssl ./compile -I./matrixssl ssl_io.c udpsvd.o: compile sysdeps udpsvd.c ipsvd_log.h ./compile udpsvd.c ipsvd-cdb.o: compile sysdeps ipsvd-cdb.c ./compile ipsvd-cdb.c sslio.o: compile sysdeps sslio.c matrixssl ./compile -I./matrixssl sslio.c check-tcpsvd.o: compile check-tcpsvd.c ./compile check-tcpsvd.c check-udpsvd.o: compile check-udpsvd.c ./compile check-udpsvd.c check-ipsvd-cdb.o: compile uint32.h check-ipsvd-cdb.c ./compile check-ipsvd-cdb.c ipsvd_log.o: compile ipsvd_log.c ./compile ipsvd_log.c ipsvd_fmt.o: compile ipsvd_fmt.c ./compile ipsvd_fmt.c ipsvd_check.o: compile ipsvd_check.c uint64.h ./compile ipsvd_check.c ipsvd_hostname.o: compile ipsvd_hostname.c uint64.h ./compile ipsvd_hostname.c ipsvd_phcc.o: compile ipsvd_phcc.c ./compile ipsvd_phcc.c ipsvd_scan.o: compile ipsvd_scan.c ./compile ipsvd_scan.c uidgid.o: compile uidgid.c uidgid.h ./compile uidgid.c sslerror_str.o: compile sslerror_str.c sslerror_str.h matrixssl ./compile -I./matrixssl sslerror_str.c socket.lib: compile load trysocketlib.c ./compile trysocketlib.c (./load trysocketlib >/dev/null 2>&1 || \ (./load trysocketlib -lxnet >/dev/null 2>&1 && echo '-lxnet') || \ (./load trysocketlib -lsocket -lnsl >/dev/null 2>&1 && \ echo '-lsocket -lnsl') ) >socket.lib rm -f trysocketlib.o trysocketlib command.ssl: command.sslcheck command.sslcheck: ( (test ! -r matrixssl.tar.gz && echo nossl) || \ echo sslio sslsvd) >command.sslcheck mv -f command.sslcheck command.ssl nossl: : no ssl library, not making sslio clean: rm -f `cat TARGETS` *~ rm -rf matrixssl matrixssl-* alloc.o: alloc.c alloc.h compile error.h ./compile alloc.c alloc_re.o: alloc.h alloc_re.c byte.h compile ./compile alloc_re.c buffer.o: buffer.c buffer.h compile ./compile buffer.c buffer_0.o: buffer.h buffer_0.c compile ./compile buffer_0.c buffer_1.o: buffer.h buffer_1.c compile ./compile buffer_1.c buffer_2.o: buffer.h buffer_2.c compile ./compile buffer_2.c buffer_get.o: buffer.h buffer_get.c byte.h compile error.h ./compile buffer_get.c buffer_put.o: buffer.h buffer_put.c byte.h compile error.h str.h ./compile buffer_put.c buffer_read.o: buffer.h buffer_read.c compile ./compile buffer_read.c buffer_write.o: buffer.h buffer_write.c compile ./compile buffer_write.c byte.a: byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_rchr.o byte_zero.o \ case_diffb.o fmt_uint.o fmt_uint0.o fmt_ulong.o ip4_scan.o makelib \ scan_ulong.o str_chr.o str_diff.o str_len.o str_start.o \ uint16_pack.o uint16_unpack.o ./makelib byte.a byte_chr.o byte_copy.o byte_cr.o byte_diff.o \ byte_rchr.o byte_zero.o case_diffb.o fmt_uint.o fmt_uint0.o \ fmt_ulong.o ip4_scan.o scan_ulong.o str_chr.o str_diff.o str_len.o \ str_start.o uint16_pack.o uint16_unpack.o byte_chr.o: byte.h byte_chr.c compile ./compile byte_chr.c byte_copy.o: byte.h byte_copy.c compile ./compile byte_copy.c byte_cr.o: byte.h byte_cr.c compile ./compile byte_cr.c byte_diff.o: byte.h byte_diff.c compile ./compile byte_diff.c byte_rchr.o: byte.h byte_rchr.c compile ./compile byte_rchr.c byte_zero.o: byte.h byte_zero.c compile ./compile byte_zero.c case_diffb.o: case.h case_diffb.c compile ./compile case_diffb.c chkshsgr: chkshsgr.o load ./load chkshsgr chkshsgr.o: chkshsgr.c compile ./compile chkshsgr.c choose: choose.sh warn-auto.sh rm -f choose cat warn-auto.sh choose.sh >choose chmod 555 choose coe.o: coe.c coe.h compile ./compile coe.c compile: conf-cc print-cc.sh systype warn-auto.sh rm -f compile sh print-cc.sh >compile chmod 555 compile direntry.h: choose compile direntry.h1 direntry.h2 trydrent.c ./choose c trydrent direntry.h1 direntry.h2 >direntry.h dns.a: makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o \ dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o \ dns_rcrw.o dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o \ dns_mx.o dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o \ dns_rcrw.o dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o dns_dfd.o: compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_dfd.c dns_domain.o: compile dns_domain.c error.h alloc.h case.h byte.h dns.h \ stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_domain.c dns_dtda.o: compile dns_dtda.c stralloc.h gen_alloc.h dns.h stralloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile dns_dtda.c dns_ip.o: compile dns_ip.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_ip.c dns_ipq.o: compile dns_ipq.c stralloc.h gen_alloc.h case.h byte.h str.h \ dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_ipq.c dns_mx.o: compile dns_mx.c stralloc.h gen_alloc.h byte.h uint16.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_mx.c dns_name.o: compile dns_name.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_name.c dns_nd.o: compile dns_nd.c byte.h fmt.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile dns_nd.c dns_packet.o: compile dns_packet.c error.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile dns_packet.c dns_random.o: compile dns_random.c dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h taia.h uint32.h ./compile dns_random.c dns_rcip.o: compile dns_rcip.c taia.h tai.h uint64.h openreadclose.h \ stralloc.h gen_alloc.h byte.h ip4.h env.h dns.h stralloc.h \ iopause.h taia.h taia.h ./compile dns_rcip.c dns_rcrw.o: compile dns_rcrw.c taia.h tai.h uint64.h env.h byte.h str.h \ openreadclose.h stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \ taia.h taia.h ./compile dns_rcrw.c dns_resolve.o: compile dns_resolve.c iopause.h taia.h tai.h uint64.h taia.h \ byte.h dns.h stralloc.h gen_alloc.h iopause.h taia.h ./compile dns_resolve.c dns_sortip.o: compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile dns_sortip.c dns_transmit.o: compile dns_transmit.c socket.h uint16.h alloc.h error.h \ byte.h uint16.h dns.h stralloc.h gen_alloc.h iopause.h taia.h \ tai.h uint64.h taia.h ./compile dns_transmit.c dns_txt.o: compile dns_txt.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_txt.c env.o: compile env.c env.h str.h ./compile env.c error.o: compile error.c error.h ./compile error.c error_str.o: compile error.h error_str.c ./compile error_str.c fd_copy.o: compile fd.h fd_copy.c ./compile fd_copy.c fd_move.o: compile fd.h fd_move.c ./compile fd_move.c fifo.o: compile fifo.c fifo.h hasmkffo.h ./compile fifo.c fmt_uint.o: compile fmt.h fmt_uint.c ./compile fmt_uint.c fmt_uint0.o: compile fmt.h fmt_uint0.c ./compile fmt_uint0.c fmt_ulong.o: compile fmt.h fmt_ulong.c ./compile fmt_ulong.c hasflock.h: choose compile hasflock.h1 hasflock.h2 load tryflock.c ./choose cl tryflock hasflock.h1 hasflock.h2 >hasflock.h hasmkffo.h: choose compile hasmkffo.h1 hasmkffo.h2 load trymkffo.c ./choose cl trymkffo hasmkffo.h1 hasmkffo.h2 >hasmkffo.h hassgact.h: choose compile hassgact.h1 hassgact.h2 load trysgact.c ./choose cl trysgact hassgact.h1 hassgact.h2 >hassgact.h hassgprm.h: choose compile hassgprm.h1 hassgprm.h2 load trysgprm.c ./choose cl trysgprm hassgprm.h1 hassgprm.h2 >hassgprm.h hasshsgr.h: chkshsgr choose compile hasshsgr.h1 hasshsgr.h2 load tryshsgr.c \ warn-shsgr ./chkshsgr || (cat warn-shsgr; exit 1) ./choose clr tryshsgr hasshsgr.h1 hasshsgr.h2 >hasshsgr.h haswaitp.h: choose compile haswaitp.h1 haswaitp.h2 load trywaitp.c ./choose cl trywaitp haswaitp.h1 haswaitp.h2 >haswaitp.h ip4_scan.o: compile ip4_scan.c scan.h ip4.h ./compile ip4_scan.c iopause.h: choose compile iopause.h1 iopause.h2 load trypoll.c ./choose clr trypoll iopause.h1 iopause.h2 >iopause.h iopause.o: compile iopause.c iopause.h select.h tai.h taia.h uint64.h ./compile iopause.c load: conf-ld print-ld.sh systype warn-auto.sh rm -f load sh print-ld.sh >load chmod 555 load lock_ex.o: compile hasflock.h lock.h lock_ex.c ./compile lock_ex.c lock_exnb.o: compile hasflock.h lock.h lock_exnb.c ./compile lock_exnb.c makelib: print-ar.sh systype warn-auto.sh rm -f makelib sh print-ar.sh >makelib chmod 555 makelib ndelay_off.o: compile ndelay.h ndelay_off.c ./compile ndelay_off.c ndelay_on.o: compile ndelay.h ndelay_on.c ./compile ndelay_on.c open_append.o: compile open.h open_append.c ./compile open_append.c open_read.o: compile open.h open_read.c ./compile open_read.c open_trunc.o: compile open.h open_trunc.c ./compile open_trunc.c open_write.o: compile open.h open_write.c ./compile open_write.c openreadclose.o: compile error.h gen_alloc.h open.h openreadclose.c \ openreadclose.h readclose.h stralloc.h ./compile openreadclose.c pathexec_env.o: alloc.h byte.h compile env.h gen_alloc.h pathexec.h \ pathexec_env.c str.h stralloc.h ./compile pathexec_env.c pathexec_run.o: compile env.h error.h gen_alloc.h pathexec.h pathexec_run.c \ str.h stralloc.h ./compile pathexec_run.c prot.o: compile hasshsgr.h prot.c prot.h ./compile prot.c readclose.o: compile error.h gen_alloc.h readclose.c readclose.h stralloc.h ./compile readclose.c scan_ulong.o: compile scan.h scan_ulong.c ./compile scan_ulong.c seek_set.o: compile seek.h seek_set.c ./compile seek_set.c select.h: choose compile select.h1 select.h2 trysysel.c ./choose c trysysel select.h1 select.h2 >select.h sgetopt.o: buffer.h compile sgetopt.c sgetopt.h subgetopt.h ./compile sgetopt.c sig.o: compile sig.c sig.h ./compile sig.c sig_block.o: compile hassgprm.h sig.h sig_block.c ./compile sig_block.c sig_catch.o: compile hassgact.h sig.h sig_catch.c ./compile sig_catch.c sig_pause.o: compile hassgprm.h sig.h sig_pause.c ./compile sig_pause.c socket_bind.o: compile socket_bind.c byte.h socket.h uint16.h ./compile socket_bind.c socket_conn.o: compile socket_conn.c byte.h socket.h uint16.h ./compile socket_conn.c socket_tcp.o: compile socket_tcp.c ndelay.h socket.h uint16.h ./compile socket_tcp.c socket_udp.o: compile socket_udp.c ndelay.h socket.h uint16.h ./compile socket_udp.c str_chr.o: compile str.h str_chr.c ./compile str_chr.c str_diff.o: compile str.h str_diff.c ./compile str_diff.c str_len.o: compile str.h str_len.c ./compile str_len.c str_start.o: compile str.h str_start.c ./compile str_start.c stralloc_cat.o: byte.h compile gen_alloc.h stralloc.h stralloc_cat.c ./compile stralloc_cat.c stralloc_catb.o: byte.h compile gen_alloc.h stralloc.h stralloc_catb.c ./compile stralloc_catb.c stralloc_cats.o: byte.h compile gen_alloc.h str.h stralloc.h stralloc_cats.c ./compile stralloc_cats.c stralloc_copy.o: compile stralloc_copy.c byte.h stralloc.h gen_alloc.h ./compile stralloc_copy.c stralloc_eady.o: alloc.h compile gen_alloc.h gen_allocdefs.h stralloc.h \ stralloc_eady.c ./compile stralloc_eady.c stralloc_opyb.o: byte.h compile gen_alloc.h stralloc.h stralloc_opyb.c ./compile stralloc_opyb.c stralloc_opys.o: byte.h compile gen_alloc.h str.h stralloc.h stralloc_opys.c ./compile stralloc_opys.c stralloc_pend.o: alloc.h compile gen_alloc.h gen_allocdefs.h stralloc.h \ stralloc_pend.c ./compile stralloc_pend.c strerr_die.o: buffer.h compile strerr.h strerr_die.c ./compile strerr_die.c strerr_sys.o: compile error.h strerr.h strerr_sys.c ./compile strerr_sys.c subgetopt.o: compile subgetopt.c subgetopt.h ./compile subgetopt.c sysdeps: compile direntry.h hasflock.h hasmkffo.h hassgact.h hassgprm.h \ hasshsgr.h haswaitp.h iopause.h load select.h systype uint64.h \ uint32.h socket.lib rm -f sysdeps cat systype compile load socket.lib >>sysdeps grep sysdep direntry.h >>sysdeps grep sysdep haswaitp.h >>sysdeps grep sysdep hassgact.h >>sysdeps grep sysdep hassgprm.h >>sysdeps grep sysdep select.h >>sysdeps grep sysdep uint64.h >>sysdeps grep sysdep iopause.h >>sysdeps grep sysdep hasmkffo.h >>sysdeps grep sysdep hasflock.h >>sysdeps grep sysdep hasshsgr.h >>sysdeps cat sysdeps systype: find-systype.sh trycpp.c x86cpuid.c sh find-systype.sh >systype tai_now.o: compile tai.h tai_now.c uint64.h ./compile tai_now.c tai_pack.o: compile tai.h tai_pack.c uint64.h ./compile tai_pack.c tai_sub.o: compile tai.h tai_sub.c uint64.h ./compile tai_sub.c tai_unpack.o: compile tai.h tai_unpack.c uint64.h ./compile tai_unpack.c taia_add.o: compile tai.h taia.h taia_add.c uint64.h ./compile taia_add.c taia_approx.o: compile tai.h taia.h taia_approx.c uint64.h ./compile taia_approx.c taia_frac.o: compile tai.h taia.h taia_frac.c uint64.h ./compile taia_frac.c taia_less.o: compile tai.h taia.h taia_less.c uint64.h ./compile taia_less.c taia_now.o: compile tai.h taia.h taia_now.c uint64.h ./compile taia_now.c taia_pack.o: compile tai.h taia.h taia_pack.c uint64.h ./compile taia_pack.c taia_sub.o: compile tai.h taia.h taia_sub.c uint64.h ./compile taia_sub.c taia_uint.o: compile tai.h taia.h taia_uint.c uint64.h ./compile taia_uint.c time.a: iopause.o makelib tai_now.o tai_pack.o tai_sub.o tai_unpack.o \ taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o \ taia_pack.o taia_sub.o taia_uint.o ./makelib time.a iopause.o tai_now.o tai_pack.o tai_sub.o \ tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o \ taia_now.o taia_pack.o taia_sub.o taia_uint.o uint16_pack.o: compile uint16_pack.c uint16.h ./compile uint16_pack.c uint16_unpack.o: compile uint16_unpack.c uint16.h ./compile uint16_unpack.c uint32.h: tryulong32.c compile load uint32.h1 uint32.h2 ( (./compile tryulong32.c && ./load tryulong32 && \ ./tryulong32) >/dev/null 2>&1 \ && cat uint32.h2 || cat uint32.h1) >uint32.h rm -f tryulong32.o tryulong32 uint32_pack.o: compile uint32.h uint32_pack.c ./compile uint32_pack.c uint32_unpack.o: compile uint32.h uint32_unpack.c ./compile uint32_unpack.c uint64.h: choose compile load tryulong64.c uint64.h1 uint64.h2 ./choose clr tryulong64 uint64.h1 uint64.h2 >uint64.h unix.a: alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o buffer_2.o \ buffer_get.o buffer_put.o buffer_read.o buffer_write.o coe.o \ env.o error.o error_str.o fd_copy.o fd_move.o fifo.o lock_ex.o \ lock_exnb.o makelib ndelay_off.o ndelay_on.o open_append.o \ open_read.o open_trunc.o open_write.o openreadclose.o \ pathexec_env.o pathexec_run.o prot.o readclose.o seek_set.o \ sgetopt.o sig.o sig_block.o sig_catch.o sig_pause.o \ socket_bind.o socket_conn.o socket_tcp.o socket_udp.o \ stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_copy.o \ stralloc_eady.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o \ strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o wait_pid.o ./makelib unix.a alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o \ buffer_2.o buffer_get.o buffer_put.o buffer_read.o buffer_write.o \ coe.o env.o error.o error_str.o fd_copy.o fd_move.o fifo.o \ lock_ex.o lock_exnb.o ndelay_off.o ndelay_on.o open_append.o \ open_read.o open_trunc.o open_write.o openreadclose.o \ pathexec_env.o pathexec_run.o prot.o readclose.o seek_set.o \ sgetopt.o sig.o sig_block.o sig_catch.o sig_pause.o \ socket_bind.o socket_conn.o socket_tcp.o socket_udp.o \ stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_copy.o \ stralloc_eady.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o \ strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o wait_pid.o wait_nohang.o: compile haswaitp.h wait_nohang.c ./compile wait_nohang.c wait_pid.o: compile error.h haswaitp.h wait_pid.c ./compile wait_pid.c # from cdb-0.75; Public domain cdb.a: makelib cdb.o cdb_hash.o cdb_make.o uint32_pack.o uint32_unpack.o ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o uint32_pack.o \ uint32_unpack.o cdb.o: compile cdb.c error.h seek.h byte.h cdb.h uint32.h ./compile cdb.c cdb_hash.o: compile cdb_hash.c cdb.h uint32.h ./compile cdb_hash.c cdb_make.o: compile cdb_make.c seek.h error.h alloc.h cdb.h uint32.h \ cdb_make.h buffer.h uint32.h ./compile cdb_make.c net/ipsvd-1.0.0/src/Makefile.matrixssl0000644000000000000000000000031611025276022016372 0ustar rootrootinclude Makefile CC=../../compile LD=../../load LDFLAGS= DFLAGS= matrixssl.a: $(OBJECTS) rm -f matrixssl.a ../../makelib matrixssl.a $(OBJECTS) # ar cr libmatrixssl.a $(OBJECTS) # ranlib libmatrixssl.a net/ipsvd-1.0.0/src/TARGETS0000644000000000000000000000353311025276022013745 0ustar rootroottcpsvd tcpsvd.o udpsvd udpsvd.o ipsvd-cdb ipsvd-cdb.o sslio sslio.o sslsvd sslsvd.o check-tcpsvd check-tcpsvd.o check-udpsvd check-udpsvd.o check-ipsvd-cdb check-ipsvd-cdb.o ipsvd_check.o ipsvd_fmt.o ipsvd_log.o ipsvd_hostname.o ipsvd_phcc.o ipsvd_scan.o ssl_io.o sslerror_str.o uidgid.o socket.lib trysocketlib trysocketlib.o command.ssl matrixSsl.h matrixssl.a cdb_hash.o cdb_make.o cdb.a cdb.o uint32_pack.o uint32_unpack.o sysdeps check alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o buffer_2.o buffer_get.o buffer_put.o buffer_read.o buffer_write.o byte.a byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_rchr.o chkshsgr chkshsgr.o choose coe.o compile direntry.h env.o error.o error_str.o fd_copy.o fd_move.o fifo.o fmt_uint.o fmt_uint0.o fmt_ulong.o hasflock.h hasmkffo.h hassgact.h hassgprm.h hasshsgr.h haswaitp.h iopause.h iopause.o load lock_ex.o lock_exnb.o makelib ndelay_off.o ndelay_on.o open_append.o open_read.o open_trunc.o open_write.o openreadclose.o pathexec_env.o pathexec_run.o prot.o readclose.o scan_ulong.o seek_set.o select.h sgetopt.o sig.o sig_block.o sig_catch.o sig_pause.o str_chr.o str_diff.o str_len.o str_start.o stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o strerr_die.o strerr_sys.o subgetopt.o systype tai_now.o tai_pack.o tai_sub.o tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o taia_pack.o taia_sub.o taia_uint.o time.a uint32.h uint64.h unix.a wait_nohang.o wait_pid.o byte_zero.o case_diffb.o dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o ip4_scan.o socket_bind.o socket_conn.o socket_tcp.o socket_udp.o stralloc_copy.o uint16_pack.o uint16_unpack.o dns.a ipsvd-cdb.local tcpsvd.local udpsvd.local sslio.local net/ipsvd-1.0.0/src/alloc.c0000644000000000000000000000150011025276022014137 0ustar rootroot/* Public domain. */ #include #include "alloc.h" #include "error.h" #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ #define SPACE 2048 /* must be multiple of ALIGNMENT */ typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; static aligned realspace[SPACE / ALIGNMENT]; #define space ((char *) realspace) static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ /*@null@*//*@out@*/char *alloc(n) unsigned int n; { char *x; n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ if (n <= avail) { avail -= n; return space + avail; } x = malloc(n); if (!x) errno = error_nomem; return x; } void alloc_free(x) char *x; { if (x >= space) if (x < space + SPACE) return; /* XXX: assuming that pointers are flat */ free(x); } net/ipsvd-1.0.0/src/alloc.h0000644000000000000000000000023111025276022014144 0ustar rootroot/* Public domain. */ #ifndef ALLOC_H #define ALLOC_H extern /*@null@*//*@out@*/char *alloc(); extern void alloc_free(); extern int alloc_re(); #endif net/ipsvd-1.0.0/src/alloc_re.c0000644000000000000000000000035311025276022014632 0ustar rootroot/* Public domain. */ #include "alloc.h" #include "byte.h" int alloc_re(x,m,n) char **x; unsigned int m; unsigned int n; { char *y; y = alloc(n); if (!y) return 0; byte_copy(y,m,*x); alloc_free(*x); *x = y; return 1; } net/ipsvd-1.0.0/src/buffer.c0000644000000000000000000000027511025276022014326 0ustar rootroot/* Public domain. */ #include "buffer.h" void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len) { s->x = buf; s->fd = fd; s->op = op; s->p = 0; s->n = len; } net/ipsvd-1.0.0/src/buffer.h0000644000000000000000000000315011025276022014326 0ustar rootroot/* Public domain. */ #ifndef BUFFER_H #define BUFFER_H typedef struct buffer { char *x; unsigned int p; unsigned int n; int fd; int (*op)(); } buffer; #define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } #define BUFFER_INSIZE 8192 #define BUFFER_OUTSIZE 8192 extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int); extern int buffer_flush(buffer *); extern int buffer_put(buffer *,const char *,unsigned int); extern int buffer_putalign(buffer *,const char *,unsigned int); extern int buffer_putflush(buffer *,const char *,unsigned int); extern int buffer_puts(buffer *,const char *); extern int buffer_putsalign(buffer *,const char *); extern int buffer_putsflush(buffer *,const char *); #define buffer_PUTC(s,c) \ ( ((s)->n != (s)->p) \ ? ( (s)->x[(s)->p++] = (c), 0 ) \ : buffer_put((s),&(c),1) \ ) extern int buffer_get(buffer *,char *,unsigned int); extern int buffer_bget(buffer *,char *,unsigned int); extern int buffer_feed(buffer *); extern char *buffer_peek(buffer *); extern void buffer_seek(buffer *,unsigned int); #define buffer_PEEK(s) ( (s)->x + (s)->n ) #define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) #define buffer_GETC(s,c) \ ( ((s)->p > 0) \ ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \ : buffer_get((s),(c),1) \ ) extern int buffer_copy(buffer *,buffer *); extern int buffer_unixread(int,char *,unsigned int); extern int buffer_unixwrite(int,const char *,unsigned int); extern buffer *buffer_0; extern buffer *buffer_0small; extern buffer *buffer_1; extern buffer *buffer_1small; extern buffer *buffer_2; #endif net/ipsvd-1.0.0/src/buffer_0.c0000644000000000000000000000052111025276022014537 0ustar rootroot/* Public domain. */ #include "buffer.h" int buffer_0_read(fd,buf,len) int fd; char *buf; int len; { if (buffer_flush(buffer_1) == -1) return -1; return buffer_unixread(fd,buf,len); } char buffer_0_space[BUFFER_INSIZE]; static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space); buffer *buffer_0 = ⁢ net/ipsvd-1.0.0/src/buffer_1.c0000644000000000000000000000030111025276022014534 0ustar rootroot/* Public domain. */ #include "buffer.h" char buffer_1_space[BUFFER_OUTSIZE]; static buffer it = BUFFER_INIT(buffer_unixwrite,1,buffer_1_space,sizeof buffer_1_space); buffer *buffer_1 = ⁢ net/ipsvd-1.0.0/src/buffer_2.c0000644000000000000000000000026611025276022014547 0ustar rootroot/* Public domain. */ #include "buffer.h" char buffer_2_space[256]; static buffer it = BUFFER_INIT(buffer_unixwrite,2,buffer_2_space,sizeof buffer_2_space); buffer *buffer_2 = ⁢ net/ipsvd-1.0.0/src/buffer_get.c0000644000000000000000000000236511025276022015167 0ustar rootroot/* Public domain. */ #include "buffer.h" #include "byte.h" #include "error.h" static int oneread(int (*op)(),int fd,char *buf,unsigned int len) { int r; for (;;) { r = op(fd,buf,len); if (r == -1) if (errno == error_intr) continue; return r; } } static int getthis(buffer *s,char *buf,unsigned int len) { if (len > s->p) len = s->p; s->p -= len; byte_copy(buf,len,s->x + s->n); s->n += len; return len; } int buffer_feed(buffer *s) { int r; if (s->p) return s->p; r = oneread(s->op,s->fd,s->x,s->n); if (r <= 0) return r; s->p = r; s->n -= r; if (s->n > 0) byte_copyr(s->x + s->n,r,s->x); return r; } int buffer_bget(buffer *s,char *buf,unsigned int len) { int r; if (s->p > 0) return getthis(s,buf,len); if (s->n <= len) return oneread(s->op,s->fd,buf,s->n); r = buffer_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } int buffer_get(buffer *s,char *buf,unsigned int len) { int r; if (s->p > 0) return getthis(s,buf,len); if (s->n <= len) return oneread(s->op,s->fd,buf,len); r = buffer_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } char *buffer_peek(buffer *s) { return s->x + s->n; } void buffer_seek(buffer *s,unsigned int len) { s->n += len; s->p -= len; } net/ipsvd-1.0.0/src/buffer_put.c0000644000000000000000000000341211025276022015212 0ustar rootroot/* Public domain. */ #include "buffer.h" #include "str.h" #include "byte.h" #include "error.h" static int allwrite(int (*op)(),int fd,const char *buf,unsigned int len) { int w; while (len) { w = op(fd,buf,len); if (w == -1) { if (errno == error_intr) continue; return -1; /* note that some data may have been written */ } if (w == 0) ; /* luser's fault */ buf += w; len -= w; } return 0; } int buffer_flush(buffer *s) { int p; p = s->p; if (!p) return 0; s->p = 0; return allwrite(s->op,s->fd,s->x,p); } int buffer_putalign(buffer *s,const char *buf,unsigned int len) { unsigned int n; while (len > (n = s->n - s->p)) { byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; if (buffer_flush(s) == -1) return -1; } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int buffer_put(buffer *s,const char *buf,unsigned int len) { unsigned int n; n = s->n; if (len > n - s->p) { if (buffer_flush(s) == -1) return -1; /* now s->p == 0 */ if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE; while (len > s->n) { if (n > len) n = len; if (allwrite(s->op,s->fd,buf,n) == -1) return -1; buf += n; len -= n; } } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int buffer_putflush(buffer *s,const char *buf,unsigned int len) { if (buffer_flush(s) == -1) return -1; return allwrite(s->op,s->fd,buf,len); } int buffer_putsalign(buffer *s,const char *buf) { return buffer_putalign(s,buf,str_len(buf)); } int buffer_puts(buffer *s,const char *buf) { return buffer_put(s,buf,str_len(buf)); } int buffer_putsflush(buffer *s,const char *buf) { return buffer_putflush(s,buf,str_len(buf)); } net/ipsvd-1.0.0/src/buffer_read.c0000644000000000000000000000022511025276022015314 0ustar rootroot/* Public domain. */ #include #include "buffer.h" int buffer_unixread(int fd,char *buf,unsigned int len) { return read(fd,buf,len); } net/ipsvd-1.0.0/src/buffer_write.c0000644000000000000000000000023511025276022015534 0ustar rootroot/* Public domain. */ #include #include "buffer.h" int buffer_unixwrite(int fd,const char *buf,unsigned int len) { return write(fd,buf,len); } net/ipsvd-1.0.0/src/byte.h0000644000000000000000000000042711025276022014024 0ustar rootroot/* Public domain. */ #ifndef BYTE_H #define BYTE_H extern unsigned int byte_chr(); extern unsigned int byte_rchr(); extern void byte_copy(); extern void byte_copyr(); extern int byte_diff(); extern void byte_zero(); #define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) #endif net/ipsvd-1.0.0/src/byte_chr.c0000644000000000000000000000063011025276022014647 0ustar rootroot/* Public domain. */ #include "byte.h" unsigned int byte_chr(s,n,c) char *s; register unsigned int n; int c; { register char ch; register char *t; ch = c; t = s; for (;;) { if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; } return t - s; } net/ipsvd-1.0.0/src/byte_copy.c0000644000000000000000000000050111025276022015042 0ustar rootroot/* Public domain. */ #include "byte.h" void byte_copy(to,n,from) register char *to; register unsigned int n; register char *from; { for (;;) { if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; } } net/ipsvd-1.0.0/src/byte_cr.c0000644000000000000000000000053211025276022014500 0ustar rootroot/* Public domain. */ #include "byte.h" void byte_copyr(to,n,from) register char *to; register unsigned int n; register char *from; { to += n; from += n; for (;;) { if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; } } net/ipsvd-1.0.0/src/byte_diff.c0000644000000000000000000000073311025276022015007 0ustar rootroot/* Public domain. */ #include "byte.h" int byte_diff(s,n,t) register char *s; register unsigned int n; register char *t; { for (;;) { if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; } return ((int)(unsigned int)(unsigned char) *s) - ((int)(unsigned int)(unsigned char) *t); } net/ipsvd-1.0.0/src/byte_rchr.c0000644000000000000000000000070711025276022015036 0ustar rootroot/* Public domain. */ #include "byte.h" unsigned int byte_rchr(s,n,c) char *s; register unsigned int n; int c; { register char ch; register char *t; register char *u; ch = c; t = s; u = 0; for (;;) { if (!n) break; if (*t == ch) u = t; ++t; --n; if (!n) break; if (*t == ch) u = t; ++t; --n; if (!n) break; if (*t == ch) u = t; ++t; --n; if (!n) break; if (*t == ch) u = t; ++t; --n; } if (!u) u = t; return u - s; } net/ipsvd-1.0.0/src/byte_zero.c0000644000000000000000000000034611025276022015056 0ustar rootroot#include "byte.h" void byte_zero(s,n) char *s; register unsigned int n; { for (;;) { if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; } } net/ipsvd-1.0.0/src/case.h0000644000000000000000000000061311025276022013771 0ustar rootroot#ifndef CASE_H #define CASE_H extern void case_lowers(char *); extern void case_lowerb(char *,unsigned int); extern int case_diffs(const char *,const char *); extern int case_diffb(const char *,unsigned int,const char *); extern int case_starts(const char *,const char *); extern int case_startb(const char *,unsigned int,const char *); #define case_equals(s,t) (!case_diffs((s),(t))) #endif net/ipsvd-1.0.0/src/case_diffb.c0000644000000000000000000000066111025276022015121 0ustar rootroot#include "case.h" int case_diffb(register const char *s,register unsigned int len,register const char *t) { register unsigned char x; register unsigned char y; while (len > 0) { --len; x = *s++ - 'A'; if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; y = *t++ - 'A'; if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; if (x != y) return ((int)(unsigned int) x) - ((int)(unsigned int) y); } return 0; } net/ipsvd-1.0.0/src/cdb.c0000644000000000000000000000514711025276022013610 0ustar rootroot/* Public domain. */ #include #include #include #include "readwrite.h" #include "error.h" #include "seek.h" #include "byte.h" #include "cdb.h" void cdb_free(struct cdb *c) { if (c->map) { munmap(c->map,c->size); c->map = 0; } } void cdb_findstart(struct cdb *c) { c->loop = 0; } void cdb_init(struct cdb *c,int fd) { struct stat st; char *x; cdb_free(c); cdb_findstart(c); c->fd = fd; if (fstat(fd,&st) == 0) if (st.st_size <= 0xffffffff) { x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0); if (x + 1) { c->size = st.st_size; c->map = x; } } } int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos) { if (c->map) { if ((pos > c->size) || (c->size - pos < len)) goto FORMAT; byte_copy(buf,len,c->map + pos); } else { if (seek_set(c->fd,pos) == -1) return -1; while (len > 0) { int r; do r = read(c->fd,buf,len); while ((r == -1) && (errno == error_intr)); if (r == -1) return -1; if (r == 0) goto FORMAT; buf += r; len -= r; } } return 0; FORMAT: errno = error_proto; return -1; } static int match(struct cdb *c,char *key,unsigned int len,uint32 pos) { char buf[32]; int n; while (len > 0) { n = sizeof buf; if (n > len) n = len; if (cdb_read(c,buf,n,pos) == -1) return -1; if (byte_diff(buf,n,key)) return 0; pos += n; key += n; len -= n; } return 1; } int cdb_findnext(struct cdb *c,char *key,unsigned int len) { char buf[8]; uint32 pos; uint32 u; if (!c->loop) { u = cdb_hash(key,len); if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf,&c->hpos); c->khash = u; u >>= 8; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; } while (c->loop < c->hslots) { if (cdb_read(c,buf,8,c->kpos) == -1) return -1; uint32_unpack(buf + 4,&pos); if (!pos) return 0; c->loop += 1; c->kpos += 8; if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; uint32_unpack(buf,&u); if (u == c->khash) { if (cdb_read(c,buf,8,pos) == -1) return -1; uint32_unpack(buf,&u); if (u == len) switch(match(c,key,len,pos + 8)) { case -1: return -1; case 1: uint32_unpack(buf + 4,&c->dlen); c->dpos = pos + 8 + len; return 1; } } } return 0; } int cdb_find(struct cdb *c,char *key,unsigned int len) { cdb_findstart(c); return cdb_findnext(c,key,len); } net/ipsvd-1.0.0/src/cdb.h0000644000000000000000000000210511025276022013604 0ustar rootroot/* Public domain. */ #ifndef CDB_H #define CDB_H #include "uint32.h" #define CDB_HASHSTART 5381 extern uint32 cdb_hashadd(uint32,unsigned char); extern uint32 cdb_hash(char *,unsigned int); struct cdb { char *map; /* 0 if no map is available */ int fd; uint32 size; /* initialized if map is nonzero */ uint32 loop; /* number of hash slots searched under this key */ uint32 khash; /* initialized if loop is nonzero */ uint32 kpos; /* initialized if loop is nonzero */ uint32 hpos; /* initialized if loop is nonzero */ uint32 hslots; /* initialized if loop is nonzero */ uint32 dpos; /* initialized if cdb_findnext() returns 1 */ uint32 dlen; /* initialized if cdb_findnext() returns 1 */ } ; extern void cdb_free(struct cdb *); extern void cdb_init(struct cdb *,int fd); extern int cdb_read(struct cdb *,char *,unsigned int,uint32); extern void cdb_findstart(struct cdb *); extern int cdb_findnext(struct cdb *,char *,unsigned int); extern int cdb_find(struct cdb *,char *,unsigned int); #define cdb_datapos(c) ((c)->dpos) #define cdb_datalen(c) ((c)->dlen) #endif net/ipsvd-1.0.0/src/cdb_hash.c0000644000000000000000000000042711025276022014607 0ustar rootroot/* Public domain. */ #include "cdb.h" uint32 cdb_hashadd(uint32 h,unsigned char c) { h += (h << 5); return h ^ c; } uint32 cdb_hash(char *buf,unsigned int len) { uint32 h; h = CDB_HASHSTART; while (len) { h = cdb_hashadd(h,*buf++); --len; } return h; } net/ipsvd-1.0.0/src/cdb_make.c0000644000000000000000000000721111025276022014577 0ustar rootroot/* Public domain. */ #include "readwrite.h" #include "seek.h" #include "error.h" #include "alloc.h" #include "cdb.h" #include "cdb_make.h" int cdb_make_start(struct cdb_make *c,int fd) { c->head = 0; c->split = 0; c->hash = 0; c->numentries = 0; c->fd = fd; c->pos = sizeof c->final; buffer_init(&c->b,write,fd,c->bspace,sizeof c->bspace); return seek_set(fd,c->pos); } static int posplus(struct cdb_make *c,uint32 len) { uint32 newpos = c->pos + len; if (newpos < len) { errno = error_nomem; return -1; } c->pos = newpos; return 0; } int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h) { struct cdb_hplist *head; head = c->head; if (!head || (head->num >= CDB_HPLIST)) { head = (struct cdb_hplist *) alloc(sizeof(struct cdb_hplist)); if (!head) return -1; head->num = 0; head->next = c->head; c->head = head; } head->hp[head->num].h = h; head->hp[head->num].p = c->pos; ++head->num; ++c->numentries; if (posplus(c,8) == -1) return -1; if (posplus(c,keylen) == -1) return -1; if (posplus(c,datalen) == -1) return -1; return 0; } int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) { char buf[8]; if (keylen > 0xffffffff) { errno = error_nomem; return -1; } if (datalen > 0xffffffff) { errno = error_nomem; return -1; } uint32_pack(buf,keylen); uint32_pack(buf + 4,datalen); if (buffer_putalign(&c->b,buf,8) == -1) return -1; return 0; } int cdb_make_add(struct cdb_make *c,char *key,unsigned int keylen,char *data,unsigned int datalen) { if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1; if (buffer_putalign(&c->b,key,keylen) == -1) return -1; if (buffer_putalign(&c->b,data,datalen) == -1) return -1; return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen)); } int cdb_make_finish(struct cdb_make *c) { char buf[8]; int i; uint32 len; uint32 u; uint32 memsize; uint32 count; uint32 where; struct cdb_hplist *x; struct cdb_hp *hp; for (i = 0;i < 256;++i) c->count[i] = 0; for (x = c->head;x;x = x->next) { i = x->num; while (i--) ++c->count[255 & x->hp[i].h]; } memsize = 1; for (i = 0;i < 256;++i) { u = c->count[i] * 2; if (u > memsize) memsize = u; } memsize += c->numentries; /* no overflow possible up to now */ u = (uint32) 0 - (uint32) 1; u /= sizeof(struct cdb_hp); if (memsize > u) { errno = error_nomem; return -1; } c->split = (struct cdb_hp *) alloc(memsize * sizeof(struct cdb_hp)); if (!c->split) return -1; c->hash = c->split + c->numentries; u = 0; for (i = 0;i < 256;++i) { u += c->count[i]; /* bounded by numentries, so no overflow */ c->start[i] = u; } for (x = c->head;x;x = x->next) { i = x->num; while (i--) c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; } for (i = 0;i < 256;++i) { count = c->count[i]; len = count + count; /* no overflow possible */ uint32_pack(c->final + 8 * i,c->pos); uint32_pack(c->final + 8 * i + 4,len); for (u = 0;u < len;++u) c->hash[u].h = c->hash[u].p = 0; hp = c->split + c->start[i]; for (u = 0;u < count;++u) { where = (hp->h >> 8) % len; while (c->hash[where].p) if (++where == len) where = 0; c->hash[where] = *hp++; } for (u = 0;u < len;++u) { uint32_pack(buf,c->hash[u].h); uint32_pack(buf + 4,c->hash[u].p); if (buffer_putalign(&c->b,buf,8) == -1) return -1; if (posplus(c,8) == -1) return -1; } } if (buffer_flush(&c->b) == -1) return -1; if (seek_begin(c->fd) == -1) return -1; return buffer_putflush(&c->b,c->final,sizeof c->final); } net/ipsvd-1.0.0/src/cdb_make.h0000644000000000000000000000155211025276022014606 0ustar rootroot/* Public domain. */ #ifndef CDB_MAKE_H #define CDB_MAKE_H #include "buffer.h" #include "uint32.h" #define CDB_HPLIST 1000 struct cdb_hp { uint32 h; uint32 p; } ; struct cdb_hplist { struct cdb_hp hp[CDB_HPLIST]; struct cdb_hplist *next; int num; } ; struct cdb_make { char bspace[8192]; char final[2048]; uint32 count[256]; uint32 start[256]; struct cdb_hplist *head; struct cdb_hp *split; /* includes space for hash */ struct cdb_hp *hash; uint32 numentries; buffer b; uint32 pos; int fd; } ; extern int cdb_make_start(struct cdb_make *,int); extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int); extern int cdb_make_addend(struct cdb_make *,unsigned int,unsigned int,uint32); extern int cdb_make_add(struct cdb_make *,char *,unsigned int,char *,unsigned int); extern int cdb_make_finish(struct cdb_make *); #endif net/ipsvd-1.0.0/src/check-diff0000755000000000000000000000024611025276022014620 0ustar rootroot#!/bin/sh test -r "$1".dist || exit 1 test -r "$1".local || exit 1 while read i; do read j 0<&7 || exit 1 test "$i" = "$j" || exit 1 done 7<"$1".dist <"$1".local net/ipsvd-1.0.0/src/check-dist0000755000000000000000000000032711025276022014653 0ustar rootroot#!/bin/sh PATH=`pwd`:$PATH for i in `cat ../package/commands` `grep -v nossl &1 |cat -v >$i.dist done net/ipsvd-1.0.0/src/check-ipsvd-cdb.c0000644000000000000000000000171011025276022015776 0ustar rootroot#include "buffer.h" #include "strerr.h" #include "uint32.h" int i; int pos =0; uint32 eod; uint32 klen; uint32 dlen; char buf[4]; char e[256]; void get(char *buf, unsigned int l) { while (l > 0) { i =buffer_get(buffer_0, buf, l); if (i == -1) strerr_die1sys(111, "fatal: unable to read cdb: "); if (i == 0) strerr_die1x(111, "fatal: unable to read cdb: truncated"); buf +=i; l -=i; } } int main() { get(buf, 4); pos +=4; uint32_unpack(buf, &eod); while (pos < 2048) { get(buf, 4); pos +=4; } while (pos < eod) { get(buf, 4); pos +=4; uint32_unpack(buf, &klen); get(buf, 4); pos +=4; uint32_unpack(buf, &dlen); if ((klen > 256) || (dlen > 256)) strerr_die1x(111, "fatal: unable to read cdb: entry too long"); get(e, klen); buffer_put(buffer_1, e, klen); buffer_put(buffer_1, ":", 1); get(e, dlen); buffer_put(buffer_1, e, dlen); buffer_putflush(buffer_1, "\n", 1); pos +=klen +dlen; } return(0); } net/ipsvd-1.0.0/src/check-local0000755000000000000000000000035011025276022014776 0ustar rootroot#!/bin/sh PATH=`pwd`:$PATH for i in ${1+"$@"}; do echo "Checking $i..." env - PATH="$PATH" ctmp="`pwd`/check-tmp" $i.check 2>&1 |cat -v >$i.local ./check-diff $i || ( cat $i.local; echo "$i failed."; exit 1 ) || exit 1 done net/ipsvd-1.0.0/src/check-tcpsvd.c0000644000000000000000000000145511025276022015434 0ustar rootroot#include #include "error.h" #include "buffer.h" #include "strerr.h" #include "socket.h" char ip[4]; int s; int i; int main() { ip[0] =127; ip[1] =0; ip[2] =0; ip[3] =1; s =socket_tcp(); if (s == -1) strerr_die1sys(111, "fatal: unable to create socket: "); if (socket_bind4(s, ip, 0) == -1) strerr_die1sys(111, "fatal: unable to bind socket: "); if (socket_connect4(s, ip, 12614) == -1) if ((errno != error_wouldblock) && (errno != error_inprogress)) strerr_die1sys(111, "fatal: unable to connect socket: "); for (i =0; i < 2; ++i) if (socket_connected(s)) break; else sleep(1); if (i >= 2) strerr_die1sys(111, "fatal: timeout connecting socket: "); if (write(s, "bar\n", 4) != 4) strerr_die1sys(111, "fatal: unable to write to socket: "); close(s); return(0); } net/ipsvd-1.0.0/src/check-udpsvd.c0000644000000000000000000000143411025276022015433 0ustar rootroot#include #include #include #include #include #include "error.h" #include "buffer.h" #include "strerr.h" #include "socket.h" #include "byte.h" char ip[4]; int s; struct sockaddr_in sa; int main() { ip[0] =127; ip[1] =0; ip[2] =0; ip[3] =1; s =socket_udp(); if (s == -1) strerr_die1sys(111, "fatal: unable to create socket: "); if (socket_bind4(s, ip, 0) == -1) strerr_die1sys(111, "fatal: unable to bind socket: "); byte_zero(&sa, sizeof(sa)); sa.sin_family =AF_INET; uint16_pack_big((char *)&sa.sin_port, 12614); byte_copy((char *)&sa.sin_addr, 4, ip); if (sendto(s, "foo\n", 4, 0, (struct sockaddr *)&sa, sizeof(sa)) != 4) strerr_die1sys(111, "fatal: unable to send: "); close(s); return(0); } net/ipsvd-1.0.0/src/chkshsgr.c0000644000000000000000000000024711025276022014670 0ustar rootroot/* Public domain. */ #include int main() { short x[4]; x[0] = x[1] = 0; if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); _exit(0); } net/ipsvd-1.0.0/src/choose.sh0000644000000000000000000000040211025276022014515 0ustar rootroot result="$4" case "$1" in *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;; esac case "$1" in *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;; esac case "$1" in *r*) ./$2 >/dev/null 2>&1 || result="$3" ;; esac rm -f $2.o $2 exec cat "$result" net/ipsvd-1.0.0/src/coe.c0000644000000000000000000000015511025276022013620 0ustar rootroot/* Public domain. */ #include #include "coe.h" int coe(int fd) { return fcntl(fd,F_SETFD,1); } net/ipsvd-1.0.0/src/coe.h0000644000000000000000000000012011025276022013615 0ustar rootroot/* Public domain. */ #ifndef COE_H #define COE_H extern int coe(int); #endif net/ipsvd-1.0.0/src/conf-cc0000644000000000000000000000026111025276022014137 0ustar rootrootgcc -O2 -Wall gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings This will be used to compile .c files. net/ipsvd-1.0.0/src/conf-ld0000644000000000000000000000007711025276022014156 0ustar rootrootgcc -s This will be used to link .o files into an executable. net/ipsvd-1.0.0/src/direntry.h10000644000000000000000000000024711025276022015002 0ustar rootroot/* Public domain. */ #ifndef DIRENTRY_H #define DIRENTRY_H /* sysdep: -dirent */ #include #include #define direntry struct direct #endif net/ipsvd-1.0.0/src/direntry.h20000644000000000000000000000024611025276022015002 0ustar rootroot/* Public domain. */ #ifndef DIRENTRY_H #define DIRENTRY_H /* sysdep: +dirent */ #include #include #define direntry struct dirent #endif net/ipsvd-1.0.0/src/dns.h0000644000000000000000000000562711025276022013654 0ustar rootroot#ifndef DNS_H #define DNS_H #include "stralloc.h" #include "iopause.h" #include "taia.h" #define DNS_C_IN "\0\1" #define DNS_C_ANY "\0\377" #define DNS_T_A "\0\1" #define DNS_T_NS "\0\2" #define DNS_T_CNAME "\0\5" #define DNS_T_SOA "\0\6" #define DNS_T_PTR "\0\14" #define DNS_T_HINFO "\0\15" #define DNS_T_MX "\0\17" #define DNS_T_TXT "\0\20" #define DNS_T_RP "\0\21" #define DNS_T_SIG "\0\30" #define DNS_T_KEY "\0\31" #define DNS_T_AAAA "\0\34" #define DNS_T_AXFR "\0\374" #define DNS_T_ANY "\0\377" struct dns_transmit { char *query; /* 0, or dynamically allocated */ unsigned int querylen; char *packet; /* 0, or dynamically allocated */ unsigned int packetlen; int s1; /* 0, or 1 + an open file descriptor */ int tcpstate; unsigned int udploop; unsigned int curserver; struct taia deadline; unsigned int pos; const char *servers; char localip[4]; char qtype[2]; } ; extern void dns_random_init(const char *); extern unsigned int dns_random(unsigned int); extern void dns_sortip(char *,unsigned int); extern void dns_domain_free(char **); extern int dns_domain_copy(char **,const char *); extern unsigned int dns_domain_length(const char *); extern int dns_domain_equal(const char *,const char *); extern int dns_domain_suffix(const char *,const char *); extern unsigned int dns_domain_suffixpos(const char *,const char *); extern int dns_domain_fromdot(char **,const char *,unsigned int); extern int dns_domain_todot_cat(stralloc *,const char *); extern unsigned int dns_packet_copy(const char *,unsigned int,unsigned int,char *,unsigned int); extern unsigned int dns_packet_getname(const char *,unsigned int,unsigned int,char **); extern unsigned int dns_packet_skipname(const char *,unsigned int,unsigned int); extern int dns_transmit_start(struct dns_transmit *,const char *,int,const char *,const char *,const char *); extern void dns_transmit_free(struct dns_transmit *); extern void dns_transmit_io(struct dns_transmit *,iopause_fd *,struct taia *); extern int dns_transmit_get(struct dns_transmit *,const iopause_fd *,const struct taia *); extern int dns_resolvconfip(char *); extern int dns_resolve(const char *,const char *); extern struct dns_transmit dns_resolve_tx; extern int dns_ip4_packet(stralloc *,const char *,unsigned int); extern int dns_ip4(stralloc *,const stralloc *); extern int dns_name_packet(stralloc *,const char *,unsigned int); extern void dns_name4_domain(char *,const char *); #define DNS_NAME4_DOMAIN 31 extern int dns_name4(stralloc *,const char *); extern int dns_txt_packet(stralloc *,const char *,unsigned int); extern int dns_txt(stralloc *,const stralloc *); extern int dns_mx_packet(stralloc *,const char *,unsigned int); extern int dns_mx(stralloc *,const stralloc *); extern int dns_resolvconfrewrite(stralloc *); extern int dns_ip4_qualify_rules(stralloc *,stralloc *,const stralloc *,const stralloc *); extern int dns_ip4_qualify(stralloc *,stralloc *,const stralloc *); #endif net/ipsvd-1.0.0/src/dns_dfd.c0000644000000000000000000000277511025276022014465 0ustar rootroot#include "error.h" #include "alloc.h" #include "byte.h" #include "dns.h" int dns_domain_fromdot(char **out,const char *buf,unsigned int n) { char label[63]; unsigned int labellen = 0; /* <= sizeof label */ char name[255]; unsigned int namelen = 0; /* <= sizeof name */ char ch; char *x; errno = error_proto; for (;;) { if (!n) break; ch = *buf++; --n; if (ch == '.') { if (labellen) { if (namelen + labellen + 1 > sizeof name) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } continue; } if (ch == '\\') { if (!n) break; ch = *buf++; --n; if ((ch >= '0') && (ch <= '7')) { ch -= '0'; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; } } } } if (labellen >= sizeof label) return 0; label[labellen++] = ch; } if (labellen) { if (namelen + labellen + 1 > sizeof name) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } if (namelen + 1 > sizeof name) return 0; name[namelen++] = 0; x = alloc(namelen); if (!x) return 0; byte_copy(x,namelen,name); if (*out) alloc_free(*out); *out = x; return 1; } net/ipsvd-1.0.0/src/dns_domain.c0000644000000000000000000000235511025276022015171 0ustar rootroot#include "error.h" #include "alloc.h" #include "case.h" #include "byte.h" #include "dns.h" unsigned int dns_domain_length(const char *dn) { const char *x; unsigned char c; x = dn; while (c = *x++) x += (unsigned int) c; return x - dn; } void dns_domain_free(char **out) { if (*out) { alloc_free(*out); *out = 0; } } int dns_domain_copy(char **out,const char *in) { unsigned int len; char *x; len = dns_domain_length(in); x = alloc(len); if (!x) return 0; byte_copy(x,len,in); if (*out) alloc_free(*out); *out = x; return 1; } int dns_domain_equal(const char *dn1,const char *dn2) { unsigned int len; len = dns_domain_length(dn1); if (len != dns_domain_length(dn2)) return 0; if (case_diffb(dn1,len,dn2)) return 0; /* safe since 63 < 'A' */ return 1; } int dns_domain_suffix(const char *big,const char *little) { unsigned char c; for (;;) { if (dns_domain_equal(big,little)) return 1; c = *big++; if (!c) return 0; big += c; } } unsigned int dns_domain_suffixpos(const char *big,const char *little) { const char *orig = big; unsigned char c; for (;;) { if (dns_domain_equal(big,little)) return big - orig; c = *big++; if (!c) return 0; big += c; } } net/ipsvd-1.0.0/src/dns_dtda.c0000644000000000000000000000145511025276022014636 0ustar rootroot#include "stralloc.h" #include "dns.h" int dns_domain_todot_cat(stralloc *out,const char *d) { char ch; char ch2; unsigned char ch3; char buf[4]; if (!*d) return stralloc_append(out,"."); for (;;) { ch = *d++; while (ch--) { ch2 = *d++; if ((ch2 >= 'A') && (ch2 <= 'Z')) ch2 += 32; if (((ch2 >= 'a') && (ch2 <= 'z')) || ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_')) { if (!stralloc_append(out,&ch2)) return 0; } else { ch3 = ch2; buf[3] = '0' + (ch3 & 7); ch3 >>= 3; buf[2] = '0' + (ch3 & 7); ch3 >>= 3; buf[1] = '0' + (ch3 & 7); buf[0] = '\\'; if (!stralloc_catb(out,buf,4)) return 0; } } if (!*d) return 1; if (!stralloc_append(out,".")) return 0; } } net/ipsvd-1.0.0/src/dns_ip.c0000644000000000000000000000344311025276022014331 0ustar rootroot#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_A)) if (byte_equal(header + 2,2,DNS_C_IN)) if (datalen == 4) { if (!dns_packet_copy(buf,len,pos,header,4)) return -1; if (!stralloc_catb(out,header,4)) return -1; } pos += datalen; } dns_sortip(out->s,out->len); return 0; } static char *q = 0; int dns_ip4(stralloc *out,const stralloc *fqdn) { unsigned int i; char code; char ch; if (!stralloc_copys(out,"")) return -1; code = 0; for (i = 0;i <= fqdn->len;++i) { if (i < fqdn->len) ch = fqdn->s[i]; else ch = '.'; if ((ch == '[') || (ch == ']')) continue; if (ch == '.') { if (!stralloc_append(out,&code)) return -1; code = 0; continue; } if ((ch >= '0') && (ch <= '9')) { code *= 10; code += ch - '0'; continue; } if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_A) == -1) return -1; if (dns_ip4_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } out->len &= ~3; return 0; } net/ipsvd-1.0.0/src/dns_ipq.c0000644000000000000000000000341011025276022014504 0ustar rootroot#include "stralloc.h" #include "case.h" #include "byte.h" #include "str.h" #include "dns.h" static int doit(stralloc *work,const char *rule) { char ch; unsigned int colon; unsigned int prefixlen; ch = *rule++; if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1; colon = str_chr(rule,':'); if (!rule[colon]) return 1; if (work->len < colon) return 1; prefixlen = work->len - colon; if ((ch == '=') && prefixlen) return 1; if (case_diffb(rule,colon,work->s + prefixlen)) return 1; if (ch == '?') { if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1; } work->len = prefixlen; if (ch == '-') work->len = 0; return stralloc_cats(work,rule + colon + 1); } int dns_ip4_qualify_rules(stralloc *out,stralloc *fqdn,const stralloc *in,const stralloc *rules) { unsigned int i; unsigned int j; unsigned int plus; unsigned int fqdnlen; if (!stralloc_copy(fqdn,in)) return -1; for (j = i = 0;j < rules->len;++j) if (!rules->s[j]) { if (!doit(fqdn,rules->s + i)) return -1; i = j + 1; } fqdnlen = fqdn->len; plus = byte_chr(fqdn->s,fqdnlen,'+'); if (plus >= fqdnlen) return dns_ip4(out,fqdn); i = plus + 1; for (;;) { j = byte_chr(fqdn->s + i,fqdnlen - i,'+'); byte_copy(fqdn->s + plus,j,fqdn->s + i); fqdn->len = plus + j; if (dns_ip4(out,fqdn) == -1) return -1; if (out->len) return 0; i += j; if (i >= fqdnlen) return 0; ++i; } } int dns_ip4_qualify(stralloc *out,stralloc *fqdn,const stralloc *in) { static stralloc rules; if (dns_resolvconfrewrite(&rules) == -1) return -1; return dns_ip4_qualify_rules(out,fqdn,in,&rules); } net/ipsvd-1.0.0/src/dns_mx.c0000644000000000000000000000262011025276022014341 0ustar rootroot#include "stralloc.h" #include "byte.h" #include "uint16.h" #include "dns.h" static char *q = 0; int dns_mx_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; char pref[2]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_MX)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_copy(buf,len,pos,pref,2)) return -1; if (!dns_packet_getname(buf,len,pos + 2,&q)) return -1; if (!stralloc_catb(out,pref,2)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; if (!stralloc_0(out)) return -1; } pos += datalen; } return 0; } int dns_mx(stralloc *out,const stralloc *fqdn) { if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_MX) == -1) return -1; if (dns_mx_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } net/ipsvd-1.0.0/src/dns_name.c0000644000000000000000000000237611025276022014645 0ustar rootroot#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" static char *q = 0; int dns_name_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_PTR)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_getname(buf,len,pos,&q)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; return 0; } pos += datalen; } return 0; } int dns_name4(stralloc *out,const char ip[4]) { char name[DNS_NAME4_DOMAIN]; dns_name4_domain(name,ip); if (dns_resolve(name,DNS_T_PTR) == -1) return -1; if (dns_name_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } net/ipsvd-1.0.0/src/dns_nd.c0000644000000000000000000000126311025276022014320 0ustar rootroot#include "byte.h" #include "fmt.h" #include "dns.h" void dns_name4_domain(char name[DNS_NAME4_DOMAIN],const char ip[4]) { unsigned int namelen; unsigned int i; namelen = 0; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[3]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[2]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[1]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[0]); name[namelen++] = i; namelen += i; byte_copy(name + namelen,14,"\7in-addr\4arpa\0"); } net/ipsvd-1.0.0/src/dns_packet.c0000644000000000000000000000335711025276022015174 0ustar rootroot/* DNS should have used LZ77 instead of its own sophomoric compression algorithm. */ #include "error.h" #include "dns.h" unsigned int dns_packet_copy(const char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) { while (outlen) { if (pos >= len) { errno = error_proto; return 0; } *out = buf[pos++]; ++out; --outlen; } return pos; } unsigned int dns_packet_skipname(const char *buf,unsigned int len,unsigned int pos) { unsigned char ch; for (;;) { if (pos >= len) break; ch = buf[pos++]; if (ch >= 192) return pos + 1; if (ch >= 64) break; if (!ch) return pos; pos += ch; } errno = error_proto; return 0; } unsigned int dns_packet_getname(const char *buf,unsigned int len,unsigned int pos,char **d) { unsigned int loop = 0; unsigned int state = 0; unsigned int firstcompress = 0; unsigned int where; unsigned char ch; char name[255]; unsigned int namelen = 0; for (;;) { if (pos >= len) goto PROTO; ch = buf[pos++]; if (++loop >= 1000) goto PROTO; if (state) { if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; --state; } else { while (ch >= 192) { where = ch; where -= 192; where <<= 8; if (pos >= len) goto PROTO; ch = buf[pos++]; if (!firstcompress) firstcompress = pos; pos = where + ch; if (pos >= len) goto PROTO; ch = buf[pos++]; if (++loop >= 1000) goto PROTO; } if (ch >= 64) goto PROTO; if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; if (!ch) break; state = ch; } } if (!dns_domain_copy(d,name)) return 0; if (firstcompress) return firstcompress; return pos; PROTO: errno = error_proto; return 0; } net/ipsvd-1.0.0/src/dns_random.c0000644000000000000000000000253011025276022015175 0ustar rootroot#include #include "dns.h" #include "taia.h" #include "uint32.h" static uint32 seed[32]; static uint32 in[12]; static uint32 out[8]; static int outleft = 0; #define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b)))) #define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b)); static void surf(void) { uint32 t[12]; uint32 x; uint32 sum = 0; int r; int i; int loop; for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i]; for (i = 0;i < 8;++i) out[i] = seed[24 + i]; x = t[11]; for (loop = 0;loop < 2;++loop) { for (r = 0;r < 16;++r) { sum += 0x9e3779b9; MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13) MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13) MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13) } for (i = 0;i < 8;++i) out[i] ^= t[i + 4]; } } void dns_random_init(const char data[128]) { int i; struct taia t; char tpack[16]; for (i = 0;i < 32;++i) uint32_unpack(data + 4 * i,seed + i); taia_now(&t); taia_pack(tpack,&t); for (i = 0;i < 4;++i) uint32_unpack(tpack + 4 * i,in + 4 + i); in[8] = getpid(); in[9] = getppid(); /* more space in 10 and 11, but this is probably enough */ } unsigned int dns_random(unsigned int n) { if (!n) return 0; if (!outleft) { if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; surf(); outleft = 8; } return out[--outleft] % n; } net/ipsvd-1.0.0/src/dns_rcip.c0000644000000000000000000000332611025276022014656 0ustar rootroot#include "taia.h" #include "openreadclose.h" #include "byte.h" #include "ip4.h" #include "env.h" #include "dns.h" static stralloc data = {0}; static int init(char ip[64]) { int i; int j; int iplen = 0; char *x; x = env_get("DNSCACHEIP"); if (x) while (iplen <= 60) { if (*x == '.') ++x; else { i = ip4_scan(x,ip + iplen); if (!i) break; x += i; iplen += 4; } } if (!iplen) { i = openreadclose("/etc/resolv.conf",&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) { i += 10; while ((data.s[i] == ' ') || (data.s[i] == '\t')) ++i; if (iplen <= 60) if (ip4_scan(data.s + i,ip + iplen)) { if (byte_equal(ip + iplen,4,"\0\0\0\0")) byte_copy(ip + iplen,4,"\177\0\0\1"); iplen += 4; } } i = j + 1; } } } if (!iplen) { byte_copy(ip,4,"\177\0\0\1"); iplen = 4; } byte_zero(ip + iplen,64 - iplen); return 0; } static int ok = 0; static unsigned int uses; static struct taia deadline; static char ip[64]; /* defined if ok */ int dns_resolvconfip(char s[64]) { struct taia now; taia_now(&now); if (taia_less(&deadline,&now)) ok = 0; if (!uses) ok = 0; if (!ok) { if (init(ip) == -1) return -1; taia_uint(&deadline,600); taia_add(&deadline,&now,&deadline); uses = 10000; ok = 1; } --uses; byte_copy(s,64,ip); return 0; } net/ipsvd-1.0.0/src/dns_rcrw.c0000644000000000000000000000640111025276022014673 0ustar rootroot#include #include "taia.h" #include "env.h" #include "byte.h" #include "str.h" #include "openreadclose.h" #include "dns.h" static stralloc data = {0}; static int init(stralloc *rules) { char host[256]; const char *x; int i; int j; int k; if (!stralloc_copys(rules,"")) return -1; x = env_get("DNSREWRITEFILE"); if (!x) x = "/etc/dnsrewrite"; i = openreadclose(x,&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (!stralloc_catb(rules,data.s + i,j - i)) return -1; while (rules->len) { if (rules->s[rules->len - 1] != ' ') if (rules->s[rules->len - 1] != '\t') if (rules->s[rules->len - 1] != '\r') break; --rules->len; } if (!stralloc_0(rules)) return -1; i = j + 1; } return 0; } x = env_get("LOCALDOMAIN"); if (x) { if (!stralloc_copys(&data,x)) return -1; if (!stralloc_append(&data," ")) return -1; if (!stralloc_copys(rules,"?:")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == ' ') { if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,j - i)) return -1; i = j + 1; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = openreadclose("/etc/resolv.conf",&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) { if (!stralloc_copys(rules,"?:")) return -1; i += 7; while (i < j) { k = byte_chr(data.s + i,j - i,' '); k = byte_chr(data.s + i,k,'\t'); if (!k) { ++i; continue; } if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,k)) return -1; i += k; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = j + 1; } } host[0] = 0; if (gethostname(host,sizeof host) == -1) return -1; host[(sizeof host) - 1] = 0; i = str_chr(host,'.'); if (host[i]) { if (!stralloc_copys(rules,"?:")) return -1; if (!stralloc_cats(rules,host + i)) return -1; if (!stralloc_0(rules)) return -1; } if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } static int ok = 0; static unsigned int uses; static struct taia deadline; static stralloc rules = {0}; /* defined if ok */ int dns_resolvconfrewrite(stralloc *out) { struct taia now; taia_now(&now); if (taia_less(&deadline,&now)) ok = 0; if (!uses) ok = 0; if (!ok) { if (init(&rules) == -1) return -1; taia_uint(&deadline,600); taia_add(&deadline,&now,&deadline); uses = 10000; ok = 1; } --uses; if (!stralloc_copy(out,&rules)) return -1; return 0; } net/ipsvd-1.0.0/src/dns_resolve.c0000644000000000000000000000130511025276022015373 0ustar rootroot#include "iopause.h" #include "taia.h" #include "byte.h" #include "dns.h" struct dns_transmit dns_resolve_tx = {0}; int dns_resolve(const char *q,const char qtype[2]) { struct taia stamp; struct taia deadline; char servers[64]; iopause_fd x[1]; int r; if (dns_resolvconfip(servers) == -1) return -1; if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,"\0\0\0\0") == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&dns_resolve_tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&dns_resolve_tx,x,&stamp); if (r == -1) return -1; if (r == 1) return 0; } } net/ipsvd-1.0.0/src/dns_sortip.c0000644000000000000000000000063211025276022015236 0ustar rootroot#include "byte.h" #include "dns.h" /* XXX: sort servers by configurable notion of closeness? */ /* XXX: pay attention to competence of each server? */ void dns_sortip(char *s,unsigned int n) { unsigned int i; char tmp[4]; n >>= 2; while (n > 1) { i = dns_random(n); --n; byte_copy(tmp,4,s + (i << 2)); byte_copy(s + (i << 2),4,s + (n << 2)); byte_copy(s + (n << 2),4,tmp); } } net/ipsvd-1.0.0/src/dns_transmit.c0000644000000000000000000002025111025276022015556 0ustar rootroot#include #include #include #include "socket.h" #include "alloc.h" #include "error.h" #include "byte.h" #include "uint16.h" #include "dns.h" static int serverwantstcp(const char *buf,unsigned int len) { char out[12]; if (!dns_packet_copy(buf,len,0,out,12)) return 1; if (out[2] & 2) return 1; return 0; } static int serverfailed(const char *buf,unsigned int len) { char out[12]; unsigned int rcode; if (!dns_packet_copy(buf,len,0,out,12)) return 1; rcode = out[3]; rcode &= 15; if (rcode && (rcode != 3)) { errno = error_again; return 1; } return 0; } static int irrelevant(const struct dns_transmit *d,const char *buf,unsigned int len) { char out[12]; char *dn; unsigned int pos; pos = dns_packet_copy(buf,len,0,out,12); if (!pos) return 1; if (byte_diff(out,2,d->query + 2)) return 1; if (out[4] != 0) return 1; if (out[5] != 1) return 1; dn = 0; pos = dns_packet_getname(buf,len,pos,&dn); if (!pos) return 1; if (!dns_domain_equal(dn,d->query + 14)) { alloc_free(dn); return 1; } alloc_free(dn); pos = dns_packet_copy(buf,len,pos,out,4); if (!pos) return 1; if (byte_diff(out,2,d->qtype)) return 1; if (byte_diff(out + 2,2,DNS_C_IN)) return 1; return 0; } static void packetfree(struct dns_transmit *d) { if (!d->packet) return; alloc_free(d->packet); d->packet = 0; } static void queryfree(struct dns_transmit *d) { if (!d->query) return; alloc_free(d->query); d->query = 0; } static void socketfree(struct dns_transmit *d) { if (!d->s1) return; close(d->s1 - 1); d->s1 = 0; } void dns_transmit_free(struct dns_transmit *d) { queryfree(d); socketfree(d); packetfree(d); } static int randombind(struct dns_transmit *d) { int j; for (j = 0;j < 10;++j) if (socket_bind4(d->s1 - 1,d->localip,1025 + dns_random(64510)) == 0) return 0; if (socket_bind4(d->s1 - 1,d->localip,0) == 0) return 0; return -1; } static const int timeouts[4] = { 1, 3, 11, 45 }; static int thisudp(struct dns_transmit *d) { const char *ip; socketfree(d); while (d->udploop < 4) { for (;d->curserver < 16;++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff(ip,4,"\0\0\0\0")) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_udp(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } if (socket_connect4(d->s1 - 1,ip,53) == 0) if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) { struct taia now; taia_now(&now); taia_uint(&d->deadline,timeouts[d->udploop]); taia_add(&d->deadline,&d->deadline,&now); d->tcpstate = 0; return 0; } socketfree(d); } } ++d->udploop; d->curserver = 0; } dns_transmit_free(d); return -1; } static int firstudp(struct dns_transmit *d) { d->curserver = 0; return thisudp(d); } static int nextudp(struct dns_transmit *d) { ++d->curserver; return thisudp(d); } static int thistcp(struct dns_transmit *d) { struct taia now; const char *ip; socketfree(d); packetfree(d); for (;d->curserver < 16;++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff(ip,4,"\0\0\0\0")) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_tcp(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } taia_now(&now); taia_uint(&d->deadline,10); taia_add(&d->deadline,&d->deadline,&now); if (socket_connect4(d->s1 - 1,ip,53) == 0) { d->tcpstate = 2; return 0; } if ((errno == error_inprogress) || (errno == error_wouldblock)) { d->tcpstate = 1; return 0; } socketfree(d); } } dns_transmit_free(d); return -1; } static int firsttcp(struct dns_transmit *d) { d->curserver = 0; return thistcp(d); } static int nexttcp(struct dns_transmit *d) { ++d->curserver; return thistcp(d); } int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrecursive,const char *q,const char qtype[2],const char localip[4]) { unsigned int len; dns_transmit_free(d); errno = error_io; len = dns_domain_length(q); d->querylen = len + 18; d->query = alloc(d->querylen); if (!d->query) return -1; uint16_pack_big(d->query,len + 16); byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround"); byte_copy(d->query + 14,len,q); byte_copy(d->query + 14 + len,2,qtype); byte_copy(d->query + 16 + len,2,DNS_C_IN); byte_copy(d->qtype,2,qtype); d->servers = servers; byte_copy(d->localip,4,localip); d->udploop = flagrecursive ? 1 : 0; if (len + 16 > 512) return firsttcp(d); return firstudp(d); } void dns_transmit_io(struct dns_transmit *d,iopause_fd *x,struct taia *deadline) { x->fd = d->s1 - 1; switch(d->tcpstate) { case 0: case 3: case 4: case 5: x->events = IOPAUSE_READ; break; case 1: case 2: x->events = IOPAUSE_WRITE; break; } if (taia_less(&d->deadline,deadline)) *deadline = d->deadline; } int dns_transmit_get(struct dns_transmit *d,const iopause_fd *x,const struct taia *when) { char udpbuf[513]; unsigned char ch; int r; int fd; errno = error_io; fd = d->s1 - 1; if (!x->revents) { if (taia_less(when,&d->deadline)) return 0; errno = error_timeout; if (d->tcpstate == 0) return nextudp(d); return nexttcp(d); } if (d->tcpstate == 0) { /* have attempted to send UDP query to each server udploop times have sent query to curserver on UDP socket s */ r = recv(fd,udpbuf,sizeof udpbuf,0); if (r <= 0) { if (errno == error_connrefused) if (d->udploop == 2) return 0; return nextudp(d); } if (r + 1 > sizeof udpbuf) return 0; if (irrelevant(d,udpbuf,r)) return 0; if (serverwantstcp(udpbuf,r)) return firsttcp(d); if (serverfailed(udpbuf,r)) { if (d->udploop == 2) return 0; return nextudp(d); } socketfree(d); d->packetlen = r; d->packet = alloc(d->packetlen); if (!d->packet) { dns_transmit_free(d); return -1; } byte_copy(d->packet,d->packetlen,udpbuf); queryfree(d); return 1; } if (d->tcpstate == 1) { /* have sent connection attempt to curserver on TCP socket s pos not defined */ if (!socket_connected(fd)) return nexttcp(d); d->pos = 0; d->tcpstate = 2; return 0; } if (d->tcpstate == 2) { /* have connection to curserver on TCP socket s have sent pos bytes of query */ r = write(fd,d->query + d->pos,d->querylen - d->pos); if (r <= 0) return nexttcp(d); d->pos += r; if (d->pos == d->querylen) { struct taia now; taia_now(&now); taia_uint(&d->deadline,10); taia_add(&d->deadline,&d->deadline,&now); d->tcpstate = 3; } return 0; } if (d->tcpstate == 3) { /* have sent entire query to curserver on TCP socket s pos not defined */ r = read(fd,&ch,1); if (r <= 0) return nexttcp(d); d->packetlen = ch; d->tcpstate = 4; return 0; } if (d->tcpstate == 4) { /* have sent entire query to curserver on TCP socket s pos not defined have received one byte of packet length into packetlen */ r = read(fd,&ch,1); if (r <= 0) return nexttcp(d); d->packetlen <<= 8; d->packetlen += ch; d->tcpstate = 5; d->pos = 0; d->packet = alloc(d->packetlen); if (!d->packet) { dns_transmit_free(d); return -1; } return 0; } if (d->tcpstate == 5) { /* have sent entire query to curserver on TCP socket s have received entire packet length into packetlen packet is allocated have received pos bytes of packet */ r = read(fd,d->packet + d->pos,d->packetlen - d->pos); if (r <= 0) return nexttcp(d); d->pos += r; if (d->pos < d->packetlen) return 0; socketfree(d); if (irrelevant(d,d->packet,d->packetlen)) return nexttcp(d); if (serverwantstcp(d->packet,d->packetlen)) return nexttcp(d); if (serverfailed(d->packet,d->packetlen)) return nexttcp(d); queryfree(d); return 1; } return 0; } net/ipsvd-1.0.0/src/dns_txt.c0000644000000000000000000000303711025276022014537 0ustar rootroot#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" int dns_txt_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; char ch; unsigned int txtlen; int i; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_TXT)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (pos + datalen > len) return -1; txtlen = 0; for (i = 0;i < datalen;++i) { ch = buf[pos + i]; if (!txtlen) txtlen = (unsigned char) ch; else { --txtlen; if (ch < 32) ch = '?'; if (ch > 126) ch = '?'; if (!stralloc_append(out,&ch)) return -1; } } } pos += datalen; } return 0; } static char *q = 0; int dns_txt(stralloc *out,const stralloc *fqdn) { if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_TXT) == -1) return -1; if (dns_txt_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } net/ipsvd-1.0.0/src/env.c0000644000000000000000000000047211025276022013644 0ustar rootroot/* Public domain. */ #include "str.h" #include "env.h" extern /*@null@*/char *env_get(const char *s) { int i; unsigned int len; if (!s) return 0; len = str_len(s); for (i = 0;environ[i];++i) if (str_start(environ[i],s) && (environ[i][len] == '=')) return environ[i] + len + 1; return 0; } net/ipsvd-1.0.0/src/env.h0000644000000000000000000000020111025276022013637 0ustar rootroot/* Public domain. */ #ifndef ENV_H #define ENV_H extern char **environ; extern /*@null@*/char *env_get(const char *); #endif net/ipsvd-1.0.0/src/error.c0000644000000000000000000000232011025276022014177 0ustar rootroot/* Public domain. */ #include #include "error.h" /* warning: as coverage improves here, should update error_{str,temp} */ int error_intr = #ifdef EINTR EINTR; #else -1; #endif int error_nomem = #ifdef ENOMEM ENOMEM; #else -2; #endif int error_noent = #ifdef ENOENT ENOENT; #else -3; #endif int error_txtbsy = #ifdef ETXTBSY ETXTBSY; #else -4; #endif int error_io = #ifdef EIO EIO; #else -5; #endif int error_exist = #ifdef EEXIST EEXIST; #else -6; #endif int error_timeout = #ifdef ETIMEDOUT ETIMEDOUT; #else -7; #endif int error_inprogress = #ifdef EINPROGRESS EINPROGRESS; #else -8; #endif int error_wouldblock = #ifdef EWOULDBLOCK EWOULDBLOCK; #else -9; #endif int error_again = #ifdef EAGAIN EAGAIN; #else -10; #endif int error_pipe = #ifdef EPIPE EPIPE; #else -11; #endif int error_perm = #ifdef EPERM EPERM; #else -12; #endif int error_acces = #ifdef EACCES EACCES; #else -13; #endif int error_nodevice = #ifdef ENXIO ENXIO; #else -14; #endif int error_proto = #ifdef EPROTO EPROTO; #else -15; #endif int error_isdir = #ifdef EISDIR EISDIR; #else -16; #endif int error_connrefused = #ifdef ECONNREFUSED ECONNREFUSED; #else -17; #endif int error_notdir = #ifdef ENOTDIR ENOTDIR; #else -18; #endif net/ipsvd-1.0.0/src/error.h0000644000000000000000000000124711025276022014213 0ustar rootroot/* Public domain. */ #ifndef ERROR_H #define ERROR_H /* 20030307: include -upcoming glibc changes */ #include /* extern int errno; */ extern int error_intr; extern int error_nomem; extern int error_noent; extern int error_txtbsy; extern int error_io; extern int error_exist; extern int error_timeout; extern int error_inprogress; extern int error_wouldblock; extern int error_again; extern int error_pipe; extern int error_perm; extern int error_acces; extern int error_nodevice; extern int error_proto; extern int error_isdir; extern int error_connrefused; extern int error_notdir; extern const char *error_str(int); extern int error_temp(int); #endif net/ipsvd-1.0.0/src/error_str.c0000644000000000000000000001257611025276022015105 0ustar rootroot/* Public domain. */ #include #include "error.h" #define X(e,s) if (i == e) return s; const char *error_str(int i) { X(0,"no error") X(error_intr,"interrupted system call") X(error_nomem,"out of memory") X(error_noent,"file does not exist") X(error_txtbsy,"text busy") X(error_io,"input/output error") X(error_exist,"file already exists") X(error_timeout,"timed out") X(error_inprogress,"operation in progress") X(error_again,"temporary failure") X(error_wouldblock,"input/output would block") X(error_pipe,"broken pipe") X(error_perm,"permission denied") X(error_acces,"access denied") X(error_nodevice,"device not configured") X(error_proto,"protocol error") X(error_isdir,"is a directory") X(error_connrefused,"connection refused") X(error_notdir,"not a directory") #ifdef ESRCH X(ESRCH,"no such process") #endif #ifdef E2BIG X(E2BIG,"argument list too long") #endif #ifdef ENOEXEC X(ENOEXEC,"exec format error") #endif #ifdef EBADF X(EBADF,"file descriptor not open") #endif #ifdef ECHILD X(ECHILD,"no child processes") #endif #ifdef EDEADLK X(EDEADLK,"operation would cause deadlock") #endif #ifdef EFAULT X(EFAULT,"bad address") #endif #ifdef ENOTBLK X(ENOTBLK,"not a block device") #endif #ifdef EBUSY X(EBUSY,"device busy") #endif #ifdef EXDEV X(EXDEV,"cross-device link") #endif #ifdef ENODEV X(ENODEV,"device does not support operation") #endif #ifdef EINVAL X(EINVAL,"invalid argument") #endif #ifdef ENFILE X(ENFILE,"system cannot open more files") #endif #ifdef EMFILE X(EMFILE,"process cannot open more files") #endif #ifdef ENOTTY X(ENOTTY,"not a tty") #endif #ifdef EFBIG X(EFBIG,"file too big") #endif #ifdef ENOSPC X(ENOSPC,"out of disk space") #endif #ifdef ESPIPE X(ESPIPE,"unseekable descriptor") #endif #ifdef EROFS X(EROFS,"read-only file system") #endif #ifdef EMLINK X(EMLINK,"too many links") #endif #ifdef EDOM X(EDOM,"input out of range") #endif #ifdef ERANGE X(ERANGE,"output out of range") #endif #ifdef EALREADY X(EALREADY,"operation already in progress") #endif #ifdef ENOTSOCK X(ENOTSOCK,"not a socket") #endif #ifdef EDESTADDRREQ X(EDESTADDRREQ,"destination address required") #endif #ifdef EMSGSIZE X(EMSGSIZE,"message too long") #endif #ifdef EPROTOTYPE X(EPROTOTYPE,"incorrect protocol type") #endif #ifdef ENOPROTOOPT X(ENOPROTOOPT,"protocol not available") #endif #ifdef EPROTONOSUPPORT X(EPROTONOSUPPORT,"protocol not supported") #endif #ifdef ESOCKTNOSUPPORT X(ESOCKTNOSUPPORT,"socket type not supported") #endif #ifdef EOPNOTSUPP X(EOPNOTSUPP,"operation not supported") #endif #ifdef EPFNOSUPPORT X(EPFNOSUPPORT,"protocol family not supported") #endif #ifdef EAFNOSUPPORT X(EAFNOSUPPORT,"address family not supported") #endif #ifdef EADDRINUSE X(EADDRINUSE,"address already used") #endif #ifdef EADDRNOTAVAIL X(EADDRNOTAVAIL,"address not available") #endif #ifdef ENETDOWN X(ENETDOWN,"network down") #endif #ifdef ENETUNREACH X(ENETUNREACH,"network unreachable") #endif #ifdef ENETRESET X(ENETRESET,"network reset") #endif #ifdef ECONNABORTED X(ECONNABORTED,"connection aborted") #endif #ifdef ECONNRESET X(ECONNRESET,"connection reset") #endif #ifdef ENOBUFS X(ENOBUFS,"out of buffer space") #endif #ifdef EISCONN X(EISCONN,"already connected") #endif #ifdef ENOTCONN X(ENOTCONN,"not connected") #endif #ifdef ESHUTDOWN X(ESHUTDOWN,"socket shut down") #endif #ifdef ETOOMANYREFS X(ETOOMANYREFS,"too many references") #endif #ifdef ELOOP X(ELOOP,"symbolic link loop") #endif #ifdef ENAMETOOLONG X(ENAMETOOLONG,"file name too long") #endif #ifdef EHOSTDOWN X(EHOSTDOWN,"host down") #endif #ifdef EHOSTUNREACH X(EHOSTUNREACH,"host unreachable") #endif #ifdef ENOTEMPTY X(ENOTEMPTY,"directory not empty") #endif #ifdef EPROCLIM X(EPROCLIM,"too many processes") #endif #ifdef EUSERS X(EUSERS,"too many users") #endif #ifdef EDQUOT X(EDQUOT,"disk quota exceeded") #endif #ifdef ESTALE X(ESTALE,"stale NFS file handle") #endif #ifdef EREMOTE X(EREMOTE,"too many levels of remote in path") #endif #ifdef EBADRPC X(EBADRPC,"RPC structure is bad") #endif #ifdef ERPCMISMATCH X(ERPCMISMATCH,"RPC version mismatch") #endif #ifdef EPROGUNAVAIL X(EPROGUNAVAIL,"RPC program unavailable") #endif #ifdef EPROGMISMATCH X(EPROGMISMATCH,"program version mismatch") #endif #ifdef EPROCUNAVAIL X(EPROCUNAVAIL,"bad procedure for program") #endif #ifdef ENOLCK X(ENOLCK,"no locks available") #endif #ifdef ENOSYS X(ENOSYS,"system call not available") #endif #ifdef EFTYPE X(EFTYPE,"bad file type") #endif #ifdef EAUTH X(EAUTH,"authentication error") #endif #ifdef ENEEDAUTH X(ENEEDAUTH,"not authenticated") #endif #ifdef ENOSTR X(ENOSTR,"not a stream device") #endif #ifdef ETIME X(ETIME,"timer expired") #endif #ifdef ENOSR X(ENOSR,"out of stream resources") #endif #ifdef ENOMSG X(ENOMSG,"no message of desired type") #endif #ifdef EBADMSG X(EBADMSG,"bad message type") #endif #ifdef EIDRM X(EIDRM,"identifier removed") #endif #ifdef ENONET X(ENONET,"machine not on network") #endif #ifdef ERREMOTE X(ERREMOTE,"object not local") #endif #ifdef ENOLINK X(ENOLINK,"link severed") #endif #ifdef EADV X(EADV,"advertise error") #endif #ifdef ESRMNT X(ESRMNT,"srmount error") #endif #ifdef ECOMM X(ECOMM,"communication error") #endif #ifdef EMULTIHOP X(EMULTIHOP,"multihop attempted") #endif #ifdef EREMCHG X(EREMCHG,"remote address changed") #endif return "unknown error"; } net/ipsvd-1.0.0/src/fd.h0000644000000000000000000000016311025276022013447 0ustar rootroot/* Public domain. */ #ifndef FD_H #define FD_H extern int fd_copy(int,int); extern int fd_move(int,int); #endif net/ipsvd-1.0.0/src/fd_copy.c0000644000000000000000000000040111025276022014467 0ustar rootroot/* Public domain. */ #include #include #include "fd.h" int fd_copy(int to,int from) { if (to == from) return 0; if (fcntl(from,F_GETFL,0) == -1) return -1; close(to); if (fcntl(from,F_DUPFD,to) == -1) return -1; return 0; } net/ipsvd-1.0.0/src/fd_move.c0000644000000000000000000000027411025276022014473 0ustar rootroot/* Public domain. */ #include #include "fd.h" int fd_move(int to,int from) { if (to == from) return 0; if (fd_copy(to,from) == -1) return -1; close(from); return 0; } net/ipsvd-1.0.0/src/fifo.c0000644000000000000000000000043311025276022013774 0ustar rootroot/* Public domain. */ #include #include #include "hasmkffo.h" #include "fifo.h" #ifdef HASMKFIFO int fifo_make(const char *fn,int mode) { return mkfifo(fn,mode); } #else int fifo_make(const char *fn,int mode) { return mknod(fn,S_IFIFO | mode,0); } #endif net/ipsvd-1.0.0/src/fifo.h0000644000000000000000000000014511025276022014001 0ustar rootroot/* Public domain. */ #ifndef FIFO_H #define FIFO_H extern int fifo_make(const char *,int); #endif net/ipsvd-1.0.0/src/find-systype.sh0000644000000000000000000000640411025276022015703 0ustar rootroot# oper-:arch-:syst-:chip-:kern- # oper = operating system type; e.g., sunos-4.1.4 # arch = machine language; e.g., sparc # syst = which binaries can run; e.g., sun4 # chip = chip model; e.g., micro-2-80 # kern = kernel version; e.g., sun4m # dependence: arch --- chip # \ \ # oper --- syst --- kern # so, for example, syst is interpreted in light of oper, but chip is not. # anyway, no slashes, no extra colons, no uppercase letters. # the point of the extra -'s is to ease parsing: can add hierarchies later. # e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, # and i386-486 (486s do have more instructions, you know) as well as i386. # the idea here is to include ALL useful available information. exec 2>/dev/null sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" if [ x"$sys" != x ] then unamer="`uname -r | tr /: ..`" unamem="`uname -m | tr /: ..`" unamev="`uname -v | tr /: ..`" case "$sys" in bsd.os|freebsd|netbsd|openbsd) # in bsd 4.4, uname -v does not have useful info. # in bsd 4.4, uname -m is arch, not chip. oper="$sys-$unamer" arch="$unamem" syst="" chip="`sysctl -n hw.model`" # hopefully kern="" ;; linux) # as in bsd 4.4, uname -v does not have useful info. oper="$sys-$unamer" syst="" chip="$unamem" kern="" case "$chip" in i386|i486|i586|i686) arch="i386" ;; alpha) arch="alpha" ;; esac ;; aix) # naturally IBM has to get uname -r and uname -v backwards. dorks. oper="$sys-$unamev-$unamer" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; sunos) oper="$sys-$unamer-$unamev" arch="`(uname -p || mach) | tr /: ..`" syst="`arch | tr /: ..`" chip="$unamem" # this is wrong; is there any way to get the real info? kern="`arch -k | tr /: ..`" ;; unix_sv) oper="$sys-$unamer-$unamev" arch="`uname -m`" syst="" chip="$unamem" kern="" ;; *) oper="$sys-$unamer-$unamev" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; esac else gcc -c trycpp.c gcc -o trycpp trycpp.o case `./trycpp` in nextstep) oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" syst="" chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" kern="" ;; *) oper="unknown" arch="" syst="" chip="" kern="" ;; esac rm -f trycpp.o trycpp fi case "$chip" in 80486) # let's try to be consistent here. (BSD/OS) chip=i486 ;; i486DX) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx ;; i486.DX2) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx2 ;; Intel.586) # no, you nitwits, there is no such chip. (NeXTStep) chip=pentium ;; i586) # no, you nitwits, there is no such chip. (Linux) chip=pentium ;; i686) # STOP SAYING THAT! (Linux) chip=ppro esac if gcc -c x86cpuid.c then if gcc -o x86cpuid x86cpuid.o then x86cpuid="`./x86cpuid | tr /: ..`" case "$x86cpuid" in ?*) chip="$x86cpuid" ;; esac fi fi rm -f x86cpuid x86cpuid.o echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' net/ipsvd-1.0.0/src/fmt.h0000644000000000000000000000212411025276022013643 0ustar rootroot/* Public domain. */ #ifndef FMT_H #define FMT_H #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ #define FMT_LEN ((char *) 0) /* convenient abbreviation */ extern unsigned int fmt_uint(char *,unsigned int); extern unsigned int fmt_uint0(char *,unsigned int,unsigned int); extern unsigned int fmt_xint(char *,unsigned int); extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int); extern unsigned int fmt_ushort(char *,unsigned short); extern unsigned int fmt_xshort(char *,unsigned short); extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short); extern unsigned int fmt_ulong(char *,unsigned long); extern unsigned int fmt_xlong(char *,unsigned long); extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long); extern unsigned int fmt_plusminus(char *,int); extern unsigned int fmt_minus(char *,int); extern unsigned int fmt_0x(char *,int); extern unsigned int fmt_str(char *,const char *); extern unsigned int fmt_strn(char *,const char *,unsigned int); #endif net/ipsvd-1.0.0/src/fmt_uint.c0000644000000000000000000000020511025276022014673 0ustar rootroot/* Public domain. */ #include "fmt.h" unsigned int fmt_uint(register char *s,register unsigned int u) { return fmt_ulong(s,u); } net/ipsvd-1.0.0/src/fmt_uint0.c0000644000000000000000000000036111025276022014756 0ustar rootroot/* Public domain. */ #include "fmt.h" unsigned int fmt_uint0(char *s,unsigned int u,unsigned int n) { unsigned int len; len = fmt_uint(FMT_LEN,u); while (len < n) { if (s) *s++ = '0'; ++len; } if (s) fmt_uint(s,u); return len; } net/ipsvd-1.0.0/src/fmt_ulong.c0000644000000000000000000000052011025276022015040 0ustar rootroot/* Public domain. */ #include "fmt.h" unsigned int fmt_ulong(register char *s,register unsigned long u) { register unsigned int len; register unsigned long q; len = 1; q = u; while (q > 9) { ++len; q /= 10; } if (s) { s += len; do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ } return len; } net/ipsvd-1.0.0/src/gen_alloc.h0000644000000000000000000000030311025276022014775 0ustar rootroot/* Public domain. */ #ifndef GEN_ALLOC_H #define GEN_ALLOC_H #define GEN_ALLOC_typedef(ta,type,field,len,a) \ typedef struct ta { type *field; unsigned int len; unsigned int a; } ta; #endif net/ipsvd-1.0.0/src/gen_allocdefs.h0000644000000000000000000000227411025276022015650 0ustar rootroot/* Public domain. */ #ifndef GEN_ALLOC_DEFS_H #define GEN_ALLOC_DEFS_H #define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ int ta_ready(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \ int ta_rplus(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; n += x->len; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \ int ta_append(register ta *x,register const type *i) \ { if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } #endif net/ipsvd-1.0.0/src/hasflock.h10000644000000000000000000000005311025276022014727 0ustar rootroot/* Public domain. */ /* sysdep: -flock */ net/ipsvd-1.0.0/src/hasflock.h20000644000000000000000000000007611025276022014735 0ustar rootroot/* Public domain. */ /* sysdep: +flock */ #define HASFLOCK 1 net/ipsvd-1.0.0/src/hasmkffo.h10000644000000000000000000000005411025276022014734 0ustar rootroot/* Public domain. */ /* sysdep: -mkfifo */ net/ipsvd-1.0.0/src/hasmkffo.h20000644000000000000000000000010011025276022014725 0ustar rootroot/* Public domain. */ /* sysdep: +mkfifo */ #define HASMKFIFO 1 net/ipsvd-1.0.0/src/hassgact.h10000644000000000000000000000005711025276022014736 0ustar rootroot/* Public domain. */ /* sysdep: -sigaction */ net/ipsvd-1.0.0/src/hassgact.h20000644000000000000000000000010611025276022014732 0ustar rootroot/* Public domain. */ /* sysdep: +sigaction */ #define HASSIGACTION 1 net/ipsvd-1.0.0/src/hassgprm.h10000644000000000000000000000006111025276022014760 0ustar rootroot/* Public domain. */ /* sysdep: -sigprocmask */ net/ipsvd-1.0.0/src/hassgprm.h20000644000000000000000000000011211025276022014756 0ustar rootroot/* Public domain. */ /* sysdep: +sigprocmask */ #define HASSIGPROCMASK 1 net/ipsvd-1.0.0/src/hasshsgr.h10000644000000000000000000000006411025276022014761 0ustar rootroot/* Public domain. */ /* sysdep: -shortsetgroups */ net/ipsvd-1.0.0/src/hasshsgr.h20000644000000000000000000000012011025276022014753 0ustar rootroot/* Public domain. */ /* sysdep: +shortsetgroups */ #define HASSHORTSETGROUPS 1 net/ipsvd-1.0.0/src/haswaitp.h10000644000000000000000000000005511025276022014757 0ustar rootroot/* Public domain. */ /* sysdep: -waitpid */ net/ipsvd-1.0.0/src/haswaitp.h20000644000000000000000000000010211025276022014751 0ustar rootroot/* Public domain. */ /* sysdep: +waitpid */ #define HASWAITPID 1 net/ipsvd-1.0.0/src/iopause.c0000644000000000000000000000321411025276022014516 0ustar rootroot/* Public domain. */ #include "taia.h" #include "select.h" #include "iopause.h" void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp) { struct taia t; int millisecs; double d; int i; if (taia_less(deadline,stamp)) millisecs = 0; else { t = *stamp; taia_sub(&t,deadline,&t); d = taia_approx(&t); if (d > 1000.0) d = 1000.0; millisecs = d * 1000.0 + 20.0; } for (i = 0;i < len;++i) x[i].revents = 0; #ifdef IOPAUSE_POLL poll(x,len,millisecs); /* XXX: some kernels apparently need x[0] even if len is 0 */ /* XXX: how to handle EAGAIN? are kernels really this dumb? */ /* XXX: how to handle EINVAL? when exactly can this happen? */ #else { struct timeval tv; fd_set rfds; fd_set wfds; int nfds; int fd; FD_ZERO(&rfds); FD_ZERO(&wfds); nfds = 1; for (i = 0;i < len;++i) { fd = x[i].fd; if (fd < 0) continue; if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ if (fd >= nfds) nfds = fd + 1; if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds); if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds); } tv.tv_sec = millisecs / 1000; tv.tv_usec = 1000 * (millisecs % 1000); if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0) return; /* XXX: for EBADF, could seek out and destroy the bad descriptor */ for (i = 0;i < len;++i) { fd = x[i].fd; if (fd < 0) continue; if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ if (x[i].events & IOPAUSE_READ) if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ; if (x[i].events & IOPAUSE_WRITE) if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE; } } #endif } net/ipsvd-1.0.0/src/iopause.h10000644000000000000000000000046211025276022014606 0ustar rootroot/* Public domain. */ #ifndef IOPAUSE_H #define IOPAUSE_H /* sysdep: -poll */ typedef struct { int fd; short events; short revents; } iopause_fd; #define IOPAUSE_READ 1 #define IOPAUSE_WRITE 4 #include "taia.h" extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); #endif net/ipsvd-1.0.0/src/iopause.h20000644000000000000000000000052311025276022014605 0ustar rootroot/* Public domain. */ #ifndef IOPAUSE_H #define IOPAUSE_H /* sysdep: +poll */ #define IOPAUSE_POLL #include #include typedef struct pollfd iopause_fd; #define IOPAUSE_READ POLLIN #define IOPAUSE_WRITE POLLOUT #include "taia.h" extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); #endif net/ipsvd-1.0.0/src/ip4.h0000644000000000000000000000023611025276022013553 0ustar rootroot#ifndef IP4_H #define IP4_H extern unsigned int ip4_scan(const char *,char *); extern unsigned int ip4_fmt(char *,const char *); #define IP4_FMT 20 #endif net/ipsvd-1.0.0/src/ip4_scan.c0000644000000000000000000000107511025276022014554 0ustar rootroot#include "scan.h" #include "ip4.h" unsigned int ip4_scan(const char *s,char ip[4]) { unsigned int i; unsigned int len; unsigned long u; len = 0; i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i; return len; } net/ipsvd-1.0.0/src/ipsvd-cdb.c0000644000000000000000000000631411025276022014730 0ustar rootroot#include #include #include #include #include #include "ipsvd_check.h" #include "sgetopt.h" #include "error.h" #include "open.h" #include "lock.h" #include "strerr.h" #include "stralloc.h" #include "direntry.h" #include "cdb.h" #include "cdb_make.h" #include "str.h" #define USAGE " cdb cdb.tmp dir" #define VERSION "$Id: 940f83f1189944815f693d2f54ee1616b3f85763 $" #define FATAL "ipsvd-cdb: fatal: " #define WARNING "ipsvd-cdb: warning: " const char *progname; char *instdir; char *cdbfn; char *tmpfn; struct cdb_make c; struct cdb cdb; int fdcdb; int fdtmp; static stralloc sa ={0}; static stralloc tmp ={0}; void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); } void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); } void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); } void fatal2(char *m0, char *m1) { strerr_die5sys(111, FATAL, m0, ": ", m1, ": "); } void warn(char *m0, char *m1) { strerr_warn4(WARNING, m0, ": ", m1, 0); } int main(int argc, char **argv) { int mydir; DIR *dir; direntry *d; struct stat s; int ac; int i; progname =*argv++; if (! argv || ! *argv) usage(); cdbfn =*argv++; if (! argv || ! *argv) usage(); tmpfn =*argv++; if (! argv || ! *argv) usage(); instdir =*argv; if ((mydir =open_read(".")) == -1) fatal("unable to open current directory"); /* open cdb.tmp */ if ((fdtmp =open_trunc(tmpfn)) == -1) fatal2("unable to create", tmpfn); if (cdb_make_start(&c, fdtmp) == -1) fatal2("unable to create", tmpfn); if (chdir(instdir) == -1) fatal2("unable to change dir", instdir); if (! (dir =opendir("."))) fatal2("unable to open dir", instdir); errno =0; while ((d =readdir(dir))) { if (d->d_name[0] == '.') { if (d->d_name[1] == 0) continue; if (d->d_name[1] == '.') continue; } if (stat(d->d_name, &s) == -1) { warn("unable to stat", d->d_name); errno =0; continue; } sa.len =0; ac =ipsvd_check(0, &sa, &tmp, ".", 0, d->d_name, 0); if (ac == -1) fatal2("unable to read instruction", d->d_name); if (ac == IPSVD_ERR) fatal2("unable to read", "."); /* impossible? */ switch(ac) { case IPSVD_EXEC: sa.s[sa.len -1] ='X'; if (cdb_make_add(&c, d->d_name, str_len(d->d_name), sa.s, sa.len) == -1) fatal2("unable to add entry", instdir); continue; case IPSVD_DENY: if (! sa.len) { if (cdb_make_add(&c, d->d_name, str_len(d->d_name), "D", 1) == -1) fatal2("unable to add entry", instdir); continue; } case IPSVD_INSTRUCT: for (i =0; i < sa.len; i++) if (sa.s[i] == '\n') sa.s[i] =0; sa.s[sa.len -1] ='I'; if (cdb_make_add(&c, d->d_name, str_len(d->d_name), sa.s, sa.len) == -1) fatal2("unable to add entry", instdir); continue; } warn("ignore", d->d_name); } /* catch errno? */ closedir(dir); if (cdb_make_finish(&c) == -1) fatal2("unable to write cdb", tmpfn); if (fsync(fdtmp) == -1) fatal2("unable to write cdb", tmpfn); close(fdtmp); if (fchdir(mydir) == -1) fatal("unable to change to previous directory"); close(mydir); if (rename(tmpfn, cdbfn) == -1) fatal2("unable to replace", cdbfn); _exit(0); } net/ipsvd-1.0.0/src/ipsvd-cdb.check0000755000000000000000000000112311025276022015557 0ustar rootroot#!/bin/sh rm -rf "${ctmp}" ipsvd-cdb echo $? mkdir "${ctmp}" echo >"${ctmp}"/0 chmod 0 "${ctmp}"/0 echo '+foo=bar' >"${ctmp}"/10.0.0.1 chmod 600 "${ctmp}"/10.0.0.1 echo '+foo=bar' >"${ctmp}"/10.14.1 echo 'C14:foobar' >>"${ctmp}"/10.14.1 chmod 600 "${ctmp}"/10.14.1 echo '+foo=' >"${ctmp}"/127 echo '+bar' >>"${ctmp}"/127 echo '=localhost:10.14.1' >>"${ctmp}"/127 chmod 600 "${ctmp}"/127 echo 'exec env' >"${ctmp}"/192.168 chmod 700 "${ctmp}"/192.168 ipsvd-cdb "${ctmp}".cdb "${ctmp}".cdb.tmp "${ctmp}" echo $? check-ipsvd-cdb <"${ctmp}".cdb |sort echo $? rm -f "${ctmp}".cdb rm -rf "${ctmp}" net/ipsvd-1.0.0/src/ipsvd-cdb.dist0000644000000000000000000000022611025276022015445 0ustar rootrootusage: ipsvd-cdb cdb cdb.tmp dir 111 0 0:D 10.0.0.1:+foo=barI 10.14.1:+foo=bar^@C14:foobarI 127:+foo=^@+bar^@=localhost:10.14.1I 192.168:exec envX 0 net/ipsvd-1.0.0/src/ipsvd_check.c0000644000000000000000000002417411025276022015343 0ustar rootroot#include #include #include #include #include "ipsvd_check.h" #include "ipsvd_log.h" #include "ipsvd_fmt.h" #include "error.h" #include "stralloc.h" #include "strerr.h" #include "byte.h" #include "scan.h" #include "str.h" #include "openreadclose.h" #include "open.h" #include "cdb.h" #include "pathexec.h" #include "dns.h" #include "ip4.h" extern const char *progname; static stralloc sa ={0}; static stralloc ips ={0}; static stralloc fqdn ={0}; static stralloc msg ={0}; static stralloc forwardfn ={0}; static stralloc moredata ={0}; static char *forward =0; unsigned long phccmax; char *phccmsg; static struct cdb c; static int fd; static uint32 dlen; int ipsvd_instruct(stralloc *inst, stralloc *match, char *ip) { char *insts; unsigned int instslen; int delim; int i, j; int rc =IPSVD_DEFAULT; if (inst->s && inst->len) { insts =inst->s; instslen =inst->len; while ((i =byte_chr(insts, instslen, 0)) < instslen) { switch(*insts) { case '+': if ((delim =str_chr(insts, '=')) <= 1) break; /* empty inst */ if (insts[delim] == '=') { insts[delim] =0; if (! pathexec_env(insts +1, insts +delim +1)) return(-1); insts[delim] ='='; } else if (! pathexec_env(insts +1, 0)) return(-1); break; case 'C': if (! phccmax) break; delim =scan_ulong(insts +1, &phccmax); if (insts[delim +1] == ':') { if (ipsvd_fmt_msg(&msg, insts +delim +2) == -1) return(-1); if (! stralloc_0(&msg)) return(-1); phccmsg =msg.s; } break; case '=': if (ip && (rc != IPSVD_INSTRUCT)) { unsigned int next; rc =IPSVD_DENY; next =str_chr(insts +1, ':'); ++next; if ((next == 2) && (insts[1] == '0')) { if (! stralloc_copys(&sa, ip)) return(-1); } else if (! stralloc_copyb(&sa, insts +1, next -1)) return(-1); if (insts[next] != 0) ++next; if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4)) if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1) { if (! stralloc_0(&sa)) return(-1); strerr_warn5(progname, ": warning: ", "unable to look up ip address: ", sa.s, ": ", &strerr_sys); break; } if (ips.len < 4) { if (! stralloc_0(&sa)) return(-1); strerr_warn4(progname, ": warning: ", "unable to look up ip address: ", sa.s, 0); break; } for (j =0; j +4 <= ips.len; j +=4) { char tmp[IP4_FMT]; tmp[ipsvd_fmt_ip(tmp, ips.s +j)] =0; if (str_equal(tmp, ip)) { inst->len =insts -inst->s +i +1; if (insts[next]) { forward =insts +next; return(IPSVD_FORWARD); } return(IPSVD_INSTRUCT); } } } break; case 0: case '#': /* skip empty line and comment */ break; default: strerr_warn6(progname, ": warning: ", "bad instruction: ", match->s, ": ", insts, 0); } insts +=i +1; instslen -=i +1; } } if (rc == IPSVD_DEFAULT) return(IPSVD_INSTRUCT); return(rc); } int ipsvd_check_direntry(stralloc *d, stralloc *m, char *ip, time_t now, unsigned long t, int *rc) { int i; struct stat s; if (stat(m->s, &s) != -1) { if (t && (s.st_mode & S_IWUSR) && (now >= s.st_atime)) if ((now -s.st_atime) >= t) { if (unlink(m->s) == -1) strerr_warn4(progname, ": warning: unable to unlink: ", m->s, ": ", &strerr_sys); return(0); } if (! (s.st_mode & S_IXUSR) && ! (s.st_mode & S_IRUSR)) { *rc =IPSVD_DENY; return(1); } if (s.st_mode & S_IXUSR) { if (openreadclose(m->s, d, 256) <= 0) return(-1); if (d->len && (d->s[d->len -1] == '\n')) d->len--; if (! stralloc_0(d)) return(-1); *rc =IPSVD_EXEC; return(1); } if (s.st_mode & S_IRUSR) { if (openreadclose(m->s, d, 256) <= 0) return(-1); if (d->len && (d->s[d->len -1] == '\n')) d->len--; for (i =0; i < d->len; i++) if (d->s[i] == '\n') d->s[i] =0; if (! stralloc_0(d)) return(-1); if ((*rc =ipsvd_instruct(d, m, ip)) == -1) return(-1); return(1); } if (! stralloc_copys(m, "")) return(-1); if (! stralloc_0(m)) return(-1); *rc =IPSVD_DEFAULT; return(1); } else if (errno != error_noent) return(-1); return(0); } int ipsvd_check_dir(stralloc *data, stralloc *match, char *dir, char *ip, char *name, unsigned long timeout) { struct stat s; int i; int rc; int ok; int base; time_t now =0; if (stat(dir, &s) == -1) return(IPSVD_ERR); if (timeout) now =time((time_t*)0); if (! stralloc_copys(match, dir)) return(-1); if (! stralloc_cats(match, "/")) return(-1); base =match->len; /* ip */ if (ip) { if (! stralloc_cats(match, ip)) return(-1); if (! stralloc_0(match)) return(-1); data->len =0; for (;;) { ok =ipsvd_check_direntry(data, match, ip, now, timeout, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; return(rc); } if ((i =byte_rchr(match->s, match->len, '.')) == match->len) break; if (i <= base) break; match->s[i] =0; match->len =i +1; } } /* host */ if (name) { for (;;) { if (! *name || (*name == '.')) break; match->len =base; if (! stralloc_cats(match, name)) return(-1); if (! stralloc_0(match)) return(-1); ok =ipsvd_check_direntry(data, match, ip, now, timeout, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; return(rc); } if ((i =byte_chr(name, str_len(name), '.')) == str_len(name)) break; name +=i +1; } } /* default */ match->len =base; if (! stralloc_cats(match, "0")) return(-1); if (! stralloc_0(match)) return(-1); ok =ipsvd_check_direntry(data, match, ip, now, timeout, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; return(rc); } if (! stralloc_copys(match, "")) return(-1); if (! stralloc_0(match)) return(-1); return(IPSVD_DEFAULT); forwarded: if (! stralloc_copyb(&forwardfn, match->s, base)) return(-1); if (! stralloc_cats(&forwardfn, forward)) return(-1); if (! stralloc_0(&forwardfn)) return(-1); ok =ipsvd_check_direntry(&moredata, &forwardfn, 0, now, timeout, &rc); if (ok == -1) return(-1); --match->len; if (! stralloc_cats(match, ",")) return(-1); if (! stralloc_cats(match, forwardfn.s +base)) return(-1); if (! stralloc_0(match)) return(-1); if (ok) { if (rc == IPSVD_EXEC) data->len =0; else data->s[data->len -1] =','; if (! stralloc_cat(data, &moredata)) return(-1); return(rc); } strerr_warn4(progname, ": warning: ", match->s, ": not found", 0); return(IPSVD_DENY); } int ipsvd_check_cdbentry(stralloc *d, stralloc *m, char *ip, int *rc) { switch(cdb_find(&c, m->s, m->len -1)) { case -1: return(-1); case 1: dlen =cdb_datalen(&c); if (! stralloc_ready(d, dlen)) return(-1); if (cdb_read(&c, d->s, dlen, cdb_datapos(&c)) == -1) return(-1); if (! dlen) return(-1); switch(d->s[dlen -1]) { case 'D': *rc =IPSVD_DENY; return(1); case 'X': d->s[dlen -1] =0; d->len =dlen; *rc =IPSVD_EXEC; return(1); case 'I': d->s[dlen -1] =0; d->len =dlen; if ((*rc =ipsvd_instruct(d, m, ip)) == -1) return(-1); return(1); } } return(0); } int ipsvd_check_cdb(stralloc *data, stralloc *match, char *cdb, char *ip, char *name, unsigned long unused) { int ok; int i; int rc; if ((fd =open_read(cdb)) == -1) return(IPSVD_ERR); cdb_init(&c, fd); if (! stralloc_copys(match, ip)) return(-1); if (! stralloc_0(match)) return(-1); data->len =0; /* ip */ for (;;) { ok =ipsvd_check_cdbentry(data, match, ip, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; close(fd); return(rc); } if ((i =byte_rchr(match->s, match->len, '.')) == match->len) break; match->s[i] =0; match->len =i +1; } /* host */ if (name) { for (;;) { if (! *name || (*name == '.')) break; if (! stralloc_copys(match, name)) return(-1); if (! stralloc_0(match)) return(-1); ok =ipsvd_check_cdbentry(data, match, ip, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; close(fd); return(rc); } if ((i =byte_chr(name, str_len(name), '.')) == str_len(name)) break; name +=i +1; } } /* default */ if (! stralloc_copys(match, "0")) return(-1); if (! stralloc_0(match)) return(-1); ok =ipsvd_check_cdbentry(data, match, ip, &rc); if (ok == -1) return(-1); if (ok) { if (rc == IPSVD_FORWARD) goto forwarded; close(fd); return(rc); } if (! stralloc_copys(match, "")) return(-1); if (! stralloc_0(match)) return(-1); close(fd); return(IPSVD_DEFAULT); forwarded: if (! stralloc_copys(&forwardfn, forward)) return(-1); if (! stralloc_0(&forwardfn)) return(-1); ok =ipsvd_check_cdbentry(&moredata, &forwardfn, 0, &rc); close(fd); if (ok == -1) return(-1); --match->len; if (! stralloc_cats(match, ",")) return(-1); if (! stralloc_cats(match, forwardfn.s)) return(-1); if (! stralloc_0(match)) return(-1); if (ok) { if (rc == IPSVD_EXEC) data->len =0; else data->s[data->len -1] =','; if (! stralloc_cat(data, &moredata)) return(-1); return(rc); } strerr_warn4(progname, ": warning: ", match->s, ": not found", 0); return(IPSVD_DENY); } int ipsvd_check(int c, stralloc *data, stralloc *match, char *db, char *ip, char *name, unsigned long timeout) { if (c) return(ipsvd_check_cdb(data, match, db, ip, name, 0)); else return(ipsvd_check_dir(data, match, db, ip, name, timeout)); } net/ipsvd-1.0.0/src/ipsvd_check.h0000644000000000000000000000057411025276022015346 0ustar rootroot#ifndef IPSVD_CHECK_H #define IPSVD_CHECK_H #include "stralloc.h" extern unsigned long phccmax; extern char *phccmsg; #define IPSVD_ERR 0 #define IPSVD_DENY 1 #define IPSVD_DEFAULT 2 #define IPSVD_INSTRUCT 3 #define IPSVD_EXEC 4 #define IPSVD_FORWARD 5 extern int ipsvd_check(int, stralloc *, stralloc *, char *, char *, char *, unsigned long); #endif net/ipsvd-1.0.0/src/ipsvd_fmt.c0000644000000000000000000000246211025276022015050 0ustar rootroot#include "fmt.h" #include "stralloc.h" #include "str.h" unsigned int ipsvd_fmt_ip(char *s, char ip[4]) { char *p =s; int i; i =fmt_ulong(p, (unsigned long)(unsigned char)ip[0]); if (p) p +=i; if (p) *p++ ='.'; i =fmt_ulong(p, (unsigned long)(unsigned char)ip[1]); if (p) p +=i; if (p) *p++ ='.'; i =fmt_ulong(p, (unsigned long)(unsigned char)ip[2]); if (p) p +=i; if (p) *p++ ='.'; i =fmt_ulong(p, (unsigned long)(unsigned char)ip[3]); if (p) p +=i; return(p -s); } unsigned int ipsvd_fmt_port(char *s, char port[2]) { unsigned short u; u =(unsigned char)port[0]; u <<=8; u +=(unsigned char)port[1]; return(fmt_ulong(s, (unsigned long)u)); } int ipsvd_fmt_msg(stralloc *sa, const char *msg) { const char *p; int i; if (! msg) return(0); if (! stralloc_copys(sa, "")) return(-1); for (p =msg; *p; ++p) { i =str_chr(p, '\\'); if (! stralloc_catb(sa, p, i)) return(-1); if (*(p +=i) == 0) break; switch(*++p) { case 0: break; case '\\': if (! stralloc_append(sa, "\\")) return(-1); continue; case 'n': if (! stralloc_append(sa, "\n")) return(-1); continue; case 'r': if (! stralloc_append(sa, "\r")) return(-1); continue; default: if (! stralloc_catb(sa, p -1, 2)) return(-1); } } return(sa->len); } net/ipsvd-1.0.0/src/ipsvd_fmt.h0000644000000000000000000000033511025276022015052 0ustar rootroot#ifndef IPSVD_FMT_H #define IPSVD_FMT_H extern unsigned int ipsvd_fmt_ip(char *s, char ip[4]); extern unsigned int ipsvd_fmt_port(char *s, char port[2]); extern int ipsvd_fmt_msg(stralloc *sa, const char *msg); #endif net/ipsvd-1.0.0/src/ipsvd_hostname.c0000644000000000000000000000077111025276022016101 0ustar rootroot#include "ipsvd_hostname.h" #include "byte.h" static stralloc sa; int ipsvd_hostname(stralloc *host, char *ip, unsigned int paranoid) { int i; if (dns_name4(host, ip) == -1) { host->len =0; return(-1); } if (host->len && paranoid) { if (dns_ip4(&sa, host) == -1) { host->len =0; return(-1); } for (i =0; i +4 <= sa.len; i +=4) if (byte_equal(ip, 4, sa.s +i)) { paranoid =0; break; } if (paranoid) host->len =0; } return(0); } net/ipsvd-1.0.0/src/ipsvd_hostname.h0000644000000000000000000000012711025276022016101 0ustar rootroot#include "dns.h" int ipsvd_hostname(stralloc *host, char *ip, unsigned int paranoid); net/ipsvd-1.0.0/src/ipsvd_log.c0000644000000000000000000000146711025276022015047 0ustar rootroot#include "buffer.h" #include "ipsvd_log.h" void out(char *m) { buffer_puts(buffer_1, m); } void outfix(char *m) { char ch; int i; if (! m) return; for (i =0; i < 100; ++i) { ch =m[i]; if (!ch) return; if (ch < 33) ch ='?'; else if (ch > 126) ch ='?'; else if (ch == ':') ch ='?'; buffer_put(buffer_1, &ch, 1); } out("...(truncate)"); } void outinst(stralloc *sa) { char ch; int len, i; if (! sa->s || ! sa->len) return; for (len =sa->len; len && (sa->s[len -1] == 0); --len); for (i =0; i < 140; ++i) { if (i >= len) return; ch =sa->s[i]; if (ch == 0) ch =','; else if (ch < 32) ch ='?'; else if (ch > 126) ch ='?'; buffer_put(buffer_1, &ch, 1); } out("...(truncate)"); } void flush(char *m) { buffer_puts(buffer_1, m); buffer_flush(buffer_1); } net/ipsvd-1.0.0/src/ipsvd_log.h0000644000000000000000000000027111025276022015044 0ustar rootroot#ifndef IPSVD_LOG_H #define IPSVD_LOG_H #include "stralloc.h" extern void out(char *); extern void outfix(char *); extern void outinst(stralloc *); extern void flush(char *); #endif net/ipsvd-1.0.0/src/ipsvd_phcc.c0000644000000000000000000000215211025276022015173 0ustar rootroot#include "alloc.h" #include "byte.h" struct hcc { char ip[4]; int pid; }; static struct hcc *cc; static unsigned int cclen; static int pos =-1; unsigned int i; /* to be optimized */ int ipsvd_phcc_init(unsigned int c) { if (cc) alloc_free(cc); cc =(struct hcc*)alloc(c *sizeof(struct hcc)); if (! cc) return(-1); for (i =0; i < c; ++i) { cc[i].ip[0] =0; cc[i].pid =0; } cclen =c; return(0); } unsigned int ipsvd_phcc_add(char *ip) { unsigned int rc =1; int p =-1; for (i =0; i < cclen; ++i) { if (cc[i].ip[0] == 0) { if (p == -1) p =i; continue; } if (byte_equal(cc[i].ip, 4, ip)) { ++rc; continue; } } if ((pos =p) == -1) return(0); /* impossible */ byte_copy(cc[pos].ip, 4, ip); return(rc); } unsigned int ipsvd_phcc_setpid(int pid) { if (pos == -1) return(0); /* should never happen */ cc[pos].pid =pid; return(1); } int ipsvd_phcc_rem(int pid) { for (i =0; i < cclen; ++i) if (cc[i].pid == pid) { cc[i].ip[0] =0; cc[i].pid =0; return(0); } return(-1); } void ipsvd_phcc_free(void) { if (cc) alloc_free(cc); } net/ipsvd-1.0.0/src/ipsvd_phcc.h0000644000000000000000000000025411025276022015201 0ustar rootrootint ipsvd_phcc_init(unsigned int); unsigned int ipsvd_phcc_add(char *ip); unsigned int ipsvd_phcc_setpid(int pid); int ipsvd_phcc_rem(int pid); void ipsvd_phcc_free(void); net/ipsvd-1.0.0/src/ipsvd_scan.c0000644000000000000000000000065511025276022015210 0ustar rootroot#include #include #include #include "scan.h" unsigned int ipsvd_scan_port(const char *s, const char *proto, unsigned long *p) { struct servent *se; if (! *s) return(0); if ((se =getservbyname(s, proto))) { /* what is se->s_port, uint16 or uint32? */ *p =htons(se->s_port); return(1); } if (s[scan_ulong(s, p)]) return(0); return(1); } net/ipsvd-1.0.0/src/ipsvd_scan.h0000644000000000000000000000026011025276022015205 0ustar rootroot#ifndef IPSVD_SCAN_H #define IPSVD_SCAN_H extern unsigned int ipsvd_scan_port(const char *s, const char *proto, unsigned long *p); #endif net/ipsvd-1.0.0/src/lock.h0000644000000000000000000000021211025276022014001 0ustar rootroot/* Public domain. */ #ifndef LOCK_H #define LOCK_H extern int lock_ex(int); extern int lock_un(int); extern int lock_exnb(int); #endif net/ipsvd-1.0.0/src/lock_ex.c0000644000000000000000000000037411025276022014501 0ustar rootroot/* Public domain. */ #include #include #include #include "hasflock.h" #include "lock.h" #ifdef HASFLOCK int lock_ex(int fd) { return flock(fd,LOCK_EX); } #else int lock_ex(int fd) { return lockf(fd,1,0); } #endif net/ipsvd-1.0.0/src/lock_exnb.c0000644000000000000000000000041211025276022015012 0ustar rootroot/* Public domain. */ #include #include #include #include "hasflock.h" #include "lock.h" #ifdef HASFLOCK int lock_exnb(int fd) { return flock(fd,LOCK_EX | LOCK_NB); } #else int lock_exnb(int fd) { return lockf(fd,2,0); } #endif net/ipsvd-1.0.0/src/ndelay.h0000644000000000000000000000017011025276022014330 0ustar rootroot/* Public domain. */ #ifndef NDELAY_H #define NDELAY_H extern int ndelay_on(int); extern int ndelay_off(int); #endif net/ipsvd-1.0.0/src/ndelay_off.c0000644000000000000000000000034511025276022015161 0ustar rootroot/* Public domain. */ #include #include #include "ndelay.h" #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif int ndelay_off(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK); } net/ipsvd-1.0.0/src/ndelay_on.c0000644000000000000000000000034311025276022015021 0ustar rootroot/* Public domain. */ #include #include #include "ndelay.h" #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif int ndelay_on(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK); } net/ipsvd-1.0.0/src/open.h0000644000000000000000000000036511025276022014023 0ustar rootroot/* Public domain. */ #ifndef OPEN_H #define OPEN_H extern int open_read(const char *); extern int open_excl(const char *); extern int open_append(const char *); extern int open_trunc(const char *); extern int open_write(const char *); #endif net/ipsvd-1.0.0/src/open_append.c0000644000000000000000000000026611025276022015345 0ustar rootroot/* Public domain. */ #include #include #include "open.h" int open_append(const char *fn) { return open(fn,O_WRONLY | O_NDELAY | O_APPEND | O_CREAT,0600); } net/ipsvd-1.0.0/src/open_read.c0000644000000000000000000000023211025276022015002 0ustar rootroot/* Public domain. */ #include #include #include "open.h" int open_read(const char *fn) { return open(fn,O_RDONLY | O_NDELAY); } net/ipsvd-1.0.0/src/open_trunc.c0000644000000000000000000000026411025276022015227 0ustar rootroot/* Public domain. */ #include #include #include "open.h" int open_trunc(const char *fn) { return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } net/ipsvd-1.0.0/src/open_write.c0000644000000000000000000000023311025276022015222 0ustar rootroot/* Public domain. */ #include #include #include "open.h" int open_write(const char *fn) { return open(fn,O_WRONLY | O_NDELAY); } net/ipsvd-1.0.0/src/openreadclose.c0000644000000000000000000000054011025276022015673 0ustar rootroot/* Public domain. */ #include "error.h" #include "open.h" #include "readclose.h" #include "openreadclose.h" int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize) { int fd; fd = open_read(fn); if (fd == -1) { if (errno == error_noent) return 0; return -1; } if (readclose(fd,sa,bufsize) == -1) return -1; return 1; } net/ipsvd-1.0.0/src/openreadclose.h0000644000000000000000000000024611025276022015703 0ustar rootroot/* Public domain. */ #ifndef OPENREADCLOSE_H #define OPENREADCLOSE_H #include "stralloc.h" extern int openreadclose(const char *,stralloc *,unsigned int); #endif net/ipsvd-1.0.0/src/pathexec.h0000644000000000000000000000036711025276022014665 0ustar rootroot/* Public domain. */ #ifndef PATHEXEC_H #define PATHEXEC_H extern void pathexec_run(const char *,const char * const *,const char * const *); extern int pathexec_env(const char *,const char *); extern void pathexec(const char * const *); #endif net/ipsvd-1.0.0/src/pathexec_env.c0000644000000000000000000000253411025276022015526 0ustar rootroot/* Public domain. */ #include "stralloc.h" #include "alloc.h" #include "str.h" #include "byte.h" #include "env.h" #include "pathexec.h" static stralloc plus; static stralloc tmp; int pathexec_env(const char *s,const char *t) { if (!s) return 1; if (!stralloc_copys(&tmp,s)) return 0; if (t) { if (!stralloc_cats(&tmp,"=")) return 0; if (!stralloc_cats(&tmp,t)) return 0; } if (!stralloc_0(&tmp)) return 0; return stralloc_cat(&plus,&tmp); } void pathexec(const char *const *argv) { const char **e; unsigned int elen; unsigned int i; unsigned int j; unsigned int split; unsigned int t; if (!stralloc_cats(&plus,"")) return; elen = 0; for (i = 0;environ[i];++i) ++elen; for (i = 0;i < plus.len;++i) if (!plus.s[i]) ++elen; e = (const char **) alloc((elen + 1) * sizeof(char *)); if (!e) return; elen = 0; for (i = 0;environ[i];++i) e[elen++] = environ[i]; j = 0; for (i = 0;i < plus.len;++i) if (!plus.s[i]) { split = str_chr(plus.s + j,'='); for (t = 0;t < elen;++t) if (byte_equal(plus.s + j,split,e[t])) if (e[t][split] == '=') { --elen; e[t] = e[elen]; break; } if (plus.s[j + split]) e[elen++] = plus.s + j; j = i + 1; } e[elen] = 0; pathexec_run(*argv,argv,e); alloc_free(e); } net/ipsvd-1.0.0/src/pathexec_run.c0000644000000000000000000000202011025276022015530 0ustar rootroot/* Public domain. */ #include "error.h" #include "stralloc.h" #include "str.h" #include "env.h" #include "pathexec.h" static stralloc tmp; void pathexec_run(const char *file,const char * const *argv,const char * const *envp) { const char *path; unsigned int split; int savederrno; if (file[str_chr(file,'/')]) { execve(file,argv,envp); return; } path = env_get("PATH"); if (!path) path = "/bin:/usr/bin"; savederrno = 0; for (;;) { split = str_chr(path,':'); if (!stralloc_copyb(&tmp,path,split)) return; if (!split) if (!stralloc_cats(&tmp,".")) return; if (!stralloc_cats(&tmp,"/")) return; if (!stralloc_cats(&tmp,file)) return; if (!stralloc_0(&tmp)) return; execve(tmp.s,argv,envp); if (errno != error_noent) { savederrno = errno; if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return; } if (!path[split]) { if (savederrno) errno = savederrno; return; } path += split; path += 1; } } net/ipsvd-1.0.0/src/print-ar.sh0000644000000000000000000000037111025276022014776 0ustar rootrootcat warn-auto.sh echo 'main="$1"; shift' echo 'rm -f "$main"' echo 'ar cr "$main" ${1+"$@"}' case "`cat systype`" in sunos-5.*) ;; unix_sv*) ;; irix64-*) ;; irix-*) ;; dgux-*) ;; hp-ux-*) ;; sco*) ;; *) echo 'ranlib "$main"' ;; esac net/ipsvd-1.0.0/src/print-cc.sh0000644000000000000000000000011011025276022014750 0ustar rootrootcc="`head -n1 conf-cc`" cat warn-auto.sh echo exec "$cc" '-c ${1+"$@"}' net/ipsvd-1.0.0/src/print-ld.sh0000644000000000000000000000016211025276022014771 0ustar rootrootld="`head -n1 conf-ld`" cat warn-auto.sh echo 'main="$1"; shift' echo exec "$ld" '-o "$main" "$main".o ${1+"$@"}' net/ipsvd-1.0.0/src/prot.c0000644000000000000000000000061311025276022014035 0ustar rootroot/* Public domain. */ #include "hasshsgr.h" #include "prot.h" int prot_gid(int gid) { #ifdef HASSHORTSETGROUPS short x[2]; x[0] = gid; x[1] = 73; /* catch errors */ if (setgroups(1,x) == -1) return -1; #else if (setgroups(1,&gid) == -1) return -1; #endif return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ } int prot_uid(int uid) { return setuid(uid); } net/ipsvd-1.0.0/src/prot.h0000644000000000000000000000016111025276022014040 0ustar rootroot/* Public domain. */ #ifndef PROT_H #define PROT_H extern int prot_gid(int); extern int prot_uid(int); #endif net/ipsvd-1.0.0/src/readclose.c0000644000000000000000000000105511025276022015013 0ustar rootroot/* Public domain. */ #include #include "error.h" #include "readclose.h" int readclose_append(int fd,stralloc *sa,unsigned int bufsize) { int r; for (;;) { if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } r = read(fd,sa->s + sa->len,bufsize); if (r == -1) if (errno == error_intr) continue; if (r <= 0) { close(fd); return r; } sa->len += r; } } int readclose(int fd,stralloc *sa,unsigned int bufsize) { if (!stralloc_copys(sa,"")) { close(fd); return -1; } return readclose_append(fd,sa,bufsize); } net/ipsvd-1.0.0/src/readclose.h0000644000000000000000000000031311025276022015014 0ustar rootroot/* Public domain. */ #ifndef READCLOSE_H #define READCLOSE_H #include "stralloc.h" extern int readclose_append(int,stralloc *,unsigned int); extern int readclose(int,stralloc *,unsigned int); #endif net/ipsvd-1.0.0/src/readwrite.h0000644000000000000000000000002411025276022015040 0ustar rootroot#include net/ipsvd-1.0.0/src/scan.h0000644000000000000000000000260511025276022014005 0ustar rootroot/* Public domain. */ #ifndef SCAN_H #define SCAN_H extern unsigned int scan_uint(const char *,unsigned int *); extern unsigned int scan_xint(const char *,unsigned int *); extern unsigned int scan_nbbint(const char *,unsigned int,unsigned int,unsigned int,unsigned int *); extern unsigned int scan_ushort(const char *,unsigned short *); extern unsigned int scan_xshort(const char *,unsigned short *); extern unsigned int scan_nbbshort(const char *,unsigned int,unsigned int,unsigned int,unsigned short *); extern unsigned int scan_ulong(const char *,unsigned long *); extern unsigned int scan_xlong(const char *,unsigned long *); extern unsigned int scan_nbblong(const char *,unsigned int,unsigned int,unsigned int,unsigned long *); extern unsigned int scan_plusminus(const char *,int *); extern unsigned int scan_0x(const char *,unsigned int *); extern unsigned int scan_whitenskip(const char *,unsigned int); extern unsigned int scan_nonwhitenskip(const char *,unsigned int); extern unsigned int scan_charsetnskip(const char *,const char *,unsigned int); extern unsigned int scan_noncharsetnskip(const char *,const char *,unsigned int); extern unsigned int scan_strncmp(const char *,const char *,unsigned int); extern unsigned int scan_memcmp(const char *,const char *,unsigned int); extern unsigned int scan_long(const char *,long *); extern unsigned int scan_8long(const char *,unsigned long *); #endif net/ipsvd-1.0.0/src/scan_ulong.c0000644000000000000000000000055111025276022015202 0ustar rootroot/* Public domain. */ #include "scan.h" unsigned int scan_ulong(register const char *s,register unsigned long *u) { register unsigned int pos = 0; register unsigned long result = 0; register unsigned long c; while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) { result = result * 10 + c; ++pos; } *u = result; return pos; } net/ipsvd-1.0.0/src/seek.h0000644000000000000000000000042711025276022014010 0ustar rootroot/* Public domain. */ #ifndef SEEK_H #define SEEK_H typedef unsigned long seek_pos; extern seek_pos seek_cur(int); extern int seek_set(int,seek_pos); extern int seek_end(int); extern int seek_trunc(int,seek_pos); #define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) #endif net/ipsvd-1.0.0/src/seek_set.c0000644000000000000000000000027211025276022014654 0ustar rootroot/* Public domain. */ #include #include "seek.h" #define SET 0 /* sigh */ int seek_set(int fd,seek_pos pos) { if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } net/ipsvd-1.0.0/src/select.h10000644000000000000000000000023511025276022014416 0ustar rootroot/* Public domain. */ #ifndef SELECT_H #define SELECT_H /* sysdep: -sysselect */ #include #include extern int select(); #endif net/ipsvd-1.0.0/src/select.h20000644000000000000000000000026511025276022014422 0ustar rootroot/* Public domain. */ #ifndef SELECT_H #define SELECT_H /* sysdep: +sysselect */ #include #include #include extern int select(); #endif net/ipsvd-1.0.0/src/sgetopt.c0000644000000000000000000000242511025276022014541 0ustar rootroot/* Public domain. */ /* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer D. J. Bernstein, djb@pobox.com. Depends on subgetopt.h, buffer.h. No system requirements. 19991219: Switched to buffer.h. 19970208: Cleanups. 931201: Baseline. No known patent problems. Documentation in sgetopt.3. */ #include "buffer.h" #define SGETOPTNOSHORT #include "sgetopt.h" #define SUBGETOPTNOSHORT #include "subgetopt.h" #define getopt sgetoptmine #define optind subgetoptind #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname int opterr = 1; const char *optprogname = 0; int getopt(int argc,const char *const *argv,const char *opts) { int c; const char *s; if (!optprogname) { optprogname = *argv; if (!optprogname) optprogname = ""; for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1; } c = subgetopt(argc,argv,opts); if (opterr) if (c == '?') { char chp[2]; chp[0] = optproblem; chp[1] = '\n'; buffer_puts(buffer_2,optprogname); if (argv[optind] && (optind < argc)) buffer_puts(buffer_2,": illegal option -- "); else buffer_puts(buffer_2,": option requires an argument -- "); buffer_put(buffer_2,chp,2); buffer_flush(buffer_2); } return c; } net/ipsvd-1.0.0/src/sgetopt.h0000644000000000000000000000074111025276022014545 0ustar rootroot/* Public domain. */ #ifndef SGETOPT_H #define SGETOPT_H #ifndef SGETOPTNOSHORT #define getopt sgetoptmine #define optarg subgetoptarg #define optind subgetoptind #define optpos subgetoptpos #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname #define opteof subgetoptdone #endif #include "subgetopt.h" extern int sgetoptmine(int,const char *const *,const char *); extern int sgetopterr; extern const char *sgetoptprogname; #endif net/ipsvd-1.0.0/src/sig.c0000644000000000000000000000046511025276022013640 0ustar rootroot/* Public domain. */ #include #include "sig.h" int sig_alarm = SIGALRM; int sig_child = SIGCHLD; int sig_cont = SIGCONT; int sig_hangup = SIGHUP; int sig_int = SIGINT; int sig_pipe = SIGPIPE; int sig_term = SIGTERM; void (*sig_defaulthandler)() = SIG_DFL; void (*sig_ignorehandler)() = SIG_IGN; net/ipsvd-1.0.0/src/sig.h0000644000000000000000000000111311025276022013634 0ustar rootroot/* Public domain. */ #ifndef SIG_H #define SIG_H extern int sig_alarm; extern int sig_child; extern int sig_cont; extern int sig_hangup; extern int sig_int; extern int sig_pipe; extern int sig_term; extern void (*sig_defaulthandler)(); extern void (*sig_ignorehandler)(); extern void sig_catch(int,void (*)()); #define sig_ignore(s) (sig_catch((s),sig_ignorehandler)) #define sig_uncatch(s) (sig_catch((s),sig_defaulthandler)) extern void sig_block(int); extern void sig_unblock(int); extern void sig_blocknone(void); extern void sig_pause(void); extern void sig_dfl(int); #endif net/ipsvd-1.0.0/src/sig_block.c0000644000000000000000000000122311025276022015003 0ustar rootroot/* Public domain. */ #include #include "sig.h" #include "hassgprm.h" void sig_block(int sig) { #ifdef HASSIGPROCMASK sigset_t ss; sigemptyset(&ss); sigaddset(&ss,sig); sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0); #else sigblock(1 << (sig - 1)); #endif } void sig_unblock(int sig) { #ifdef HASSIGPROCMASK sigset_t ss; sigemptyset(&ss); sigaddset(&ss,sig); sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0); #else sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1))); #endif } void sig_blocknone(void) { #ifdef HASSIGPROCMASK sigset_t ss; sigemptyset(&ss); sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); #else sigsetmask(0); #endif } net/ipsvd-1.0.0/src/sig_catch.c0000644000000000000000000000055311025276022015000 0ustar rootroot/* Public domain. */ #include #include "sig.h" #include "hassgact.h" void sig_catch(int sig,void (*f)()) { #ifdef HASSIGACTION struct sigaction sa; sa.sa_handler = f; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(sig,&sa,(struct sigaction *) 0); #else signal(sig,f); /* won't work under System V, even nowadays---dorks */ #endif } net/ipsvd-1.0.0/src/sig_pause.c0000644000000000000000000000032311025276022015026 0ustar rootroot/* Public domain. */ #include #include "sig.h" #include "hassgprm.h" void sig_pause(void) { #ifdef HASSIGPROCMASK sigset_t ss; sigemptyset(&ss); sigsuspend(&ss); #else sigpause(0); #endif } net/ipsvd-1.0.0/src/socket.h0000644000000000000000000000121111025276022014341 0ustar rootroot#ifndef SOCKET_H #define SOCKET_H #include "uint16.h" extern int socket_tcp(void); extern int socket_udp(void); extern int socket_connect4(int,const char *,uint16); extern int socket_connected(int); extern int socket_bind4(int,char *,uint16); extern int socket_bind4_reuse(int,char *,uint16); extern int socket_listen(int,int); extern int socket_accept4(int,char *,uint16 *); extern int socket_recv4(int,char *,int,char *,uint16 *); extern int socket_send4(int,const char *,int,const char *,uint16); extern int socket_local4(int,char *,uint16 *); extern int socket_remote4(int,char *,uint16 *); extern void socket_tryreservein(int,int); #endif net/ipsvd-1.0.0/src/socket_bind.c0000644000000000000000000000135111025276022015335 0ustar rootroot#include #include #include #include #include "byte.h" #include "socket.h" int socket_bind4(int s,char ip[4],uint16 port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = AF_INET; uint16_pack_big((char *) &sa.sin_port,port); byte_copy((char *) &sa.sin_addr,4,ip); return bind(s,(struct sockaddr *) &sa,sizeof sa); } int socket_bind4_reuse(int s,char ip[4],uint16 port) { int opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); return socket_bind4(s,ip,port); } void socket_tryreservein(int s,int size) { while (size >= 1024) { if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,&size,sizeof size) == 0) return; size -= (size >> 5); } } net/ipsvd-1.0.0/src/socket_conn.c0000644000000000000000000000123511025276022015357 0ustar rootroot#include #include #include #include #include #include "byte.h" #include "socket.h" int socket_connect4(int s,const char ip[4],uint16 port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = AF_INET; uint16_pack_big((char *) &sa.sin_port,port); byte_copy((char *) &sa.sin_addr,4,ip); return connect(s,(struct sockaddr *) &sa,sizeof sa); } int socket_connected(int s) { struct sockaddr_in sa; int dummy; char ch; dummy = sizeof sa; if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) { read(s,&ch,1); /* sets errno */ return 0; } return 1; } net/ipsvd-1.0.0/src/socket_tcp.c0000644000000000000000000000047411025276022015214 0ustar rootroot#include #include #include #include #include #include "ndelay.h" #include "socket.h" int socket_tcp(void) { int s; s = socket(AF_INET,SOCK_STREAM,0); if (s == -1) return -1; if (ndelay_on(s) == -1) { close(s); return -1; } return s; } net/ipsvd-1.0.0/src/socket_udp.c0000644000000000000000000000047311025276022015215 0ustar rootroot#include #include #include #include #include #include "ndelay.h" #include "socket.h" int socket_udp(void) { int s; s = socket(AF_INET,SOCK_DGRAM,0); if (s == -1) return -1; if (ndelay_on(s) == -1) { close(s); return -1; } return s; } net/ipsvd-1.0.0/src/ssl_io.c0000644000000000000000000003066711025276022014355 0ustar rootroot#include #include #include "matrixSsl.h" #include "uidgid.h" #include "prot.h" #include "error.h" #include "strerr.h" #include "fd.h" #include "pathexec.h" #include "stralloc.h" #include "byte.h" #include "taia.h" #include "iopause.h" #include "ndelay.h" #include "fmt.h" #include "scan.h" #include "sgetopt.h" #include "env.h" #include "sig.h" #include "sslerror_str.h" #define USAGEROOT " -u user [-U user] [-/ root] [-C cert] [-K key] [-A ca] [-vc] prog" #define USAGE " [-C cert] [-K key] [-A ca] [-cv] prog" #define VERSION "$Id: 5b49a0244b79fd00a69b028b11d60dde84c7a8a5 $" #define NAME "sslio[" #define FATAL "]: fatal: " #define WARNING "]: warning: " #define INFO "]: info: " const char *progname; extern char id[FMT_ULONG]; extern char ul[FMT_ULONG]; extern int pid; static void finish(void); static void die_nomem() { strerr_die4x(111, NAME, id, FATAL, "out of memory."); } static void fatalm(char *m0) { strerr_die5sys(111, NAME, id, FATAL, m0, ": "); } static void fatalmx(char *m0) { strerr_die4x(111, NAME, id, FATAL, m0); } static void fatal(char *m0) { strerr_warn5(NAME, id, FATAL, m0, ": ", &strerr_sys); finish(); _exit(111); } static void fatalx(char *m0) { strerr_warn4(NAME, id, FATAL, m0, 0); finish(); _exit(111); } static void fatals(char *m0, int e) { strerr_warn6(NAME, id, FATAL, m0, ": ", sslerror_str(e), 0); finish(); _exit(111); } static void warn(char *m0) { strerr_warn5(NAME, id, WARNING, m0, ": ", &strerr_sys); } static void warnx(char *m0) { strerr_warn4(NAME, id, WARNING, m0, 0); } static void info(char *m0) { strerr_warn4(NAME, id, INFO, m0, 0); } static void infou(char *m0, unsigned long u) { ul[fmt_ulong(ul, u)] =0; strerr_warn5(NAME, id, INFO, m0, ul, 0); } extern char *cert; extern char *key; extern char *ssluser; extern char *ca; extern char *svuser; extern char *root; extern unsigned int client; extern unsigned int verbose; extern struct uidgid ugid, sslugid; extern ssl_t *ssl; extern sslKeys_t *keys; static unsigned long bufsizein =8192; static unsigned long bufsizeou =12288; static int encpipe[2]; static int decpipe[2]; static int len; static int rc; static int handshake =1; static int getdec =1; static char *s; static unsigned long handshake_timeout =300; static sslBuf_t encin, encou; static stralloc encinbuf ={0}; static stralloc encoubuf ={0}; static sslBuf_t decin, decou; static stralloc decinbuf ={0}; static stralloc decoubuf ={0}; static int fdstdin =0; static int fdstdou =1; static unsigned long bytesin =0; static unsigned long bytesou =0; static unsigned char error, alvl, adesc; static char *bad_certificate; static void sig_term_handler(void) { if (verbose) info("sigterm received, exit."); finish(); _exit(0); } unsigned int blowup(sslBuf_t *buf, stralloc *sa, unsigned int len) { sa->len =buf->end -buf->buf; buf->size +=len; if (! stralloc_ready(sa, buf->size)) return(0); buf->end =sa->s +(buf->end -buf->buf); buf->start =sa->s +(buf->start -buf->buf); buf->buf =sa->s; return(1); } void finish(void) { if (fdstdou != -1) for (;;) { decou.start =decou.end =decou.buf; rc =matrixSslEncodeClosureAlert(ssl, &decou); if (rc == SSL_FULL) { if (! blowup(&decou, &decoubuf, bufsizeou)) die_nomem(); if (verbose > 1) infou("decode output buffer size: ", decou.size); continue; } if (rc == SSL_ERROR) if (verbose) warnx("unable to encode ssl close notify"); if (rc == 0) { if (write(fdstdou, decou.start, decou.end -decou.start) != (decou.end -decou.start)) { if (verbose) warn("unable to send ssl close notify"); break; } if (verbose > 2) info("sending ssl close notify"); if (verbose > 2) infou("write bytes: ", decou.end -decou.start); bytesou +=decou.end -decou.start; } break; } /* bummer */ matrixSslFreeKeys(keys); matrixSslDeleteSession(ssl); matrixSslClose(); if (fdstdou != -1) close(fdstdou); if (encpipe[0] != -1) close(encpipe[0]); if (fdstdin != -1) close(fdstdin); if (decpipe[1] != -1) close(decpipe[1]); if (verbose) { infou("bytes in: ", bytesin); infou("bytes ou: ", bytesou); } } int validate(sslCertInfo_t *cert, void *arg) { sslCertInfo_t *c =cert; if (bad_certificate) return 1; while (c->next) c =c->next; return(c->verified); } void encode(void) { if ((len =read(encpipe[0], encinbuf.s, encin.size)) < 0) fatal("unable to read from prog"); if (len == 0) { if (verbose > 2) info("eof reading from proc"); finish(); _exit(0); } for (;;) { rc =matrixSslEncode(ssl, encin.buf, len, &encou); if (rc == SSL_ERROR) { close(fdstdou); fdstdou =-1; fatalx("unable to encode data"); } if (rc == SSL_FULL) { if (! blowup(&encou, &encoubuf, bufsizeou)) die_nomem(); if (verbose > 1) infou("encode output buffer size: ", encou.size); continue; } if (write(fdstdou, encou.start, encou.end -encou.start) != encou.end -encou.start) fatal("unable to write to network"); if (verbose > 2) infou("write bytes: ", encou.end -encou.start); bytesou +=encou.end -encou.start; encou.start =encou.end =encou.buf =encoubuf.s; return; } } void decode(void) { do { if (getdec) { len =decin.size -(decin.end -decin.buf); if ((len =read(fdstdin, decin.end, len)) < 0) fatal("unable to read from network"); if (len == 0) { if (verbose > 2) info("eof reading from network"); close(fdstdin); close(decpipe[1]); fdstdin =decpipe[1] =-1; return; } if (verbose > 2) infou("read bytes: ", len); bytesin +=len; decin.end +=len; getdec =0; } for (;;) { rc =matrixSslDecode(ssl, &decin, &decou, &error, &alvl, &adesc); if (rc == SSL_SUCCESS) break; if (rc == SSL_ERROR) { if (decou.end > decou.start) if (write(fdstdou, decou.start, decou.end -decou.start) != decou.end -decou.start) warn("unable to write to network"); close(fdstdou); fdstdou =-1; fatals("ssl decode error", error); } if (rc == SSL_PROCESS_DATA) { if (write(decpipe[1], decou.start, decou.end -decou.start) != decou.end -decou.start) fatal("unable to write to prog"); decou.start =decou.end =decou.buf; if (decin.start > decin.buf) { /* align */ byte_copy(decin.buf, decin.end -decin.start, decin.start); decin.end -=decin.start -decin.buf; decin.start =decin.buf; } break; } if (rc == SSL_SEND_RESPONSE) { if (write(fdstdou, decou.start, decou.end -decou.start) != (decou.end -decou.start)) fatal("unable to send ssl response"); bytesou +=decou.end -decou.start; if (verbose > 2) info("sending ssl handshake response"); if (verbose > 2) infou("write bytes: ", decou.end -decou.start); decou.start =decou.end =decou.buf; break; } if (rc == SSL_ALERT) { close(fdstdou); fdstdou =-1; if (adesc != SSL_ALERT_CLOSE_NOTIFY) fatals("ssl alert from peer", adesc); if (verbose > 2) info("ssl close notify from peer"); finish(); _exit(0); } if (rc == SSL_PARTIAL) { getdec =1; if (decin.size -(decin.end -decin.buf) < bufsizein) { if (! blowup(&decin, &decinbuf, bufsizein)) die_nomem(); if (verbose > 1) infou("decode input buffer size: ", decin.size); } break; } if (rc == SSL_FULL) { if (! blowup(&decou, &decoubuf, bufsizeou)) die_nomem(); if (verbose > 1) infou("decode output buffer size: ", decou.size); continue; } } if (decin.start == decin.end) { decin.start =decin.end =decin.buf; getdec =1; } } while (getdec == 0); if (handshake) if (matrixSslHandshakeIsComplete(ssl)) { handshake =0; if (verbose > 2) info("ssl handshake complete"); } } void doio(void) { iopause_fd x[2]; struct taia deadline; struct taia now; struct taia timeout; if (! stralloc_ready(&encinbuf, bufsizein)) die_nomem(); encin.buf =encin.start =encin.end =encinbuf.s; encin.size =bufsizein; if (! stralloc_ready(&decinbuf, bufsizein)) die_nomem(); decin.buf =decin.start =decin.end =decinbuf.s; decin.size =bufsizein; if (! stralloc_ready(&encoubuf, bufsizeou)) die_nomem(); encou.buf =encou.start =encou.end =encoubuf.s; encou.size =bufsizeou; if (! stralloc_ready(&decoubuf, bufsizeou)) die_nomem(); decou.buf =decou.start =decou.end =decoubuf.s; decou.size =bufsizeou; if (client) { rc =matrixSslEncodeClientHello(ssl, &decou, 0); if (rc != 0) fatalx("unable to encode client hello"); if (write(fdstdou, decou.start, decou.end -decou.start) != (decou.end -decou.start)) fatal("unable to send client hello"); if (verbose > 2) info("sending client hello"); if (verbose > 2) infou("write bytes: ", decou.end -decou.start); bytesou +=decou.end -decou.start; decou.start =decou.end =decou.buf; } taia_now(&now); taia_uint(&timeout, handshake_timeout); taia_add(&timeout, &now, &timeout); for (;;) { iopause_fd *xx =x; int l =2; x[0].fd =encpipe[0]; x[0].events =IOPAUSE_READ; x[0].revents =0; x[1].fd =fdstdin; x[1].events =IOPAUSE_READ; x[1].revents =0; if ((x[0].fd == -1) || handshake) { --l; ++xx; } if (x[1].fd == -1) --l; if (! l) return; taia_now(&now); if (handshake) { if (taia_less(&timeout, &now)) { if (verbose) info("ssl handshake timeout, exit."); return; } deadline.sec =timeout.sec; deadline.nano =timeout.nano; deadline.atto =timeout.atto; } else { taia_uint(&deadline, 30); taia_add(&deadline, &now, &deadline); } iopause(xx, l, &deadline, &now); if (x[0].revents) encode(); if (x[1].revents) decode(); } } int ssl_io(unsigned int newsession, const char **prog) { if (client) { fdstdin =6; fdstdou =7; } bad_certificate = env_get("SSLIO_BAD_CERTIFICATE"); if ((s =env_get("SSLIO_BUFIN"))) scan_ulong(s, &bufsizein); if ((s =env_get("SSLIO_BUFOU"))) scan_ulong(s, &bufsizeou); if (bufsizein < 64) bufsizein =64; if (bufsizeou < 64) bufsizeou =64; if ((s =env_get("SSLIO_HANDSHAKE_TIMEOUT"))) scan_ulong(s, &handshake_timeout); if (handshake_timeout < 1) handshake_timeout =1; if (pipe(encpipe) == -1) fatalm("unable to create pipe for encoding"); if (pipe(decpipe) == -1) fatalm("unable to create pipe for decoding"); if ((pid =fork()) == -1) fatalm("unable to fork"); if (pid == 0) { if (close(encpipe[1]) == -1) fatalm("unable to close encoding pipe output"); if (close(decpipe[0]) == -1) fatalm("unable to close decoding pipe input"); if (newsession) if (matrixSslOpen() < 0) fatalm("unable to initialize ssl"); if (root) { if (chdir(root) == -1) fatalm("unable to change to new root directory"); if (chroot(".") == -1) fatalm("unable to chroot"); } if (ssluser) { /* drop permissions */ if (setgroups(sslugid.gids, sslugid.gid) == -1) fatal("unable to set groups"); if (setgid(*sslugid.gid) == -1) fatal("unable to set gid"); if (prot_uid(sslugid.uid) == -1) fatalm("unable to set uid"); } if (newsession) { if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) { if (client) fatalm("unable to read cert, key, or ca file"); fatalm("unable to read cert or key file"); } if (matrixSslNewSession(&ssl, keys, 0, client?0:SSL_FLAGS_SERVER) < 0) fatalmx("unable to create ssl session"); } if (client) if (ca || bad_certificate) matrixSslSetCertValidator(ssl, &validate, 0); sig_catch(sig_term, sig_term_handler); sig_ignore(sig_pipe); doio(); finish(); _exit(0); } if (close(encpipe[0]) == -1) fatalm("unable to close encoding pipe input"); if (close(decpipe[1]) == -1) fatalm("unable to close decoding pipe output"); if (fd_move(fdstdin, decpipe[0]) == -1) fatalm("unable to setup filedescriptor for decoding"); if (fd_move(fdstdou, encpipe[1]) == -1) fatalm("unable to setup filedescriptor for encoding"); sslCloseOsdep(); if (svuser) { if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups for prog"); if (setgid(*ugid.gid) == -1) fatal("unable to set gid for prog"); if (prot_uid(ugid.uid) == -1) fatalm("unable to set uid for prog"); } pathexec(prog); fatalm("unable to run prog"); return(111); } net/ipsvd-1.0.0/src/ssl_io.h0000644000000000000000000000054511025276022014352 0ustar rootroot#ifndef SSL_IO_H #define SSL_IO_H #include "matrixSsl.h" #include "uidgid.h" char id[FMT_ULONG]; char ul[FMT_ULONG]; char *cert =0; char *key =0; char *ssluser =0; char *ca =0; char *svuser =0; char *root =0; unsigned int client =0; int pid; struct uidgid ugid; struct uidgid sslugid; ssl_t *ssl; sslKeys_t *keys; int ssl_io(int, const char **); #endif net/ipsvd-1.0.0/src/sslerror_str.c0000644000000000000000000000143011025276022015612 0ustar rootroot#include "matrixSsl.h" #define X(e,s) if (i == e) return s; const char *sslerror_str(int i) { X(SSL_ALERT_CLOSE_NOTIFY, "close notify"); X(SSL_ALERT_UNEXPECTED_MESSAGE, "unexpected message"); X(SSL_ALERT_BAD_RECORD_MAC, "bad record mac"); X(SSL_ALERT_DECOMPRESSION_FAILURE, "decompression failure"); X(SSL_ALERT_HANDSHAKE_FAILURE, "handshake failure"); X(SSL_ALERT_NO_CERTIFICATE, "no certificate"); X(SSL_ALERT_BAD_CERTIFICATE, "bad certificate"); X(SSL_ALERT_UNSUPPORTED_CERTIFICATE, "unsupported certificate"); X(SSL_ALERT_CERTIFICATE_REVOKED, "certificate revoked"); X(SSL_ALERT_CERTIFICATE_EXPIRED, "certificate expired"); X(SSL_ALERT_CERTIFICATE_UNKNOWN, "certificate unknown"); X(SSL_ALERT_ILLEGAL_PARAMETER, "illegal parameter"); return "unknown alert"; } net/ipsvd-1.0.0/src/sslerror_str.h0000644000000000000000000000013511025276022015620 0ustar rootroot#ifndef SSLERROR_STR_H #define SSLERROR_STR_H extern const char *sslerror_str(int); #endif net/ipsvd-1.0.0/src/sslio.c0000644000000000000000000000414611025276022014207 0ustar rootroot#include #include #include "matrixSsl.h" #include "uidgid.h" #include "prot.h" #include "error.h" #include "strerr.h" #include "fd.h" #include "pathexec.h" #include "stralloc.h" #include "byte.h" #include "taia.h" #include "iopause.h" #include "ndelay.h" #include "fmt.h" #include "scan.h" #include "sgetopt.h" #include "env.h" #include "sig.h" #include "sslerror_str.h" #include "ssl_io.h" #define USAGEROOT " -u user [-U user] [-/ root] [-C cert] [-K key] [-A ca] [-vc] prog" #define USAGE " [-C cert] [-K key] [-A ca] [-cv] prog" #define VERSION "$Id: c08b30d00b9743c5bd24fa59a281a90dd4c742c4 $" const char *progname; unsigned int verbose =0; void usage() { if (getuid() == 0) strerr_die4x(111, "usage: ", progname, USAGEROOT, "\n"); strerr_die4x(111, "usage: ", progname, USAGE, "\n"); } int main(int argc, const char **argv) { int opt; progname =*argv; pid =getpid(); id[fmt_ulong(id, pid)] =0; while ((opt =getopt(argc, argv, "u:U:/:C:K:A:cvV")) != opteof) { switch(opt) { case 'u': ssluser =(char*)optarg; break; case 'U': svuser =(char*)optarg; break; case '/': root =(char*)optarg; break; case 'C': cert =(char*)optarg; break; case 'K': key =(char*)optarg; break; case 'c': client =1; break; case 'A': ca =(char*)optarg; break; case 'v': ++verbose; break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); if (getuid() == 0) { if (! ssluser) usage(); } else { if (root || ssluser || svuser) usage(); } if (! client) { if (! cert) cert ="./cert.pem"; if (! key) key =cert; } if (ssluser) if (! uidgids_get(&sslugid, ssluser)) { if (errno) strerr_die3sys(111, "sslio[", id, "]: fatal: unable to get user/group: "); strerr_die4x(100, "sslio[", id, "]: fatal: unknown user/group: ", ssluser); } if (svuser) if (! uidgids_get(&ugid, svuser)) { if (errno) strerr_die3sys(111, "sslio[", id, "]: fatal: unable to get user/group: "); strerr_die4x(100, "sslio[", id, "]: fatal: unknown user/group: ", svuser); } return(ssl_io(1, argv)); } net/ipsvd-1.0.0/src/sslio.check0000755000000000000000000000133611025276022015043 0ustar rootroot#!/bin/sh rm -rf "${ctmp}" OPTS= test `id -u` -ne 0 || OPTS='-uroot' (sslio 2>&1; echo $?) |grep -v usage (sslio -V 2>&1; echo $?) |grep -v usage mkdir "${ctmp}" mkfifo -m0600 "${ctmp}"/p0 mkfifo -m0600 "${ctmp}"/p1 sh -c "exec <${ctmp}/p0 exec >${ctmp}/p1 sslio $OPTS -Csslio.pem sh -c 'echo foo'" & pid=$! sh -c "exec 7>${ctmp}/p0 exec 6<${ctmp}/p1 sslio $OPTS -c sh -c 'cat <&6'" rcc=$? wait $pid rcs=$? sleep 2 echo $rcs echo $rcc sh -c "exec <${ctmp}/p0 exec >${ctmp}/p1 sslio $OPTS -Csslio.pem sh -c 'cat >&2'" & pid=$! sh -c "exec 7>${ctmp}/p0 exec 6<${ctmp}/p1 sslio $OPTS -c sh -c 'echo bar >&7'" rcc=$? wait $pid rcs=$? sleep 2 echo $rcs echo $rcc rm -rf "${ctmp}" net/ipsvd-1.0.0/src/sslio.dist0000644000000000000000000000011211025276022014715 0ustar rootroot 111 $Id: c08b30d00b9743c5bd24fa59a281a90dd4c742c4 $ 111 foo 0 0 bar 0 0 net/ipsvd-1.0.0/src/sslio.pem0000644000000000000000000000374611025276022014553 0ustar rootroot-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDAOexSyf5DjRCEP0h7WUieSFUX3eUxbKwgm1unA8izob7W6fTg alCYp37r6+peQDFukA4rH2nZZT9xkE6wBHosExC+F3r0Gn9YTkw4hzhMA56v34od aueWKFSSV+uEzLdzmy9Rgo44nGv0W0nSrINQY1EStzFh6ckhm3cGOCTjWwIDAQAB AoGAd8dgF9JgCq2q3g0k2B+xXVfLFj0hZKPHueW0vaRg+nXOGdLc0L3OjODJ+K4f cy1i3/cJrRs89MbfOp9mOM4BZcClo80snyxwHYbHjV48een2kybrQfAwAJ/d4eJZ VV9xQ0Lx2o4sFIbtZtPglFCoJ+yPI0+G604m+AvbogdeThECQQD75m5ENlJ8OU1A rZsPnJ/VyD11gRdsW1D50HX8uYFMI9/4N1FdYSsYSNrUY7y21tJdzUGd3um12Z1i fborCoejAkEAw1ra0zi3509T2PLMWMkGzgDKyGDk+UBLE0GLLmwLwnugGQQqS/A8 CxfCzWIE7QBFf1Fag37sPqDl3eo1bunQ6QJBAJVQRqY6SPSHhspC3boIThoLgpqn NXouOraJoZZ3YzP9w+G+8ITYdxIDBWuF3zPF7JZbd3ybyI7ZelgKTJL8v98CQEU9 ImnSpHu7RgCSrZKaTWseJME4dm9RNkqw5F+js9dOccPsEgGwN9fGqCibIRvPCNLD Rs1sYtcft9kbdazF+mECQQDLZ18I9ljgIL+W6e3FoRSTssf3UbW2OSVQGqXJX9CS WRuWpqZgQTeabPA3lXvRLBVd+JUa9WI/fLTVEW7Hdiuj -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDGTCCAoKgAwIBAgIJAMSlv4aCZ/vMMA0GCSqGSIb3DQEBBAUAMGcxCzAJBgNV BAYTAlhYMQswCQYDVQQIEwJYWDELMAkGA1UEBxMCWFgxCzAJBgNVBAoTAlhYMQsw CQYDVQQLEwJYWDEOMAwGA1UEAxMFc3NsaW8xFDASBgkqhkiG9w0BCQEWBXNzbGlv MB4XDTA1MDIyMDE0NTQzN1oXDTA1MDMyMjE0NTQzN1owZzELMAkGA1UEBhMCWFgx CzAJBgNVBAgTAlhYMQswCQYDVQQHEwJYWDELMAkGA1UEChMCWFgxCzAJBgNVBAsT AlhYMQ4wDAYDVQQDEwVzc2xpbzEUMBIGCSqGSIb3DQEJARYFc3NsaW8wgZ8wDQYJ KoZIhvcNAQEBBQADgY0AMIGJAoGBAMA57FLJ/kONEIQ/SHtZSJ5IVRfd5TFsrCCb W6cDyLOhvtbp9OBqUJinfuvr6l5AMW6QDisfadllP3GQTrAEeiwTEL4XevQaf1hO TDiHOEwDnq/fih1q55YoVJJX64TMt3ObL1GCjjica/RbSdKsg1BjURK3MWHpySGb dwY4JONbAgMBAAGjgcwwgckwHQYDVR0OBBYEFMwWLPZLBh92Ce6M2lQyUylOQhNN MIGZBgNVHSMEgZEwgY6AFMwWLPZLBh92Ce6M2lQyUylOQhNNoWukaTBnMQswCQYD VQQGEwJYWDELMAkGA1UECBMCWFgxCzAJBgNVBAcTAlhYMQswCQYDVQQKEwJYWDEL MAkGA1UECxMCWFgxDjAMBgNVBAMTBXNzbGlvMRQwEgYJKoZIhvcNAQkBFgVzc2xp b4IJAMSlv4aCZ/vMMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAiEV2 ZgADzDGyXlyK9p/OBAxz0R0KvhRzbIIRJc+lMo5PNhdkAuNEK+5GuLVnbGKc94JE 588afS98ariEBA064FPTa9G4Tx1btzGtg9z3kpFQF+sQNdMI1cuEs2BqjotissXa QtPHMgjjBuVRrwFCHLHf0FO393uOITCoMDAZ6GY= -----END CERTIFICATE----- net/ipsvd-1.0.0/src/sslsvd.c0000644000000000000000000000004311025276022014364 0ustar rootroot#define SSLSVD #include "tcpsvd.c" net/ipsvd-1.0.0/src/sslsvd.check0000755000000000000000000000002111025276022015216 0ustar rootroot#!/bin/sh exit 0 net/ipsvd-1.0.0/src/sslsvd.dist0000644000000000000000000000000011025276022015076 0ustar rootrootnet/ipsvd-1.0.0/src/sslsvd.local0000644000000000000000000000000011025276022015225 0ustar rootrootnet/ipsvd-1.0.0/src/str.h0000644000000000000000000000070411025276022013667 0ustar rootroot/* Public domain. */ #ifndef STR_H #define STR_H extern unsigned int str_copy(char *,const char *); extern int str_diff(const char *,const char *); extern int str_diffn(const char *,const char *,unsigned int); extern unsigned int str_len(const char *); extern unsigned int str_chr(const char *,int); extern unsigned int str_rchr(const char *,int); extern int str_start(const char *,const char *); #define str_equal(s,t) (!str_diff((s),(t))) #endif net/ipsvd-1.0.0/src/str_chr.c0000644000000000000000000000057211025276022014521 0ustar rootroot/* Public domain. */ #include "str.h" unsigned int str_chr(register const char *s,int c) { register char ch; register const char *t; ch = c; t = s; for (;;) { if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; } return t - s; } net/ipsvd-1.0.0/src/str_diff.c0000644000000000000000000000072311025276022014653 0ustar rootroot/* Public domain. */ #include "str.h" int str_diff(register const char *s,register const char *t) { register char x; for (;;) { x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; } return ((int)(unsigned int)(unsigned char) x) - ((int)(unsigned int)(unsigned char) *t); } net/ipsvd-1.0.0/src/str_len.c0000644000000000000000000000040511025276022014516 0ustar rootroot/* Public domain. */ #include "str.h" unsigned int str_len(const char *s) { register const char *t; t = s; for (;;) { if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; } } net/ipsvd-1.0.0/src/str_start.c0000644000000000000000000000056211025276022015101 0ustar rootroot/* Public domain. */ #include "str.h" int str_start(register const char *s,register const char *t) { register char x; for (;;) { x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; } } net/ipsvd-1.0.0/src/stralloc.h0000644000000000000000000000222711025276022014704 0ustar rootroot/* Public domain. */ #ifndef STRALLOC_H #define STRALLOC_H #include "gen_alloc.h" GEN_ALLOC_typedef(stralloc,char,s,len,a) extern int stralloc_ready(stralloc *,unsigned int); extern int stralloc_readyplus(stralloc *,unsigned int); extern int stralloc_copy(stralloc *,const stralloc *); extern int stralloc_cat(stralloc *,const stralloc *); extern int stralloc_copys(stralloc *,const char *); extern int stralloc_cats(stralloc *,const char *); extern int stralloc_copyb(stralloc *,const char *,unsigned int); extern int stralloc_catb(stralloc *,const char *,unsigned int); extern int stralloc_append(stralloc *,const char *); /* beware: this takes a pointer to 1 char */ extern int stralloc_starts(stralloc *,const char *); #define stralloc_0(sa) stralloc_append(sa,"") extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int); extern int stralloc_catlong0(stralloc *,long,unsigned int); #define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0)) #define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n))) #define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n))) #define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0)) #endif net/ipsvd-1.0.0/src/stralloc_cat.c0000644000000000000000000000025711025276022015527 0ustar rootroot/* Public domain. */ #include "byte.h" #include "stralloc.h" int stralloc_cat(stralloc *sato,const stralloc *safrom) { return stralloc_catb(sato,safrom->s,safrom->len); } net/ipsvd-1.0.0/src/stralloc_catb.c0000644000000000000000000000052211025276022015664 0ustar rootroot/* Public domain. */ #include "stralloc.h" #include "byte.h" int stralloc_catb(stralloc *sa,const char *s,unsigned int n) { if (!sa->s) return stralloc_copyb(sa,s,n); if (!stralloc_readyplus(sa,n + 1)) return 0; byte_copy(sa->s + sa->len,n,s); sa->len += n; sa->s[sa->len] = 'Z'; /* ``offensive programming'' */ return 1; } net/ipsvd-1.0.0/src/stralloc_cats.c0000644000000000000000000000025311025276022015706 0ustar rootroot/* Public domain. */ #include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_cats(stralloc *sa,const char *s) { return stralloc_catb(sa,s,str_len(s)); } net/ipsvd-1.0.0/src/stralloc_copy.c0000644000000000000000000000023311025276022015724 0ustar rootroot#include "byte.h" #include "stralloc.h" int stralloc_copy(stralloc *sato,const stralloc *safrom) { return stralloc_copyb(sato,safrom->s,safrom->len); } net/ipsvd-1.0.0/src/stralloc_eady.c0000644000000000000000000000034111025276022015674 0ustar rootroot/* Public domain. */ #include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready) GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus) net/ipsvd-1.0.0/src/stralloc_opyb.c0000644000000000000000000000042111025276022015722 0ustar rootroot/* Public domain. */ #include "stralloc.h" #include "byte.h" int stralloc_copyb(stralloc *sa,const char *s,unsigned int n) { if (!stralloc_ready(sa,n + 1)) return 0; byte_copy(sa->s,n,s); sa->len = n; sa->s[n] = 'Z'; /* ``offensive programming'' */ return 1; } net/ipsvd-1.0.0/src/stralloc_opys.c0000644000000000000000000000025511025276022015750 0ustar rootroot/* Public domain. */ #include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_copys(stralloc *sa,const char *s) { return stralloc_copyb(sa,s,str_len(s)); } net/ipsvd-1.0.0/src/stralloc_pend.c0000644000000000000000000000025711025276022015706 0ustar rootroot/* Public domain. */ #include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append) net/ipsvd-1.0.0/src/strerr.h0000644000000000000000000000532211025276022014401 0ustar rootroot/* Public domain. */ #ifndef STRERR_H #define STRERR_H struct strerr { struct strerr *who; const char *x; const char *y; const char *z; } ; extern struct strerr strerr_sys; extern void strerr_sysinit(void); extern const char *strerr(const struct strerr *); extern void strerr_warn(const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *); extern void strerr_die(int,const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *); #define STRERR(r,se,a) \ { se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS(r,se,a) \ { se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS3(r,se,a,b,c) \ { se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; } #define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_warn5(x1,x2,x3,x4,x5,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_warn4(x1,x2,x3,x4,se) \ strerr_warn((x1),(x2),(x3),(x4),0,0,(se)) #define strerr_warn3(x1,x2,x3,se) \ strerr_warn((x1),(x2),(x3),0,0,0,(se)) #define strerr_warn2(x1,x2,se) \ strerr_warn((x1),(x2),0,0,0,0,(se)) #define strerr_warn1(x1,se) \ strerr_warn((x1),0,0,0,0,0,(se)) #define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_die5(e,x1,x2,x3,x4,x5,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_die4(e,x1,x2,x3,x4,se) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se)) #define strerr_die3(e,x1,x2,x3,se) \ strerr_die((e),(x1),(x2),(x3),0,0,0,(se)) #define strerr_die2(e,x1,x2,se) \ strerr_die((e),(x1),(x2),0,0,0,0,(se)) #define strerr_die1(e,x1,se) \ strerr_die((e),(x1),0,0,0,0,0,(se)) #define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys) #define strerr_die5sys(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys) #define strerr_die4sys(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys) #define strerr_die3sys(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys) #define strerr_die2sys(e,x1,x2) \ strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys) #define strerr_die1sys(e,x1) \ strerr_die((e),(x1),0,0,0,0,0,&strerr_sys) #define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0) #define strerr_die5x(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0) #define strerr_die4x(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,0) #define strerr_die3x(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),0,0,0,0) #define strerr_die2x(e,x1,x2) \ strerr_die((e),(x1),(x2),0,0,0,0,0) #define strerr_die1x(e,x1) \ strerr_die((e),(x1),0,0,0,0,0,0) #endif net/ipsvd-1.0.0/src/strerr_die.c0000644000000000000000000000155111025276022015215 0ustar rootroot/* Public domain. */ #include #include "buffer.h" #include "strerr.h" void strerr_warn(const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se) { strerr_sysinit(); if (x1) buffer_puts(buffer_2,x1); if (x2) buffer_puts(buffer_2,x2); if (x3) buffer_puts(buffer_2,x3); if (x4) buffer_puts(buffer_2,x4); if (x5) buffer_puts(buffer_2,x5); if (x6) buffer_puts(buffer_2,x6); while(se) { if (se->x) buffer_puts(buffer_2,se->x); if (se->y) buffer_puts(buffer_2,se->y); if (se->z) buffer_puts(buffer_2,se->z); se = se->who; } buffer_puts(buffer_2,"\n"); buffer_flush(buffer_2); } void strerr_die(int e,const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se) { strerr_warn(x1,x2,x3,x4,x5,x6,se); _exit(e); } net/ipsvd-1.0.0/src/strerr_sys.c0000644000000000000000000000033211025276022015266 0ustar rootroot/* Public domain. */ #include "error.h" #include "strerr.h" struct strerr strerr_sys; void strerr_sysinit(void) { strerr_sys.who = 0; strerr_sys.x = error_str(errno); strerr_sys.y = ""; strerr_sys.z = ""; } net/ipsvd-1.0.0/src/subgetopt.c0000644000000000000000000000261311025276022015067 0ustar rootroot/* Public domain. */ #define SUBGETOPTNOSHORT #include "subgetopt.h" #define sgopt subgetopt #define optind subgetoptind #define optpos subgetoptpos #define optarg subgetoptarg #define optproblem subgetoptproblem #define optdone subgetoptdone int optind = 1; int optpos = 0; const char *optarg = 0; int optproblem = 0; int optdone = SUBGETOPTDONE; int sgopt(int argc,const char *const *argv,const char *opts) { int c; const char *s; optarg = 0; if (!argv || (optind >= argc) || !argv[optind]) return optdone; if (optpos && !argv[optind][optpos]) { ++optind; optpos = 0; if ((optind >= argc) || !argv[optind]) return optdone; } if (!optpos) { if (argv[optind][0] != '-') return optdone; ++optpos; c = argv[optind][1]; if ((c == '-') || (c == 0)) { if (c) ++optind; optpos = 0; return optdone; } /* otherwise c is reassigned below */ } c = argv[optind][optpos]; ++optpos; s = opts; while (*s) { if (c == *s) { if (s[1] == ':') { optarg = argv[optind] + optpos; ++optind; optpos = 0; if (!*optarg) { optarg = argv[optind]; if ((optind >= argc) || !optarg) { /* argument past end */ optproblem = c; return '?'; } ++optind; } } return c; } ++s; if (*s == ':') ++s; } optproblem = c; return '?'; } net/ipsvd-1.0.0/src/subgetopt.h0000644000000000000000000000111611025276022015071 0ustar rootroot/* Public domain. */ #ifndef SUBGETOPT_H #define SUBGETOPT_H #ifndef SUBGETOPTNOSHORT #define sgopt subgetopt #define sgoptarg subgetoptarg #define sgoptind subgetoptind #define sgoptpos subgetoptpos #define sgoptproblem subgetoptproblem #define sgoptprogname subgetoptprogname #define sgoptdone subgetoptdone #endif #define SUBGETOPTDONE -1 extern int subgetopt(int,const char *const *,const char *); extern const char *subgetoptarg; extern int subgetoptind; extern int subgetoptpos; extern int subgetoptproblem; extern const char *subgetoptprogname; extern int subgetoptdone; #endif net/ipsvd-1.0.0/src/tai.h0000644000000000000000000000116211025276022013633 0ustar rootroot/* Public domain. */ #ifndef TAI_H #define TAI_H #include "uint64.h" struct tai { uint64 x; } ; #define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u))) extern void tai_now(struct tai *); #define tai_approx(t) ((double) ((t)->x)) extern void tai_add(struct tai *,const struct tai *,const struct tai *); extern void tai_sub(struct tai *,const struct tai *,const struct tai *); #define tai_less(t,u) ((t)->x < (u)->x) #define TAI_PACK 8 extern void tai_pack(char *,const struct tai *); extern void tai_unpack(const char *,struct tai *); extern void tai_uint(struct tai *,unsigned int); #endif net/ipsvd-1.0.0/src/tai_now.c0000644000000000000000000000017411025276022014513 0ustar rootroot/* Public domain. */ #include #include "tai.h" void tai_now(struct tai *t) { tai_unix(t,time((time_t *) 0)); } net/ipsvd-1.0.0/src/tai_pack.c0000644000000000000000000000047111025276022014626 0ustar rootroot/* Public domain. */ #include "tai.h" void tai_pack(char *s,const struct tai *t) { uint64 x; x = t->x; s[7] = x & 255; x >>= 8; s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; s[4] = x & 255; x >>= 8; s[3] = x & 255; x >>= 8; s[2] = x & 255; x >>= 8; s[1] = x & 255; x >>= 8; s[0] = x; } net/ipsvd-1.0.0/src/tai_sub.c0000644000000000000000000000020611025276022014475 0ustar rootroot/* Public domain. */ #include "tai.h" void tai_sub(struct tai *t,const struct tai *u,const struct tai *v) { t->x = u->x - v->x; } net/ipsvd-1.0.0/src/tai_unpack.c0000644000000000000000000000063011025276022015166 0ustar rootroot/* Public domain. */ #include "tai.h" void tai_unpack(const char *s,struct tai *t) { uint64 x; x = (unsigned char) s[0]; x <<= 8; x += (unsigned char) s[1]; x <<= 8; x += (unsigned char) s[2]; x <<= 8; x += (unsigned char) s[3]; x <<= 8; x += (unsigned char) s[4]; x <<= 8; x += (unsigned char) s[5]; x <<= 8; x += (unsigned char) s[6]; x <<= 8; x += (unsigned char) s[7]; t->x = x; } net/ipsvd-1.0.0/src/taia.h0000644000000000000000000000174211025276022014000 0ustar rootroot/* Public domain. */ #ifndef TAIA_H #define TAIA_H #include "tai.h" struct taia { struct tai sec; unsigned long nano; /* 0...999999999 */ unsigned long atto; /* 0...999999999 */ } ; extern void taia_tai(const struct taia *,struct tai *); extern void taia_now(struct taia *); extern double taia_approx(const struct taia *); extern double taia_frac(const struct taia *); extern void taia_add(struct taia *,const struct taia *,const struct taia *); extern void taia_addsec(struct taia *,const struct taia *,int); extern void taia_sub(struct taia *,const struct taia *,const struct taia *); extern void taia_half(struct taia *,const struct taia *); extern int taia_less(const struct taia *,const struct taia *); #define TAIA_PACK 16 extern void taia_pack(char *,const struct taia *); extern void taia_unpack(const char *,struct taia *); #define TAIA_FMTFRAC 19 extern unsigned int taia_fmtfrac(char *,const struct taia *); extern void taia_uint(struct taia *,unsigned int); #endif net/ipsvd-1.0.0/src/taia_add.c0000644000000000000000000000063111025276022014577 0ustar rootroot/* Public domain. */ #include "taia.h" /* XXX: breaks tai encapsulation */ void taia_add(struct taia *t,const struct taia *u,const struct taia *v) { t->sec.x = u->sec.x + v->sec.x; t->nano = u->nano + v->nano; t->atto = u->atto + v->atto; if (t->atto > 999999999UL) { t->atto -= 1000000000UL; ++t->nano; } if (t->nano > 999999999UL) { t->nano -= 1000000000UL; ++t->sec.x; } } net/ipsvd-1.0.0/src/taia_approx.c0000644000000000000000000000020311025276022015353 0ustar rootroot/* Public domain. */ #include "taia.h" double taia_approx(const struct taia *t) { return tai_approx(&t->sec) + taia_frac(t); } net/ipsvd-1.0.0/src/taia_frac.c0000644000000000000000000000021611025276022014761 0ustar rootroot/* Public domain. */ #include "taia.h" double taia_frac(const struct taia *t) { return (t->atto * 0.000000001 + t->nano) * 0.000000001; } net/ipsvd-1.0.0/src/taia_less.c0000644000000000000000000000046711025276022015024 0ustar rootroot/* Public domain. */ #include "taia.h" /* XXX: breaks tai encapsulation */ int taia_less(const struct taia *t,const struct taia *u) { if (t->sec.x < u->sec.x) return 1; if (t->sec.x > u->sec.x) return 0; if (t->nano < u->nano) return 1; if (t->nano > u->nano) return 0; return t->atto < u->atto; } net/ipsvd-1.0.0/src/taia_now.c0000644000000000000000000000044111025276022014651 0ustar rootroot/* Public domain. */ #include #include #include #include "taia.h" void taia_now(struct taia *t) { struct timeval now; gettimeofday(&now,(struct timezone *) 0); tai_unix(&t->sec,now.tv_sec); t->nano = 1000 * now.tv_usec + 500; t->atto = 0; } net/ipsvd-1.0.0/src/taia_pack.c0000644000000000000000000000055011025276022014765 0ustar rootroot/* Public domain. */ #include "taia.h" void taia_pack(char *s,const struct taia *t) { unsigned long x; tai_pack(s,&t->sec); s += 8; x = t->atto; s[7] = x & 255; x >>= 8; s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; s[4] = x; x = t->nano; s[3] = x & 255; x >>= 8; s[2] = x & 255; x >>= 8; s[1] = x & 255; x >>= 8; s[0] = x; } net/ipsvd-1.0.0/src/taia_sub.c0000644000000000000000000000071411025276022014642 0ustar rootroot/* Public domain. */ #include "taia.h" /* XXX: breaks tai encapsulation */ void taia_sub(struct taia *t,const struct taia *u,const struct taia *v) { unsigned long unano = u->nano; unsigned long uatto = u->atto; t->sec.x = u->sec.x - v->sec.x; t->nano = unano - v->nano; t->atto = uatto - v->atto; if (t->atto > uatto) { t->atto += 1000000000UL; --t->nano; } if (t->nano > unano) { t->nano += 1000000000UL; --t->sec.x; } } net/ipsvd-1.0.0/src/taia_uint.c0000644000000000000000000000025611025276022015031 0ustar rootroot/* Public domain. */ #include "taia.h" /* XXX: breaks tai encapsulation */ void taia_uint(struct taia *t,unsigned int s) { t->sec.x = s; t->nano = 0; t->atto = 0; } net/ipsvd-1.0.0/src/tcpsvd.c0000644000000000000000000003054611025276022014364 0ustar rootroot#include #include #include #include #include "dns.h" #include "socket.h" #include "ip4.h" #include "ipsvd_check.h" #include "ipsvd_log.h" #include "ipsvd_fmt.h" #include "ipsvd_hostname.h" #include "ipsvd_phcc.h" #include "ipsvd_scan.h" #include "uidgid.h" #include "str.h" #include "byte.h" #include "error.h" #include "strerr.h" #include "sgetopt.h" #include "scan.h" #include "fmt.h" #include "sig.h" #include "fd.h" #include "wait.h" #include "prot.h" #include "pathexec.h" #include "ndelay.h" #ifdef SSLSVD #include "matrixSsl.h" #include "ssl_io.h" #endif #ifdef SSLSVD #define USAGE " [-Ehpv] [-u user] [-c n] [-C n:msg] [-b n] [-l name] [-i dir|-x cdb] [-t sec] [-U ssluser] [-/ root] [-Z cert] [-K key] host port prog" #else #define USAGE " [-Ehpv] [-u user] [-c n] [-C n:msg] [-b n] [-l name] [-i dir|-x cdb] [-t sec] host port prog" #endif #define VERSION "$Id: 4f21b1c1026b4c301191b8ee0bc43f3f9090d52c $" #define FATAL "tcpsvd: fatal: " #define WARNING "tcpsvd: warning: " #define INFO "tcpsvd: info: " #define DROP "tcpsvd: drop: " char *progname; unsigned int lookuphost =0; unsigned int verbose =0; unsigned long backlog =20; unsigned int paranoid =0; const char **prog; unsigned long cnum =0; unsigned long cmax =30; unsigned long timeout =0; unsigned int ucspi =1; const char *instructs =0; unsigned int iscdb =0; static stralloc local_hostname ={0}; char local_ip[IP4_FMT]; char *local_port; static stralloc remote_hostname ={0}; char remote_ip[IP4_FMT]; char remote_port[FMT_ULONG]; #ifdef SSLSVD #else struct uidgid ugid; #endif static char seed[128]; char bufnum[FMT_ULONG]; struct sockaddr_in socka; int socka_size; unsigned int phcc =0; static stralloc sa ={0}; static stralloc ips ={0}; static stralloc fqdn ={0}; static stralloc inst ={0}; static stralloc match ={0}; static stralloc msg ={0}; void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); } void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); } void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); } void fatal2(char *m0, char *m1) { strerr_die5sys(111, FATAL, m0, ": ", m1, ": "); } void warn(char *m0) { strerr_warn3(WARNING, m0, ": ", &strerr_sys); } void warn2(char *m0, char *m1) { strerr_warn5(WARNING, m0, ": ", m1, ": ", &strerr_sys); } void drop_nomem() { strerr_die2x(111, DROP, "out of memory."); } void drop(char *m0) { strerr_die3sys(111, DROP, m0, ": "); } void drop2(char *m0, char *m1) { strerr_die5sys(111, DROP, m0, ": ", m1, ": "); } void ucspi_env() { char *l =local_hostname.s; char *r =remote_hostname.s; /* setup ucspi env */ if (! pathexec_env("PROTO", "TCP")) drop_nomem(); if (! pathexec_env("TCPLOCALIP", local_ip)) drop_nomem(); if (! pathexec_env("TCPLOCALPORT", local_port)) drop_nomem(); if (! pathexec_env("TCPLOCALHOST", *l ? l : 0)) drop_nomem(); if (! pathexec_env("TCPREMOTEIP", remote_ip)) drop_nomem(); if (! pathexec_env("TCPREMOTEPORT", remote_port)) drop_nomem(); if (! pathexec_env("TCPREMOTEHOST", *r ? r : 0)) drop_nomem(); if (! pathexec_env("TCPREMOTEINFO", 0)) drop_nomem(); /* additional */ if (phcc > 0) { bufnum[fmt_ulong(bufnum, phcc)] =0; if (! pathexec_env("TCPCONCURRENCY", bufnum)) drop_nomem(); } } void connection_status() { bufnum[fmt_ulong(bufnum, cnum)] =0; out(INFO); out("status "); out(bufnum); out("/"); bufnum[fmt_ulong(bufnum, cmax)] =0; out(bufnum); flush("\n"); } void sig_term_handler() { if (phccmax) ipsvd_phcc_free(); if (verbose) { out(INFO); flush("sigterm received, exit.\n"); } _exit(0); } void sig_child_handler() { int wstat; int i; while ((i =wait_nohang(&wstat)) > 0) { if (phccmax) ipsvd_phcc_rem(i); if (cnum) cnum--; if (verbose) { bufnum[fmt_ulong(bufnum, i)] =0; out(INFO); out("end "); out(bufnum); out(" exit "); bufnum[fmt_ulong(bufnum, (unsigned long)wait_exitcode(wstat))] =0; out(bufnum); flush("\n"); } } if (verbose) connection_status(); } void connection_accept(int c) { int ac; const char **run; const char *args[4]; char *ip =(char*)&socka.sin_addr; remote_ip[ipsvd_fmt_ip(remote_ip, ip)] =0; if (verbose) { out(INFO); out("pid "); bufnum[fmt_ulong(bufnum, getpid())] =0; out(bufnum); out(" from "); outfix(remote_ip); flush("\n"); } remote_port[ipsvd_fmt_port(remote_port, (char*)&socka.sin_port)] =0; if (lookuphost) { if (ipsvd_hostname(&remote_hostname, ip, paranoid) == -1) warn2("unable to look up hostname", remote_ip); if (! stralloc_0(&remote_hostname)) drop_nomem(); } socka_size =sizeof(socka); if (getsockname(c, (struct sockaddr*)&socka, &socka_size) == -1) drop("unable to get local address"); if (! local_hostname.len) { if (dns_name4(&local_hostname, (char*)&socka.sin_addr) == -1) drop("unable to look up local hostname"); if (! stralloc_0(&local_hostname)) die_nomem(); } local_ip[ipsvd_fmt_ip(local_ip, (char*)&socka.sin_addr)] =0; if (ucspi) ucspi_env(); if (instructs) { ac =ipsvd_check(iscdb, &inst, &match, (char*)instructs, remote_ip, remote_hostname.s, timeout); if (ac == -1) drop2("unable to check inst", remote_ip); if (ac == IPSVD_ERR) drop2("unable to read", (char*)instructs); } else ac =IPSVD_DEFAULT; if (phccmax) { if (phcc > phccmax) { ac =IPSVD_DENY; if (phccmsg) { ndelay_on(c); if (write(c, phccmsg, str_len(phccmsg)) == -1) warn("unable to write concurrency message"); } } if (verbose) { bufnum[fmt_ulong(bufnum, getpid())] =0; out(INFO); out("concurrency "); out(bufnum); out(" "); outfix(remote_ip); out(" "); bufnum[fmt_ulong(bufnum, phcc)] =0; out(bufnum); out("/"); bufnum[fmt_ulong(bufnum, phccmax)] =0; out(bufnum); out("\n"); } } if (verbose) { out(INFO); switch(ac) { case IPSVD_DENY: out("deny "); break; case IPSVD_DEFAULT: case IPSVD_INSTRUCT: out("start "); break; case IPSVD_EXEC: out("exec "); break; } bufnum[fmt_ulong(bufnum, getpid())] =0; out(bufnum); out(" "); outfix(local_hostname.s); out(":"); out(local_ip); out(" :"); outfix(remote_hostname.s); out(":"); outfix(remote_ip); out(":"); outfix(remote_port); if (instructs) { out(" "); if (iscdb) { out((char*)instructs); out("/"); } outfix(match.s); if(inst.s && inst.len && (verbose > 1)) { out(": "); outinst(&inst); } } flush("\n"); } if (ac == IPSVD_DENY) { close(c); _exit(100); } if (ac == IPSVD_EXEC) { args[0] ="/bin/sh"; args[1] ="-c"; args[2] =inst.s; args[3] =0; run =args; } else run =prog; if ((fd_move(0, c) == -1) || (fd_copy(1, 0) == -1)) drop("unable to set filedescriptor"); sig_uncatch(sig_term); sig_uncatch(sig_pipe); sig_uncatch(sig_child); sig_unblock(sig_child); #ifdef SSLSVD pid =getpid(); id[fmt_ulong(id, pid)] =0; ssl_io(0, run); #else pathexec(run); #endif drop2("unable to run", (char *)*prog); } int main(int argc, char **argv) { int opt; char *user =0; char *host; unsigned long port; int pid; int s; int conn; int delim; progname =*argv; phccmax =0; #ifdef SSLSVD while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vVU:/:Z:K:")) != opteof) { #else while ((opt =getopt(argc, (const char **)argv, "c:C:i:x:u:l:Eb:hpt:vV")) != opteof) { #endif switch(opt) { case 'c': scan_ulong(optarg, &cmax); if (cmax < 1) usage(); break; case 'C': delim =scan_ulong(optarg, &phccmax); if (phccmax < 1) usage(); if (optarg[delim] == ':') { if (ipsvd_fmt_msg(&msg, optarg +delim +1) == -1) die_nomem(); if (! stralloc_0(&msg)) die_nomem(); phccmsg =msg.s; } break; case 'i': if (instructs) usage(); instructs =optarg; break; case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break; case 'u': user =(char*)optarg; break; case 'l': if (! stralloc_copys(&local_hostname, optarg)) die_nomem(); if (! stralloc_0(&local_hostname)) die_nomem(); break; case 'E': ucspi =0; break; case 'b': scan_ulong(optarg, &backlog); break; case 'h': lookuphost =1; break; case 'p': lookuphost =1; paranoid =1; break; case 't': scan_ulong(optarg, &timeout); break; case 'v': ++verbose; break; #ifdef SSLSVD case 'U': ssluser =(char*)optarg; break; case '/': root =(char*)optarg; break; case 'Z': cert =(char*)optarg; break; case 'K': key =(char*)optarg; break; #endif case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); host =*argv++; if (! argv || ! *argv) usage(); local_port =*argv++; if (! argv || ! *argv) usage(); prog =(const char **)argv; if (phccmax > cmax) phccmax =cmax; if (user) if (! uidgids_get(&ugid, user)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", user, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", user); } #ifdef SSLSVD svuser =user; client =0; if ((getuid() == 0) && (! ssluser)) strerr_die2x(100, FATAL, "-U ssluser must be set when running as root"); if (ssluser) if (! uidgids_get(&sslugid, ssluser)) { if (errno) strerr_die4sys(111, FATAL, "unable to get user/group: ", ssluser, ": "); strerr_die3x(100, FATAL, "unknown user/group: ", ssluser); } if (! cert) cert ="./cert.pem"; if (! key) key =cert; if (matrixSslOpen() < 0) fatal("unable to initialize ssl"); if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) { if (client) fatal("unable to read cert, key, or ca file"); fatal("unable to read cert or key file"); } if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0) strerr_die2x(111, FATAL, "unable to create ssl session"); #endif dns_random_init(seed); sig_block(sig_child); sig_catch(sig_child, sig_child_handler); sig_catch(sig_term, sig_term_handler); sig_ignore(sig_pipe); if (phccmax) if (ipsvd_phcc_init(cmax) == -1) die_nomem(); if (str_equal(host, "")) host ="0.0.0.0"; if (str_equal(host, "0")) host ="0.0.0.0"; if (! ipsvd_scan_port(local_port, "tcp", &port)) strerr_die3x(100, FATAL, "unknown port number or name: ", local_port); if (! stralloc_copys(&sa, host)) die_nomem(); if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4)) if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1) fatal2("unable to look up ip address", host); if (ips.len < 4) strerr_die3x(100, FATAL, "unable to look up ip address: ", host); ips.len =4; if (! stralloc_0(&ips)) die_nomem(); local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0; if (! lookuphost) { if (! stralloc_copys(&remote_hostname, "")) die_nomem(); if (! stralloc_0(&remote_hostname)) die_nomem(); } if ((s =socket_tcp()) == -1) fatal("unable to create socket"); if (socket_bind4_reuse(s, ips.s, port) == -1) fatal("unable to bind socket"); if (listen(s, backlog) == -1) fatal("unable to listen"); ndelay_off(s); #ifdef SSLSVD #else if (user) { /* drop permissions */ if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups"); if (setgid(*ugid.gid) == -1) fatal("unable to set gid"); if (prot_uid(ugid.uid) == -1) fatal("unable to set uid"); } #endif close(0); if (verbose) { out(INFO); out("listening on "); outfix(local_ip); out(":"); outfix(local_port); #ifdef SSLSVD #else if (user) { bufnum[fmt_ulong(bufnum, (unsigned long)ugid.uid)] =0; out(", uid "); out(bufnum); bufnum[fmt_ulong(bufnum, (unsigned long)ugid.gid)] =0; out(", gid "); out(bufnum); } #endif flush(", starting.\n"); } for (;;) { while (cnum >= cmax) sig_pause(); socka_size =sizeof(socka); sig_unblock(sig_child); conn =accept(s, (struct sockaddr *)&socka, &socka_size); sig_block(sig_child); if (conn == -1) { if (errno != error_intr) warn("unable to accept connection"); continue; } cnum++; if (verbose) connection_status(); if (phccmax) phcc =ipsvd_phcc_add((char*)&socka.sin_addr); if ((pid =fork()) == -1) { warn2("drop connection", "unable to fork"); close(conn); continue; } if (pid == 0) { /* child */ close(s); #ifdef SSLSVD if (*progname) *progname ='\\'; #endif connection_accept(conn); } if (phccmax) ipsvd_phcc_setpid(pid); close(conn); } _exit(0); } net/ipsvd-1.0.0/src/tcpsvd.check0000755000000000000000000000046211025276022015214 0ustar rootroot#!/bin/sh rm -rf "${ctmp}" tcpsvd echo $? tcpsvd -V echo $? mkdir "${ctmp}" tcpsvd -llocalhost -i"${ctmp}" 127.0.0.1 12614 sh -c 'cat >&2' & pid=$! sleep 1 echo "sh -c 'echo foo >&2; cat >&2'" >"${ctmp}"/127.0 chmod 0755 "${ctmp}"/127.0 check-tcpsvd sleep 3 kill -TERM $pid wait echo $? rm -rf "${ctmp}" net/ipsvd-1.0.0/src/tcpsvd.dist0000644000000000000000000000043211025276022015074 0ustar rootrootusage: tcpsvd [-Ehpv] [-u user] [-c n] [-C n:msg] [-b n] [-l name] [-i dir|-x cdb] [-t sec] host port prog 111 $Id: 4f21b1c1026b4c301191b8ee0bc43f3f9090d52c $ usage: tcpsvd [-Ehpv] [-u user] [-c n] [-C n:msg] [-b n] [-l name] [-i dir|-x cdb] [-t sec] host port prog 111 foo bar 0 net/ipsvd-1.0.0/src/test.c0000644000000000000000000000077111025276022014035 0ustar rootroot#include "dns.h" int main () { stralloc out ={0}; stralloc sa ={0}; char ip[4]; char *dn =0; stralloc_copys(&sa, "abcdefg"); dns_ip4(&out, &sa); dns_ip4_qualify(&out, &sa, &sa); dns_name4(&out, ip); dns_mx(&out, &sa); dns_txt(&out, &sa); dns_domain_length(sa.s); dns_domain_equal(sa.s, sa.s); dns_domain_copy(&dn, sa.s); dns_domain_fromdot(&dn, sa.s, sa.len); return 0; } net/ipsvd-1.0.0/src/trycpp.c0000644000000000000000000000017111025276022014371 0ustar rootroot/* Public domain. */ int main() { #ifdef NeXT printf("nextstep\n"); exit(0); #endif printf("unknown\n"); exit(0); } net/ipsvd-1.0.0/src/trydrent.c0000644000000000000000000000016111025276022014722 0ustar rootroot/* Public domain. */ #include #include void foo() { DIR *dir; struct dirent *d; } net/ipsvd-1.0.0/src/tryflock.c0000644000000000000000000000021211025276022014701 0ustar rootroot/* Public domain. */ #include #include #include main() { flock(0,LOCK_EX | LOCK_UN | LOCK_NB); } net/ipsvd-1.0.0/src/trymkffo.c0000644000000000000000000000016111025276022014710 0ustar rootroot/* Public domain. */ #include #include void main() { mkfifo("temp-trymkffo",0); } net/ipsvd-1.0.0/src/trypoll.c0000644000000000000000000000054611025276022014563 0ustar rootroot/* Public domain. */ #include #include #include int main() { struct pollfd x; x.fd = open("trypoll.c",O_RDONLY); if (x.fd == -1) _exit(111); x.events = POLLIN; if (poll(&x,1,10) == -1) _exit(1); if (x.revents != POLLIN) _exit(1); /* XXX: try to detect and avoid poll() imitation libraries */ _exit(0); } net/ipsvd-1.0.0/src/trysgact.c0000644000000000000000000000027411025276022014714 0ustar rootroot/* Public domain. */ #include main() { struct sigaction sa; sa.sa_handler = 0; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(0,&sa,(struct sigaction *) 0); } net/ipsvd-1.0.0/src/trysgprm.c0000644000000000000000000000024311025276022014737 0ustar rootroot/* Public domain. */ #include main() { sigset_t ss; sigemptyset(&ss); sigaddset(&ss,SIGCHLD); sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0); } net/ipsvd-1.0.0/src/tryshsgr.c0000644000000000000000000000044111025276022014735 0ustar rootroot/* Public domain. */ int main() { short x[4]; x[0] = x[1] = 1; if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); if (getgroups(1,x) == -1) _exit(1); if (x[1] != 1) _exit(1); x[1] = 2; if (getgroups(1,x) == -1) _exit(1); if (x[1] != 2) _exit(1); _exit(0); } net/ipsvd-1.0.0/src/trysocketlib.c0000644000000000000000000000031211025276022015563 0ustar rootroot#include #include #include #include #include int main(void) { int s; s =socket(AF_INET, SOCK_STREAM, 0); return(close(s)); } net/ipsvd-1.0.0/src/trysysel.c0000644000000000000000000000022611025276022014747 0ustar rootroot/* Public domain. */ #include #include #include #include /* SVR4 silliness */ void foo() { ; } net/ipsvd-1.0.0/src/tryulong32.c0000644000000000000000000000052311025276022015101 0ustar rootrootint main() { unsigned long u; u = 1; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; if (!u) _exit(0); _exit(1); } net/ipsvd-1.0.0/src/tryulong64.c0000644000000000000000000000055111025276022015107 0ustar rootroot/* Public domain. */ int main() { unsigned long u; u = 1; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; if (!u) _exit(1); _exit(0); } net/ipsvd-1.0.0/src/trywaitp.c0000644000000000000000000000014111025276022014730 0ustar rootroot/* Public domain. */ #include #include main() { waitpid(0,0,0); } net/ipsvd-1.0.0/src/udpsvd.c0000644000000000000000000001770111025276022014364 0ustar rootroot#include #include #include #include #include "dns.h" #include "socket.h" #include "ip4.h" #include "ipsvd_log.h" #include "ipsvd_check.h" #include "ipsvd_fmt.h" #include "ipsvd_hostname.h" #include "ipsvd_scan.h" #include "uidgid.h" #include "sgetopt.h" #include "sig.h" #include "str.h" #include "fmt.h" #include "error.h" #include "strerr.h" #include "prot.h" #include "ndelay.h" #include "scan.h" #include "fd.h" #include "wait.h" #include "pathexec.h" #define USAGE " [-hpv] [-u user] [-l name] [-i dir|-x cdb] [-t sec] host port prog" #define VERSION "$Id: 4991b38bba93e925f0772eaf9b0b96f5788b009a $" #define FATAL "udpsvd: fatal: " #define WARNING "udpsvd: warning: " #define INFO "udpsvd: info: " #define DROP "udpsvd: drop: " const char *progname; const char **prog; const char *instructs =0; unsigned int iscdb =0; unsigned int verbose =0; unsigned int lookuphost =0; unsigned int paranoid =0; unsigned long timeout =0; static stralloc local_hostname ={0}; char local_ip[IP4_FMT]; char *local_port; static stralloc remote_hostname ={0}; char remote_ip[IP4_FMT]; char remote_port[FMT_ULONG]; struct uidgid ugid; static char seed[128]; struct sockaddr_in socka; int socka_size =sizeof(socka); char bufnum[FMT_ULONG]; int s; static stralloc sa ={0}; static stralloc ips ={0}; static stralloc fqdn ={0}; static stralloc inst ={0}; static stralloc match ={0}; void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); } void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); } void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); }; void fatal2(char *m0, char *m1) { strerr_die5sys(111, FATAL, m0, ": ", m1, ": "); } void warn(char *m0) { strerr_warn3(WARNING, m0, ": ", &strerr_sys); } void warn2(char *m0, char *m1) { strerr_warn5(WARNING, m0, ": ", m1, ": ", &strerr_sys); } void drop_nomem() { strerr_die2x(111, DROP, "out of memory."); } void drop(char *m0) { strerr_die3sys(111, DROP, m0, ": "); } void discard(char *m0, char *m1) { recv(s, 0, 0, 0); strerr_die6sys(111, DROP, "discard data: ", m0, ": ", m1, ": "); } void sig_term_handler() { if (verbose) { out(INFO); flush("sigterm received, exit.\n"); } _exit(0); } void connection_accept(int c) { int ac; const char **run; const char *args[4]; char *ip =(char*)&socka.sin_addr; remote_ip[ipsvd_fmt_ip(remote_ip, ip)] =0; if (verbose) { out(INFO); out("pid "); bufnum[fmt_ulong(bufnum, getpid())] =0; out(bufnum); out(" from "); outfix(remote_ip); flush("\n"); } remote_port[ipsvd_fmt_port(remote_port, (char*)&socka.sin_port)] =0; if (lookuphost) { if (ipsvd_hostname(&remote_hostname, ip, paranoid) == -1) warn2("unable to look up hostname", remote_ip); if (! stralloc_0(&remote_hostname)) drop_nomem(); } if (instructs) { ac =ipsvd_check(iscdb, &inst, &match, (char*)instructs, remote_ip, remote_hostname.s, timeout); if (ac == -1) discard("unable to check inst", remote_ip); if (ac == IPSVD_ERR) discard("unable to read", (char*)instructs); } else ac =IPSVD_DEFAULT; if (verbose) { out(INFO); switch(ac) { case IPSVD_DENY: out("deny "); break; case IPSVD_DEFAULT: case IPSVD_INSTRUCT: out("start "); break; case IPSVD_EXEC: out("exec "); break; } bufnum[fmt_ulong(bufnum, getpid())] =0; out(bufnum); out(" "); outfix(local_hostname.s); out(":"); out(local_ip); out(" :"); outfix(remote_hostname.s); out(":"); outfix(remote_ip); out(":"); outfix(remote_port); if (instructs) { out(" "); if (iscdb) { out((char*)instructs); out("/"); } outfix(match.s); if(inst.s && inst.len && (verbose > 1)) { out(": "); outinst(&inst); } } flush("\n"); } if (ac == IPSVD_DENY) { recv(s, 0, 0, 0); _exit(100); } if (ac == IPSVD_EXEC) { args[0] ="/bin/sh"; args[1] ="-c"; args[2] =inst.s; args[3] =0; run =args; } else run =prog; if ((fd_move(0, c) == -1) || (fd_copy(1, 2) == -1)) drop("unable to set filedescriptor"); sig_uncatch(sig_term); sig_uncatch(sig_pipe); pathexec(run); discard("unable to run", (char*)*prog); } int main(int argc, const char **argv, const char *const *envp) { int opt; char *user =0; char *host; unsigned long port; int pid; int wstat; iopause_fd io[1]; struct taia now; struct taia deadline; progname =*argv; while ((opt =getopt(argc, argv, "vu:l:hpi:x:t:V")) != opteof) { switch(opt) { case 'v': ++verbose; break; case 'u': user =(char*)optarg; break; case 'l': if (! stralloc_copys(&local_hostname, optarg)) die_nomem(); if (! stralloc_0(&local_hostname)) die_nomem(); break; case 'h': lookuphost =1; break; case 'p': lookuphost =1; paranoid =1; break; case 'i': if (instructs) usage(); instructs =optarg; break; case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break; case 't': scan_ulong(optarg, &timeout); break; case 'V': strerr_warn1(VERSION, 0); case '?': usage(); } } argv +=optind; if (! argv || ! *argv) usage(); host =(char*)*argv++; if (! argv || ! *argv) usage(); local_port =(char*)*argv++; if (! argv || ! *argv) usage(); prog =argv; if (user) if (! uidgids_get(&ugid, user)) strerr_die3x(100, FATAL, "unknown user/group: ", user); dns_random_init(seed); sig_catch(sig_term, sig_term_handler); sig_ignore(sig_pipe); if (str_equal(host, "")) host ="0.0.0.0"; if (str_equal(host, "0")) host ="0.0.0.0"; if (! ipsvd_scan_port(local_port, "udp", &port)) strerr_die3x(100, FATAL, "unknown port number or name: ", local_port); if (! stralloc_copys(&sa, host)) die_nomem(); if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4)) if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1) fatal2("unable to look up ip address", host); if (ips.len < 4) strerr_die3x(100, FATAL, "unable to look up ip address: ", host); ips.len =4; if (! stralloc_0(&ips)) die_nomem(); local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0; if (! local_hostname.len) { if (dns_name4(&local_hostname, ips.s) == -1) fatal("unable to look up local hostname"); if (! stralloc_0(&local_hostname)) die_nomem(); } if (! lookuphost) { if (! stralloc_copys(&remote_hostname, "")) die_nomem(); if (! stralloc_0(&remote_hostname)) die_nomem(); } if ((s =socket_udp()) == -1) fatal("unable to create socket"); if (socket_bind4_reuse(s, ips.s, port) == -1) fatal("unable to bind socket"); ndelay_off(s); if (user) { /* drop permissions */ if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups"); if (setgid(*ugid.gid) == -1) fatal("unable to set gid"); if (prot_uid(ugid.uid) == -1) fatal("unable to set uid"); } close(0); if (verbose) { out(INFO); out("listening on "); outfix(local_ip); out(":"); outfix(local_port); if (user) { bufnum[fmt_ulong(bufnum, ugid.uid)] =0; out(", uid "); out(bufnum); bufnum[fmt_ulong(bufnum, ugid.gid)] =0; out(", gid "); out(bufnum); } flush(", starting.\n"); } io[0].fd =s; io[0].events =IOPAUSE_READ; io[0].revents =0; for (;;) { taia_now(&now); taia_uint(&deadline, 3600); taia_add(&deadline, &now, &deadline); iopause(io, 1, &deadline, &now); if (io[0].revents | IOPAUSE_READ) { io[0].revents =0; while ((pid =fork()) == -1) { warn("unable to fork, sleeping"); sleep(5); } if (pid == 0) { /* child */ if (recvfrom(s, 0, 0, MSG_PEEK, (struct sockaddr *)&socka, &socka_size) == -1) drop("unable to read from socket"); connection_accept(s); } while (wait_pid(&wstat, pid) == -1) warn("error waiting for child"); if (verbose) { out(INFO); out("end "); bufnum[fmt_ulong(bufnum, pid)] =0; out(bufnum); flush("\n"); } } } _exit(0); } net/ipsvd-1.0.0/src/udpsvd.check0000755000000000000000000000047411025276022015221 0ustar rootroot#!/bin/sh rm -rf "${ctmp}" udpsvd echo $? udpsvd -V echo $? mkdir "${ctmp}" udpsvd -llocalhost -i"${ctmp}" 127.0.0.1 12614 sh -c 'head -n1 >&2' & pid=$! sleep 1 echo "sh -c 'head -n1 >&2; echo bar >&2'" >"${ctmp}"/127.0 chmod 0755 "${ctmp}"/127.0 check-udpsvd sleep 3 kill -TERM $pid wait echo $? rm -rf "${ctmp}" net/ipsvd-1.0.0/src/udpsvd.dist0000644000000000000000000000034611025276022015102 0ustar rootrootusage: udpsvd [-hpv] [-u user] [-l name] [-i dir|-x cdb] [-t sec] host port prog 111 $Id: 4991b38bba93e925f0772eaf9b0b96f5788b009a $ usage: udpsvd [-hpv] [-u user] [-l name] [-i dir|-x cdb] [-t sec] host port prog 111 foo bar 0 net/ipsvd-1.0.0/src/uidgid.c0000644000000000000000000000301111025276022014311 0ustar rootroot#include #include #include #include "uidgid.h" #include "str.h" #include "scan.h" /* user */ unsigned int uidgid_get(struct uidgid *u, char *ug) { struct passwd *pwd =0; if (! (pwd =getpwnam(ug))) return(0); u->gid[0] =pwd->pw_gid; u->gids =1; u->uid =pwd->pw_uid; return(1); } /* uid:gid[:gid[:gid]...] */ unsigned int uidgids_set(struct uidgid *u, char *ug) { unsigned long id; int i; if (*(ug +=scan_ulong(ug, &id)) != ':') return(0); u->uid =(uid_t)id; ++ug; for (i =0; i < 60; ++i, ++ug) { ug +=scan_ulong(ug, &id); u->gid[i] =(gid_t)id; if (*ug != ':') { ++i; break; } } u->gid[i] =0; u->gids =i; if (*ug) return(0); return(1); } /* [:]user[:group[:group]...] */ unsigned int uidgids_get(struct uidgid *u, char *ug) { char *g =0; struct passwd *pwd =0; struct group *gr =0; int i, d =0; if (*ug == ':') return(uidgids_set(u, ug +1)); if (ug[(d =str_chr(ug, ':'))] == ':') { ug[d] =0; g =ug +d +1; } if (! (pwd =getpwnam(ug))) { if (g) ug[d] =':'; return(0); } u->uid =pwd->pw_uid; if (! g) { u->gid[0] =pwd->pw_gid; u->gids =1; return(1); } ug[d] =':'; for (i =0; i < 60; ++i) { if (g[(d =str_chr(g, ':'))] == ':') { g[d] =0; if (! (gr =getgrnam(g))) { g[d] =':'; return(0); } g[d] =':'; u->gid[i] =gr->gr_gid; g +=d +1; } else { if (! (gr =getgrnam(g))) return(0); u->gid[i++] =gr->gr_gid; break; } } u->gid[i] =0; u->gids =i; return(1); } net/ipsvd-1.0.0/src/uidgid.h0000644000000000000000000000044111025276022014322 0ustar rootroot#ifndef UIDGID_H #define UIDGID_H #include struct uidgid { uid_t uid; gid_t gid[61]; int gids; }; /* user */ extern unsigned int uidgid_get(struct uidgid *, char *); /* [:]user[:group[:group]...] */ extern unsigned int uidgids_get(struct uidgid *, char *); #endif net/ipsvd-1.0.0/src/uint16.h0000644000000000000000000000040711025276022014205 0ustar rootroot#ifndef UINT16_H #define UINT16_H typedef unsigned short uint16; extern void uint16_pack(char *,uint16); extern void uint16_pack_big(char *,uint16); extern void uint16_unpack(const char *,uint16 *); extern void uint16_unpack_big(const char *,uint16 *); #endif net/ipsvd-1.0.0/src/uint16_pack.c0000644000000000000000000000026211025276022015175 0ustar rootroot#include "uint16.h" void uint16_pack(char s[2],uint16 u) { s[0] = u & 255; s[1] = u >> 8; } void uint16_pack_big(char s[2],uint16 u) { s[1] = u & 255; s[0] = u >> 8; } net/ipsvd-1.0.0/src/uint16_unpack.c0000644000000000000000000000055011025276022015540 0ustar rootroot#include "uint16.h" void uint16_unpack(const char s[2],uint16 *u) { uint16 result; result = (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[0]; *u = result; } void uint16_unpack_big(const char s[2],uint16 *u) { uint16 result; result = (unsigned char) s[0]; result <<= 8; result += (unsigned char) s[1]; *u = result; } net/ipsvd-1.0.0/src/uint32.h10000644000000000000000000000040511025276022014262 0ustar rootroot#ifndef UINT32_H #define UINT32_H typedef unsigned int uint32; extern void uint32_pack(char *,uint32); extern void uint32_pack_big(char *,uint32); extern void uint32_unpack(const char *,uint32 *); extern void uint32_unpack_big(const char *,uint32 *); #endif net/ipsvd-1.0.0/src/uint32.h20000644000000000000000000000040611025276022014264 0ustar rootroot#ifndef UINT32_H #define UINT32_H typedef unsigned long uint32; extern void uint32_pack(char *,uint32); extern void uint32_pack_big(char *,uint32); extern void uint32_unpack(const char *,uint32 *); extern void uint32_unpack_big(const char *,uint32 *); #endif net/ipsvd-1.0.0/src/uint32_pack.c0000644000000000000000000000044611025276022015177 0ustar rootroot#include "uint32.h" void uint32_pack(char s[4],uint32 u) { s[0] = u & 255; u >>= 8; s[1] = u & 255; u >>= 8; s[2] = u & 255; s[3] = u >> 8; } void uint32_pack_big(char s[4],uint32 u) { s[3] = u & 255; u >>= 8; s[2] = u & 255; u >>= 8; s[1] = u & 255; s[0] = u >> 8; } net/ipsvd-1.0.0/src/uint32_unpack.c0000644000000000000000000000106011025276022015533 0ustar rootroot#include "uint32.h" void uint32_unpack(const char s[4],uint32 *u) { uint32 result; result = (unsigned char) s[3]; result <<= 8; result += (unsigned char) s[2]; result <<= 8; result += (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[0]; *u = result; } void uint32_unpack_big(const char s[4],uint32 *u) { uint32 result; result = (unsigned char) s[0]; result <<= 8; result += (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[2]; result <<= 8; result += (unsigned char) s[3]; *u = result; } net/ipsvd-1.0.0/src/uint64.h10000644000000000000000000000017411025276022014272 0ustar rootroot/* Public domain. */ #ifndef UINT64_H #define UINT64_H /* sysdep: -ulong64 */ typedef unsigned long long uint64; #endif net/ipsvd-1.0.0/src/uint64.h20000644000000000000000000000016711025276022014275 0ustar rootroot/* Public domain. */ #ifndef UINT64_H #define UINT64_H /* sysdep: +ulong64 */ typedef unsigned long uint64; #endif net/ipsvd-1.0.0/src/wait.h0000644000000000000000000000047511025276022014030 0ustar rootroot/* Public domain. */ #ifndef WAIT_H #define WAIT_H extern int wait_pid(); extern int wait_nohang(); extern int wait_stop(); extern int wait_stopnohang(); #define wait_crashed(w) ((w) & 127) #define wait_exitcode(w) ((w) >> 8) #define wait_stopsig(w) ((w) >> 8) #define wait_stopped(w) (((w) & 127) == 127) #endif net/ipsvd-1.0.0/src/wait_nohang.c0000644000000000000000000000036711025276022015355 0ustar rootroot/* Public domain. */ #include #include #include "haswaitp.h" int wait_nohang(wstat) int *wstat; { #ifdef HASWAITPID return waitpid(-1,wstat,WNOHANG); #else return wait3(wstat,WNOHANG,(struct rusage *) 0); #endif } net/ipsvd-1.0.0/src/wait_pid.c0000644000000000000000000000133311025276022014651 0ustar rootroot/* Public domain. */ #include #include #include "error.h" #include "haswaitp.h" #ifdef HASWAITPID int wait_pid(wstat,pid) int *wstat; int pid; { int r; do r = waitpid(pid,wstat,0); while ((r == -1) && (errno == error_intr)); return r; } #else /* XXX untested */ /* XXX breaks down with more than two children */ static int oldpid = 0; static int oldwstat; /* defined if(oldpid) */ int wait_pid(wstat,pid) int *wstat; int pid; { int r; if (pid == oldpid) { *wstat = oldwstat; oldpid = 0; return pid; } do { r = wait(wstat); if ((r != pid) && (r != -1)) { oldwstat = *wstat; oldpid = r; continue; } } while ((r == -1) && (errno == error_intr)); return r; } #endif net/ipsvd-1.0.0/src/warn-auto.sh0000644000000000000000000000010011025276022015145 0ustar rootroot#!/bin/sh # WARNING: This file was auto-generated. Do not edit! net/ipsvd-1.0.0/src/warn-shsgr0000644000000000000000000000031311025276022014720 0ustar rootrootOops. Your getgroups() returned 0, and setgroups() failed; this means that I can't reliably do my shsgr test. Please either ``make'' as root or ``make'' while you're in one or more supplementary groups. net/ipsvd-1.0.0/src/x86cpuid.c0000644000000000000000000000121311025276022014520 0ustar rootroot/* Public domain. */ #include void nope() { exit(1); } int main() { unsigned long x[4]; unsigned long y[4]; int i; int j; char c; signal(SIGILL,nope); x[0] = 0; x[1] = 0; x[2] = 0; x[3] = 0; asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) ); if (!x[0]) return 0; asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) ); for (i = 1;i < 4;++i) for (j = 0;j < 4;++j) { c = x[i] >> (8 * j); if (c < 32) c = 32; if (c > 126) c = 126; putchar(c); } printf("-%08x-%08x\n",y[0],y[3]); return 0; } net/ipsvd-1.0.0/package/0000755000000000000000000000000011025276022013511 5ustar rootrootnet/ipsvd-1.0.0/package/CHANGES0000644000000000000000000003051611025276022014511 0ustar rootrootipsvd 1.0.0 Sun, 15 Jun 2008 17:45:26 +0000 ipsvd 0.14.0 Sat, 19 Jan 2008 00:17:20 +0000 * uidgid.c, uidgid.h: support numerical uid, gids through :uid:gid... (taken from the runit package). * tcpsvd.c, udpsvd.c, sslio.c, ssl_io.c: support numerical uid, gids, and colon-separated list of groups through :uid:gid... with the -u, -U arguments (thx Nikola Vladov). * man/tcpsvd.8, man/udpsvd.8, man/sslsvd.8, man/sslio.8, man/ipsvd.7: adapt. ipsvd 0.13.0 Sun, 26 Aug 2007 11:04:21 +0000 * ipsvd_check.c, man/ipsvd-instruct.5: lines starting with # are comments, ignore them completely. * ssl_io.c, man/sslio.8: support env variable SSLIO_BAD_CERTIFICATE to optionally accept 'bad certificate's (thx Nikola Vladov). * ssl_io.c, man/sslio.8, man/sslsvd.8: support env variable SSL_HANDSHAKE_TIMEOUT to disconnect a client if the ssl handshake isn't completed within some number of seconds (thx Nikola Vladov); add ENVIRONMENT section to man/sslsvd.8. * Makefile: build with matrixssl-1-8-3-open. ipsvd 0.12.1 Sat, 04 Feb 2006 19:14:23 +0000 * Makefile: fix build failure with local matrixssl library (thx Charlie Brady). ipsvd 0.12.0 Fri, 03 Feb 2006 20:26:27 +0000 * ssl_io.c, ssl_io.h: new; split off most code from sslio.c. * sslio.c: main() function only, uses ssl_io() from ssl_io. * tcpsvd.c: be sslsvd using ssl_io() #ifdef SSLSVD. * sslsvd.c: new; #define SSLSVD, #include tcpsvd.c. * man/sslsvd.8: new; man page for sslsvd(8). * man/ipsvd-cdb.8, man/ipsvd-instruct.5, man/ipsvd.7, man/sslio.8, man/tcpsvd.8, man/udpsvd.8: add SEE ALSO sslsvd(8). * sslsvd.check, sslsvd.dist: selftest for sslsvd not yet implemented. * doc/index.html: mention sslsvd. ipsvd 0.11.1 Tue, 18 Oct 2005 19:02:18 +0000 * sslio.check: tweak sslio program check (fixes testing failure on Debian m68k) * ipsvd_log.c: minor * Makefile, doc/install.html: adapt to matrixssl-1-7-1-open.tar.gz. ipsvd 0.11.0 Sun, 20 Feb 2005 16:13:38 +0000 * man/tcpsvd.8: typo (thx Bastian Kleineidam). * sslio.check, sslio.dist, sslio.pem: new; ssl program check. * Makefile: don't limit sslio program to linux systype; run ssl program check; minor * package/compile, package/upgrade: adapt. * doc/benefits.html, doc/index.html, doc/install.html: sslio works on MacOSX; adapt. ipsvd 0.10.1 Sun, 16 Jan 2005 10:34:19 +0000 * sslerror_str.c: fix build failure due to broken header include (thx Charlie Brady) * Makefile: target sslerror_str.o depends on matrixSsl.h. * sslio.c: minor. ipsvd 0.10.0 Sat, 15 Jan 2005 11:47:55 +0000 * doc/install.html: typo. * sslerror_str.c, sslerror_str.h: new; ssl error strings. * sslio.c: improve logging, error messages, use sslerror_str; new option -c client support to run under tcpclient. * uidgid.c: improve error handling. * Makefile, man/sslio.8: adapt. * package/versions: new. * package/COPYING: adapt, 2005. ipsvd 0.9.7 Fri, 03 Dec 2004 10:15:37 +0000 * ipsvd_check.c: catch all failures of openreadclose(); disregard hostnames (looked up in dns) starting with a dot; fix cdb check on check hostname instruction with non-existent forward to match instruction directory behavior (deny connection). * ipsvd_hostname.c: properly handle failure and nxdomain/noptr of dns_name4(). * doc/examples.html: minor. * tcpsvd.c: bug: socka didn't get updated after ECONNABORTED from accept(); fix: re-set socka_size for each connection (thx Sergei Kolobov). ipsvd 0.9.6 Mon, 02 Aug 2004 19:18:50 +0000 * sslio.c: minor cleanup; adapt few verbose log messages; detect successful handshake through matrixSslHandshakeIsComplete(). * doc/install.html, Makefile: use library from src/matrixssl.tar.gz. ipsvd 0.9.5 Wed, 14 Jul 2004 19:43:48 +0000 * man/sslio.8: notations. * ipsvd_check.c: only parse concurrency instruction if phcc is enabled. * tcpsvd.c: bug: concurrency instruction C0 denied connection, fix: C0 correctly disables phcc (thx Torne). * package/compile, package/install-man, package/upgrade: mkdir -p dir -> mkdir -p dir/.; ignore grep's return code (fixes build failure on solaris, thx Uffe Jakobsen). * Makefile: target check-tcpsvd, check-udpsvd: add libraries needed for socket() (fixes testing failure on solaris, thx Uffe Jakobsen); use matrixssl-1.1.2 with sslio. * doc/index.html: minor. ipsvd 0.9.4 Sat, 19 Jun 2004 14:47:09 +0000 * doc/benefits.html, man/tcpsvd.8: typos (thx David Thiel). * doc/install.html, Makefile: use matrixssl-1.1.1 with sslio. * tcpsvd.check, udpsvd.check: use -llocalhost. ipsvd 0.9.3 Wed, 02 Jun 2004 19:27:13 +0000 * sslio.c: end network connection when seeing eof from prog; adapt some verbose log messages. * doc/install.html, Makefile: use matrixssl-1.1 with sslio. ipsvd 0.9.2 Sat, 15 May 2004 14:11:54 +0000 * doc/examples.html: use html named entities; minor. * man/sslio.8: clarify that chroot is done before keys are read (thx Charlie Brady). * sslio.c: include ; ignore sig_pipe, catch sig_term; send ssl close alert on end of connection, and fatal errors. * use matrixssl-1-0-2. ipsvd 0.9.1 Mon, 03 May 2004 17:08:41 +0000 * Makefile, sslio.c: fix build failure due to broken header include (thx Charlie Brady). * doc/benefits.html: minor. ipsvd 0.9.0 Sat, 01 May 2004 14:29:26 +0000 * src/print-cc.sh, src/print-ld.sh: head -1 -> head -n1 (thx Richard A Downing). * sslio.c, man/sslio.8: new sslio program for Linux. * Makefile.matrixssl: new; conditionally build static library. * doc/benefits.html: new; some ipsvd's benefits. * package/check: run program testing process. * doc/examples.html: add sslio bincimaps, sslio fnord. * doc/index.html, doc/install.html: adapt. * package/compile, package/upgrade: conditionally build, install sslio. * package/install: run package/check. ipsvd 0.8.2 Mon, 23 Feb 2004 20:15:29 +0000 * man/ipsvd-instruct.5: on C0[:msg] per host concurrency is disabled (thx Charlie Brady). * ipsvd_fmt.c: fix bug in parsing phcc message not ending with escaped character. * check-tcpsvd.c, check-udpsvd.c, check-ipsvd-cdb.c: new. * ipsvd-cdb.check: don't echo \; use check-ipsvd-cdb. * tcpsvd.check: use check-tcpsvd. * udpsvd.check: use check-udpsvd. * tcpsvd.dist, udpsvd.dist, ipsvd-cdb.dist: adapt. ipsvd 0.8.1 Sun, 22 Feb 2004 14:40:31 +0000 * udpsvd: fix usage information output. * doc/upgrade.html: typo. * check-diff, check-dist, check-local: new; run checks on programs. * ipsvd-cdb.check, tcpsvd.check, udpsvd.check: new; check program. * ipsvd-cdb.dist, tcpsvd.dist, udpsvd.dist: new; dist test program output. * Makefile: run program checks by default. ipsvd 0.8.0 Fri, 13 Feb 2004 19:42:17 +0000 * doc/index.html: typo; related links; minor. * doc/examples.html, man/ipsvd-instruct.5: typos. * doc/install.html: typo (thx Charlie Brady). * byte_zero.c, case.h, case_diffb.c, dns.h, dns_dfd.c, dns_domain.c, dns_dtda.c, dns_ip.c, dns_ipq.c, dns_mx.c, dns_name.c, dns_nd.c, dns_packet.c, dns_random.c, dns_rcip.c, dns_rcrw.c, dns_resolve.c, dns_sortip.c, dns_transmit.c, dns_txt.c, ip4.h, ip4_scan.c, socket.h, socket_bind.c, socket_conn.c, socket_tcp.c, socket_udp.c, stralloc_copy.c, test.c, uint16.h, uint16_pack.c, uint16_unpack.c: new; from djbdns-pd-1.05, public domain. * Makefile: adapt; use included djbdns client library. * doc/install.html, doc/usedietlibc.html: adapt; package build no longer requires djbdns-pd-1.05. * ipsvd_hostname.c, ipsvd_hostname.h, print-cc.sh, print-ld.sh, tcpsvd.c, udpsvd.c: adapt includes; minor. * conf-djbdnsinc, conf-djbdnslib: remove; obsolete. * package/COPYING, package/README: 2004. * package/compile, package/install-man, package/upgrade: minor cleanup. ipsvd 0.7.1 Wed, 26 Nov 2003 09:14:35 +0000 * Makefile: target ipsvd-cdb: add libraries needed for socket() (fixes build failure on solaris, thx Uffe Jakobsen). * man/ipsvd.7: typo. * ipsvd-cdb.c: bug: deny-entries possibly became instruction-entries in the cdb, fix: reset stralloc before ipsvd_check() (thx Lukas Beeler). * doc/index.html: minor. ipsvd 0.7.0 Tue, 21 Oct 2003 15:59:30 +0000 * doc/examples.html: update bincimaps example; add check hostname instruction sample. * ipsvd_check.c, ipsvd_check.h: support check host instructions; change some internals; last concurrency instruction wins. * man/ipsvd-instruct.5: document check host instructions; update concurrency instruction. * ipsvd-cdb.c: consider filenames starting with a single dot; skip filenames starting with two dots; minor. * man/ipsvd-cdb.8: adapt. * Makefile: minor. * doc/upgrade.html: new. * doc/index.html adapt. * tcpsvd.c, udpsvd.c: minor changes in warning output. ipsvd 0.6.1 Tue, 14 Oct 2003 11:17:29 +0000 * ipsvd_scan.c: include sys/types.h (fixes build failure on freebsd, thx Sergei Kolobov). * trysocketlib.c: new; check for libraries needed for socket() on some systems (solaris, thx Uffe Jakobsen). * Makefile: adapt. ipsvd 0.6.0 Mon, 29 Sep 2003 10:59:15 +0000 * man/ipsvd-instruct.5: minor. * ipsvd_scan.h, ipsvd_scan.c: new; ipsvd_scan_port(): get port number from name or number (thx Matthias Andree for sample code). * tcpsvd.c, udpsvd.c: support name from /etc/services as command line option port. * man/tcpsvd.8, man/udpsvd.8, Makefile: adapt. * man/ipsvd.7: -u option is now mandatory. * udpsvd.c, man/udpsvd.8: stdout is redirected to stderr. * doc/index.html: minor. ipsvd 0.5.0 Wed, 06 Aug 2003 15:39:11 +0200 * doc/examples.html: typo (dead link, thx clemens fischer). * man/ipsvd.7, man/tcpsvd.8, man/udpsvd.8: typos; wording. * uidgid.c, uidgid.h: new; get uid/gid by name. * ipsvd-cdb.c, ipsvd_check.h, ipsvd_check.c, ipsvd_hostname.c, tcpsvd.c, udpsvd.c: code cleanup. ipsvd 0.4.1 Mon, 12 May 2003 10:18:05 +0200 * ipsvd_fmt.c: minor cleanup. * tcpsvd.c: include sys/types.h (really; thx clemens fischer); minor cleanup. * doc/examples.html: add qmail-smtpd example; minor adaptations. * man/ipsvd-instruct.5, man/ipsvd.7: don't remove files without write permission set on timeout. * tcpsvd.c, udpsvd.c: support -uuser[:group]. * man/tcpsvd.8, man/udpsvd.8: adapt. ipsvd 0.4.0 Mon, 05 May 2003 13:15:45 +0200 * ipsvd_check.c, ipsvd_check.h, tcpsvd.c: optionally send alert message to client when denying connection due to per host concurrency limit. * man/ipsvd-instruct.5, man/tcpsvd.8: adapt. * ipsvd_fmt.c, ipsvd_fmt.h: ipsvd_fmt_msg(): convert backslash-escaped characters in message. * package/upgrade: typo. * doc/examples.html: new. * doc/index.html: adapt. ipsvd 0.3.4 Tue, 29 Apr 2003 14:56:43 +0200 * ipsvd_check.c, ipsvd_check.h: support -t option: timeout for last access of files in an instructions directory; code cleanup. * tcpsvd.c, udpsvd.c: support -t option. * man/ipsvd.7, man/tcpsvd.8, man/udpsvd.8: adapt. * doc/install.html: build static djbdns client library only. * doc/usedietlibc.html: add instructions on how to build the djbdns client library with the diet libc. ipsvd 0.3.0 Sat, 12 Apr 2003 16:40:02 +0200 * doc/install.html: typo. * ipsvd-cdb.c: adapt; typo. * ipsvd_check.c, ipsvd_check.h: support hostname based instructions and catchall file 0; support removing environment vars. * ipsvd_hostname.c, ipsvd_hostname.h: new; lookup hostname in dns. * tcpsvd.c, udpsvd.c: remove -n option; support hostname based instructions; log localip:localhost info; add -l option; add -p option; replace -H with -h, by default do not look up hostname; add -vv option; slightly change log messages. * ipsvd_phcc.c, ipsvd_phcc.h: new; connection tracking, per host concurrency. * tcpsvd.c: add -C option, support per host concurrency limit; include (BSD OS needs it, thx clemens fischer). * man/ipsvd-instruct.5: document hostname based instructions, concurrency instructions, catchall file 0, removing environment vars. * man/tcpsvd.8, man/udpsvd.8: adapt. * man/ipsvd.7: add -hpl options. * Makefile: cleanup. * doc/usedietlibc.html: new. ipsvd 0.2.0 Sat, 22 Mar 2003 00:51:26 +0100 * code cleanup * 1st public version. ipsvd 0.1.6 Thu, 20 Mar 2003 22:24:53 +0100 * installs into /package. * man/ipsvd.7, man/ipsvd-instruct.5: new. * adapt manpages * adapt documentation. * tcpsvd.c, udpsvd.c: code cleanup. ipsvd 0.1.3 Tue, 18 Mar 2003 22:27:36 +0100 * initial version. net/ipsvd-1.0.0/package/COPYING0000644000000000000000000000261211025276022014545 0ustar rootrootCopyright (c) 2003-2008, Gerrit Pape All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. net/ipsvd-1.0.0/package/README0000644000000000000000000000006611025276022014373 0ustar rootrootCopyright 2003-2005 G. Pape http://smarden.org/ipsvd/ net/ipsvd-1.0.0/package/check0000755000000000000000000000033311025276022014513 0ustar rootroot#!/bin/sh -e umask 022 test -d package || sh -cx '! : Wrong working directory.' test -d compile || sh -cx '! : Wrong working directory.' echo 'Checking commands in ./command...' sh -cx 'cd compile && exec make check' net/ipsvd-1.0.0/package/commands0000644000000000000000000000003011025276022015226 0ustar rootroottcpsvd udpsvd ipsvd-cdb net/ipsvd-1.0.0/package/compile0000755000000000000000000000133211025276022015066 0ustar rootroot#!/bin/sh -e umask 022 test -d package || sh -cx '! : Wrong working directory.' test -d src || sh -cx '! : Wrong working directory.' here=`env - PATH=$PATH pwd` mkdir -p compile/. command/. test -r compile/home || echo $here >compile/home test -h compile/src || ln -s $here/src compile/src echo 'Linking ./src/* into ./compile...' for i in `ls src`; do test -h compile/$i || ln -s src/$i compile/$i done echo 'Compiling everything in ./compile...' sh -cx 'cd compile && exec make' echo 'Copying commands into ./command...' for i in `cat package/commands` `grep -v nossl ${i}.gz done echo 'Making manpage links in /usr/local/man...' cd man for k in 5 7 8; do mkdir -p /usr/local/man/man$k/. for i in *.$k; do rm -f /usr/local/man/man$k/$i.gz'{new}' ln -s $parent/ipsvd/man/$i.gz /usr/local/man/man$k/$i.gz'{new}' mv -f /usr/local/man/man$k/$i.gz'{new}' /usr/local/man/man$k/$i.gz done done cd .. net/ipsvd-1.0.0/package/upgrade0000755000000000000000000000151411025276022015067 0ustar rootroot#!/bin/sh -e umask 022 test -d package || sh -cx '! : Wrong working directory.' test -d src || sh -cx '! : Wrong working directory.' here=`env - PATH=$PATH pwd` parent=`dirname $here` echo 'Creating symlink ipsvd -> ipsvd-1.0.0...' rm -f ipsvd ln -s ipsvd-1.0.0 ipsvd mv -f ipsvd .. echo 'Making command links in /command...' mkdir -p /command/. for i in `cat package/commands` `grep -v nossl