---
name: "sident"
section: "3"
platform: "linux"
package: "libsident0-dev"
version: "3.6-2"
release: "Debian 4.0 (Etch)"
platforms: ["linux"]
url: "https://new.carta.tech/sident"
---

# sident(3)

Query remote S/Ident responder

## 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***, int***timeout***)**

**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)](/free/3.md).  **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)](/sidentd/8.md) 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)](/sidentd/8.md).

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 Paer 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.
