<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
]>
<chapter id="chap-Defensive_Coding-Authentication">
  <title>Authentication and Authorization</title>

  <section id="sect-Defensive_Coding-Authentication-Server">
    <title>Authenticating servers</title>
    <para>
      When connecting to a server, a client has to make sure that it
      is actually talking to the server it expects.  There are two
      different aspects, securing the network path, and making sure
      that the expected user runs the process on the target host.
      There are several ways to ensure that:
    </para>
    <itemizedlist>
      <listitem>
	<para>
	  The server uses a TLS certificate which is valid according
	  to the web browser public key infrastructure, and the client
	  verifies the certificate and the host name.
	</para>
      </listitem>
      <listitem>
	<para>
	  The server uses a TLS certificate which is expectedby the
	  client (perhaps it is stored in a configuration file read by
	  the client).  In this case, no host name checking is
	  required.
	</para>
      </listitem>
      <listitem>
	<para>
	  On Linux, UNIX domain sockets (of the
	  <literal>PF_UNIX</literal> protocol family, sometimes called
	  <literal>PF_LOCAL</literal>) are restricted by file system
	  permissions.  If the server socket path is not
	  world-writable, the server identity cannot be spoofed by
	  local users.
	</para>
      </listitem>
      <listitem>
	<para>
	  Port numbers less than 1024 (<emphasis>trusted
	  ports</emphasis>) can only be used by
	  <literal>root</literal>, so if a UDP or TCP server is
	  running on the local host and it uses a trusted port, its
	  identity is assured.  (Not all operating systems enforce the
	  trusted ports concept, and the network might not be trusted,
	  so it is only useful on the local system.)
	</para>
      </listitem>
    </itemizedlist>
    <para>
      TLS (<xref linkend="chap-Defensive_Coding-TLS"/>) is the
      recommended way for securing connections over untrusted
      networks.
    </para>
    <para>
      If the server port number is 1024 is higher, a local user can
      impersonate the process by binding to this socket, perhaps after
      crashing the real server by exploiting a denial-of-service
      vulnerability.
    </para>
  </section>

  <section id="sect-Defensive_Coding-Authentication-Host_based">
    <title>Host-based authentication</title>
    <para>
      Host-based authentication uses access control lists (ACLs) to
      accept or deny requests from clients.  Thsis authentication
      method comes in two flavors: IP-based (or, more generally,
      address-based) and name-based (with the name coming from DNS or
      <filename>/etc/hosts</filename>).  IP-based ACLs often use
      prefix notation to extend access to entire subnets.  Name-based
      ACLs sometimes use wildcards for adding groups of hosts (from
      entire DNS subtrees).  (In the SSH context, host-based
      authentication means something completely different and is not
      covered in this section.)
    </para>
    <para>
      Host-based authentication trust the network and may not offer
      sufficient granularity, so it has to be considered a weak form
      of authentication.  On the other hand, IP-based authentication
      can be made extremely robust and can be applied very early in
      input processing, so it offers an opportunity for significantly
      reducing the number of potential attackers for many services.
    </para>
    <para>
      The names returned by <function>gethostbyaddr</function> and
      <function>getnameinfo</function> functions cannot be trusted.
      (DNS PTR records can be set to arbitrary values, not just names
      belong to the address owner.)  If these names are used for ACL
      matching, a forward lookup using
      <function>gethostbyaddr</function> or
      <function>getaddrinfo</function> has to be performed.  The name
      is only valid if the original address is found among the results
      of the forward lookup (<emphasis>double-reverse
      lookup</emphasis>).
    </para>
    <para>
      An empty ACL should deny all access (deny-by-default).  If empty
      ACLs permits all access, configuring any access list must switch
      to deny-by-default for all unconfigured protocols, in both
      name-based and address-based variants.
    </para>
    <para>
      Similarly, if an address or name is not matched by the list, it
      should be denied.  However, many implementations behave
      differently, so the actual behavior must be documented properly.
    </para>
    <para>
      IPv6 addresses can embed IPv4 addresses.  There is no
      universally correct way to deal with this ambiguity.  The
      behavior of the ACL implementation should be documented.
    </para>
  </section>

  <section id="sect-Defensive_Coding-Authentication-UNIX_Domain">
    <title>UNIX domain socket authentication</title>
    <para>
      UNIX domain sockets (with address family
      <literal>AF_UNIX</literal> or <literal>AF_LOCAL</literal>) are
      restricted to the local host and offer a special authentication
      mechanism: credentials passing.
    </para>
    <para>
      Nowadays, most systems support the
      <literal>SO_PEERCRED</literal> (Linux) or
      <literal>LOCAL_PEERCRED</literal> (FreeBSD) socket options, or
      the <function>getpeereid</function> (other BSDs, MacOS X).
      These interfaces provide direct access to the (effective) user
      ID on the other end of a domain socket connect, without
      cooperation from the other end.
    </para>
    <para>
      Historically, credentials passing was implemented using
      ancillary data in the <function>sendmsg</function> and
      <function>recvmsg</function> functions.  On some systems, only
      credentials data that the peer has explicitly sent can be
      received, and the kernel checks the data for correctness on the
      sending side.  This means that both peers need to deal with
      ancillary data.  Compared to that, the modern interfaces are
      easier to use.  Both sets of interfaces vary considerably among
      UNIX-like systems, unfortunately.
    </para>
    <para>
      If you want to authenticate based on supplementary groups, you
      should obtain the user ID using one of these methods, and look
      up the list of supplementary groups using
      <function>getpwuid</function> (or
      <function>getpwuid_r</function>) and
      <function>getgrouplist</function>.  Using the PID and
      information from <filename>/proc/PID/status</filename> is prone
      to race conditions and insecure.
    </para>
  </section>

  <section id="sect-Defensive_Coding-Authentication-Netlink">
    <title><literal>AF_NETLINK</literal> authentication of origin</title>
    <!-- ??? kernel change may make this obsolete:
         https://bugzilla.redhat.com/show_bug.cgi?id=851968 -->
    <para>
      Netlink messages are used as a high-performance data transfer
      mechanism between the kernel and the userspace.  Traditionally,
      they are used to exchange information related to the network
      statck, such as routing table entries.
    </para>
    <para>
      When processing Netlink messages from the kernel, it is
      important to check that these messages actually originate from
      the kernel, by checking that the port ID (or PID) field
      <literal>nl_pid</literal> in the <literal>sockaddr_nl</literal>
      structure is <literal>0</literal>.  (This structure can be
      obtained using <function>recvfrom</function> or
      <function>recvmsg</function>, it is different from the
      <literal>nlmsghdr</literal> structure.)  The kernel does not
      prevent other processes from sending unicast Netlink messages,
      but the <literal>nl_pid</literal> field in the sender's socket
      address will be non-zero in such cases.
    </para>
    <para>
      Applications should not use <literal>AF_NETLINK</literal>
      sockets as an IPC mechanism among processes, but prefer UNIX
      domain sockets for this tasks.
    </para>
  </section>
</chapter>

