libsident

NAME

ident_query, ident_lookup, ident_id, ident_free, ident_set_authtype, ident_set_authflag, ident_get_authflag, ident_query_error - Query remote S/Ident responder

SYNOPSIS

#include <sident.h>

IDENT *ident_query(struct in_addr *laddr, struct in_addr *raddr, int resp_port, int req_port, int timeout)

IDENT *ident_lookup(int fd, inttimeout)

char *ident_id(int fd, int timeout)

void ident_free(IDENT *id)

int ident_set_authtype(char *authtype, void *auth_init_data)

int ident_set_authflag(char *flag, char *value)

int ident_get_authflag(char *flag, char **value)

int ident_query_error(char *flag, char *value, IDENT *ident_ptr)

DESCRIPTION

The S/Ident protocol is used to authenticate a user who is connecting to a remote network service using a protocol (or software) which does not support authentication. The user connects to a remote server, that server opens a connection back to the client (a callback), and the callback is answered by a daemon on the client machine that returns the user's authentication out of band. In the S/Ident standard, the remote server that is trying to authenticate the user is called the requester, and the daemon on the client system that returns the authentication information is called the responder.

The S/Ident library, libsident, provides an API for S/Ident requesters to make a query back to the connecting host for authentication information associated with a particular connection. There are three different high-level calls, depending on how much information is needed and whether the caller has an open network file descriptor.

ident_query is the most "raw" of the three calls. It requires the local address of the requester system, the remote address, and the ports on the responder and requester systems and returns an IDENT struct (described below). If a network connection cannot be made to the responder, it returns NULL. This may indicate a network problem, or may indicate that the remote host is not running an S/Ident responder. If the network connection is successful but the authentication fails, there will be a non-zero status in the result_code field of the IDENT struct.

ident_lookup does the same but instead takes the file descriptor of a connected network socket and gets the IP addresses and ports from that. Its return value is the same as ident_query.

ident_id takes the same arguments as ident_lookup but returns only the identifier component of the IDENT struct (see below) on success. The return value is newly allocated memory that should be freed with a regular call to free(3). ident_id returns NULL on any error, network or otherwise, and only returns identifier on successful authentication.

All three functions take a timeout argument, which specifies the longest permissable time to block for an answer in seconds. A value of 0 says to wait indefinitely (in practice, generally until the underlying network connection times out).

ident_free should be used to free a returned IDENT struct, including all data contained in it.

ident_set_authtype sets the type of authentication to request. There are currently three supported values: "KERBEROS_V4", "GSSAPI", and "TRIVIAL". (The "TRIVIAL" authentication type behaves the same as the standard Ident protocol and doesn't do any strong authentication.) The second argument to ident_set_authtype is a pointer to whatever initialization data is required for that authentication type. Currently, the only authentication type that takes additional data is "KERBEROS_V4", which takes a pointer to the location of the srvtab file to use. The srvtab should contain a key for ident.hostname where hostname is the DNS name of the network interface that will be making the request.

(There is no direct way to specify the keytab to use for the GSS-API method because GSS-API doesn't have a way to specify it. You can, however, set the KRB5_KTNAME environment variable to point to the appropriate keytab.)

ident_set_authflag sets an optional flag in the initial authentication request. Currently, the only supported flag is "USER-INTERACTION", which can be set to "YES" or "NO". If set to "YES", the requester asks that the user be prompted to log in if possible and if they don't have current credentials. If set to "NO", the requester asks that the user not be prompted and that authentication fail if they don't have current credentials. ident_set_authtype must be called before this call can be used.

ident_get_authflag queries the current value of a flag. A pointer to the value string is returned in the value argument. ident_set_authtype must be called before this call can be used.

ident_query_error interrogates an error return (in the form of an IDENT struct) for a given flag and corresponding value. If the flag and value are present, it returns IDENT_AUTH_OKAY; otherwise, it returns IDENT_AUTH_FAIL. The two defined flags are "CAPABILITIES" and "AUTH-MECH".

The only allowable value for "CAPABILITIES" is "USER-INTERACTION". It will be returned if authentication failed because the user didn't have current credentials but the responder is capable of prompting for them if the "USER-INTERACTION" flag is set. The requester may want to set that flag with ident_set_authflag and then retry the query.

The "AUTH-MECH" flag is used to query the responder for its supported SASL mechanisms. Because of the nature of the S/Ident protocol, it doesn't do the normal SASL negotation first. Instead, the requester starts by just using some particular SASL protocol, which the responder either supports or doesn't. If it doesn't support it, the returned error lists the mechanisms that are supported. This information can be queried using ident_query_error; the flag value should be the name of a SASL mechanism, and the return code will indicate whether the responder said it supported that mechanism. Note that GSS-API mechanisms are separately listed as type/subtype. The only currently supported GSS-API mechanism is "GSSAPI/KERBEROS_v5".

The IDENT struct has the following definition:

    typedef struct {
        int resp_port;      /* Responder port. */
        int req_port;       /* Requester port (i.e. us). */
        char *identifier;   /* Identification string. */
        char *opsys;        /* Operating system. */
        char *charset;      /* Character set. */
        int result_code;    /* Result code from internal routines. */
        time_t expires;     /* Expiration of authenticating ticket. */
        char *principal;    /* Principal in local realm. */
    } IDENT;

identifier contains the authenticated identity (principal@realm for Kerberos v4 or GSS-API Kerberos v5 authentication), a colon, and identifier returned by the remote system (generally the local Unix user name or UID). In the event of an error, identifier will instead contain a string representation of the error. principal will contain only the principal portion of the Kerberos identity if its real matches the local realm. Otherwise, and on any error, it will be NULL.

The opsys and charset fields contain that information if it's specified in the S/Ident response, but are rarely useful. They will be set to NULL if that information was not specified.

result_code contains the error status of the call. See ERRORS for detailed information. If there is no error, it will be set to 0 (IDENT_AUTH_OKAY).

expires contains the time (in seconds since epoch) when the underlying authentication credentials of the user will expire.

ERRORS

The following codes are defined by the S/Ident library and are used for the result_code field of the IDENT struct and for other error returns. IDENT_AUTH_OKAY and IDENT_AUTH_FAIL are used as convenient boolean return codes for some functions.

IDENT_AUTH_OKAY

The operation was successful.

IDENT_AUTH_FAIL

Verification of authentication failed. (Or, when used outside of the IDENT struct, indicates that some error occurred.)

IDENT_AUTH_NOT_SUPPORTED

The authentication mechanism used by the requester is not supported for authentication of the owner of the indicated connection. The requester may wish to use ident_query_error with the "AUTH-MECH" flag to find another acceptable, supported SASL mechanism.

IDENT_USER_CANT_AUTH

The authentication mechanism was supported, but no authentication information is available for that user. Either they don't have valid credentials, they've chosen not to authenticate, or some similar failure occurred.

IDENT_INVALID_RESP_INFO

The response from the responder was syntactically invalid according to the S/Ident protocol.

IDENT_INVALID_REQ_INFO

The query from the responder was syntactically invalid according ot the S/Ident protocol.

IDENT_NO_USER

The connection specified is not currently in use or is not currently owned by an identifiable entity.

IDENT_UNKNOWN_ERROR

Some error occurred which is not covered by the other error codes. Optionally, this code MAY be returned in lieu of any other specific error code if, for example, the server desires to hide information implied by the return of that error code, or for any other reason.

This error code is also used if the remote system closed the connection without returning any response.

IDENT_INVALID_PORT

Either the local or foreign port was improperly specified. This should be returned if either or both of the port ids were out of range (TCP port numbers are from 1-65535), negative integers, reals or in any fashion not recognized as a non-negative integer.

IDENT_HIDDEN_USER

The server was able to identify the user of this port, but the information was not returned at the request of the user.

EXAMPLES

The following code fragment shows how to check for an authenticated connection (assuming that the network connection is on standard input, as with a server started from inetd):

    IDENT *ident;

    ident_set_authtype("GSSAPI", NULL);
    ident = ident_lookup(fileno(stdin), 30);
    if (ident != NULL) {
        if (ident->result_code == IDENT_AUTH_OKAY)
            printf("User authenticated as %s\n", ident->identifier);
        else
            printf("Authentication failed: %s\n", ident->identifier);
    } else
        printf("Unable to contact S/Ident responder\n");
    ident_free(ident);

BUGS

The S/Ident protocol has some significant flaws in the presence of NAT, firewalls, and the like. See the sidentd(8) manual page for more details.

For ident_lookup and ident_id, the blocking time in extreme cases may be as much as three times the value given in the timeout parameter.

The described interface doesn't allow for non-blocking queries, and the low-level API that would allow for them is not described here and isn't particularly attractive. Ideally, the above API should be extended slightly to allow for non-blocking queries.

This API isn't even remotely thread-safe, as is immediately apparent.

WARNING

The S/Ident protocol implemented by this package is inherently vulnerable to an active man-in-the-middle attack. If an attacker can interpose themselves into a network connection initiated by a victim and both impersonate that victim and selectively control which of their packets reach a server using S/Ident, the attacker can make use of the victim's authentication credentials. The attacker cannot initiate the session, only hijack an existing authenticated session.

Because of this, you should very carefully analyze the security requirements of any service for which you're considering deploying S/Ident authentication. Due to the requirements of the attack, S/Ident may still be appropriate for very light authentication or in secure network environments, but should not be used for general authentication on untrusted networks.

SEE ALSO

sidentd(8).

The S/Ident protocol is described in draft-morgan-ident-ext-04.txt, included in the S/Ident source. This is an expired Internet Draft that was never published as an RFC.

The basic Ident protocol is described in RFC 1413.

The S/Ident web page at <http://www.eyrie.org/~eagle/software/sident/> will have the current version of sidentd and the libsident requester library.

AUTHORS

Originally written by Booker Bense <bbense@stanford.edu> based on the S/Ident protocol proposed by Robert Morgan <morgan@stanford.edu>. GSS-API support added by Russ Allbery <rra@stanford.edu>, who currently maintains this package.

The code is based on the pidentd/libident code from Peter Eriksson <pen@lysator.liu.se> and Pär Emanuelsson <pell@lysator.liu.se>. The SASL-like kerberos exchange is based on code from CMU's imapd-1.4 release.

COPYRIGHT AND LICENSE

Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Board of Trustees, Leland Stanford Jr. University.

Portions based on source from Peter Eriksson <pen@lysator.liu.se> contained in the libident library, released into the public domain.

Portions based on code copyright (c) 1994-2000 Carnegie Mellon University.

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 "Carnegie Mellon University" must not be used to endorse or promote products derived from this software without prior written permission. For permission or any legal details, please contact

        Office of Technology Transfer 
        Carnegie Mellon University 
        5000 Forbes Avenue 
        Pittsburgh, PA 15213-3890 
        (412) 268-4387, fax: (412) 268-7395 
        tech-transfer@andrew.cmu.edu
  4. Redistributions of any form whatsoever must retain the following acknowledgment:

        "This product includes software developed by Computing Services 
        at Carnegie Mellon University (http://www.cmu.edu/computing/)."

STANFORD UNIVERSITY AND CARNEGIE MELLON UNIVERSITY DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL STANFORD UNIVERSITY OR CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Last spun 2014-07-26 from POD modified 2014-04-14