File: sident.h

package info (click to toggle)
sident 3.6-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,960 kB
  • ctags: 719
  • sloc: sh: 8,131; ansic: 6,784; makefile: 231; perl: 147
file content (428 lines) | stat: -rw-r--r-- 17,315 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
/*  $Id: sident.h 549 2004-06-17 01:26:49Z eagle $
**
**  Interface to the S/Ident requester library.
**
**  Written by Booker Bense <bbense@stanford.edu>
**  Based on libident by Peter Eriksson <pen@lysator.liu.se>
**                   and Pdr Emanuelsson <pell@lysator.liu.se>
**
**  This interface is heavily based on the libident interface, with some
**  additions for the Kerberos S/Ident functionality.  It needs a great deal
**  of work in the area of avoiding hard-coded buffer limits and global
**  variables, so I expect that this interface will change in the future.
**  It also currently contains some definitions of internal structs, which
**  will eventually be removed.
*/

#ifndef SIDENT_H
#define SIDENT_H 1

#include <netinet/in.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>

/* BEGIN_DECLS is used at the beginning of declarations so that C++ compilers
   don't mangle their names.  END_DECLS is used at the end.  Use macros so
   that smart editors don't get confused by the block. */
#undef BEGIN_DECLS
#undef END_DECLS
#ifdef __cplusplus
# define BEGIN_DECLS    extern "C" {
# define END_DECLS      }
#else
# define BEGIN_DECLS    /* empty */
# define END_DECLS      /* empty */
#endif

/* The registered ident port. */
#ifndef IDPORT
# define IDPORT 113
#endif

/* The service name for the S/Ident protocol, used in Kerberos principals. */
#define IDENT_AUTH_KRB_SERVICE "ident"

/* Default delay for network reads.  This should be configurable. */
#define IDENT_READ_TIMEOUT 60

/* Buffer size sufficient to hold a complete request or response. */
#define IDENT_BUFFER_SIZE 4096

/* The number of authentication flags supported by KERBEROS_V4. */
#define IDENT_MAX_KRB_AUTH_FLAG 1

/* A 16-bit unsigned type. */
#ifndef IDENT_INT16
# define IDENT_INT16 unsigned short
#endif


BEGIN_DECLS


/* VARIABLES AND STRUCTURES */


/* Version of the S/Ident library being used. */
extern char id_version[];

/* Return codes used by library functions. */
enum id_codes {
    IDENT_AUTH_OKAY = 0,        /* No error. */
    IDENT_AUTH_FAIL,            /* An unidentified operation failed. */

    /* None of the authentication mechanisms offered by the requester are
       supported for authentication of the owner of the indicated
       connection. */
    IDENT_AUTH_NOT_SUPPORTED,

    /* The authentication mechanism is supported for the owner of the
       connection, but no authentication information is available for that
       user. */
    IDENT_USER_CANT_AUTH,

    /* One or more values in auth-resp-info are syntactically invalid. */
    IDENT_INVALID_RESP_INFO,

    /* One or more values in auth-req-info are syntactically invalid. */
    IDENT_INVALID_REQ_INFO,

    /* The connection specified by the port pair is not currently in use or
       currently not owned by an identifiable entity. */
    IDENT_NO_USER,

    /* Any error not covered by other codes should return this error code
       value.  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.  If a server implements such a feature, it MUST be configurable
       and it MUST default to returning the proper error message.

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

    /* 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_INVALID_PORT,

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

    /* Indicates that the authentication mechanism is supported for the owner
       of the connection, but that no authentication information is available
       for that user; this value is used if the responder has prompted the
       user to authenticate.

       This error code is deprecated.  IDENT_CANT_AUTH should be used
       instead. */
    IDENT_USER_WONT_AUTH,

    /* All error codes below are internal. */
    IDENT_INTERNAL_ERR,         /* Internal library error. */
    IDENT_NO_MUTUAL_AUTH,       /* No mutual authentication given. */
    IDENT_MUTUAL_AUTH_FAIL,     /* Mutual authentication failed. */
    IDENT_SYSTEM_ERROR,         /* Some internal system error (see errno). */
    IDENT_FLAG_NOT_SUPPORTED,   /* Authentication flag not supported. */
    IDENT_INVALID_FLAG_VALUE,   /* Invalid authentication flag value. */
    IDENT_TIMEOUT,              /* Timeout in library functions. */

    IDENT_MAX_ERROR             /* Fencepost value. */
};

/* A table mapping enum id_codes codes to text strings. */
extern const char *ident_err_txt[];

/* A table listing all authentication flags supported by KERBEROS_V4. */
extern const char *ident_krb_auth_flags[];

/* Low-level struct underlying an open ident connection. */
typedef struct {
    int fd;
    char buf[IDENT_BUFFER_SIZE];
} ident_t;

/* High-level struct encapsulating all the protocol data. */
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 (what did you expect?). */
    int result_code;            /* Result code from internal routines. */
    time_t expires;             /* Expiration of authenticating ticket. */
    char *principal;            /* Principal in local realm. */
} IDENT;


/* HIGH-LEVEL CALLS */


/* The simplest of the lookup calls.  Assumes that fd points to an open
   network connection and does an ident callback to the system on the other
   end, asking for the identity of the user opening that connection.  Returns
   only the identity string in newly allocated memory.  timeout specifies the
   timout in seconds.  If the protocol failed or the user could not be
   authenticated, returns NULL. */
extern char *ident_id(int fd, int timeout);

/* Like ident_id, but returns a full IDENT struct rather than just the
   identity information.  The struct is returned even in the event of an error
   on the remote side, so the error can be diagnosed more completely.  Returns
   NULL if something fundamental goes wrong, in which case errno should be set
   appropriately. */
extern IDENT *ident_lookup(int fd, int timeout);

/* Like ident_lookup(), but rather than just taking the file descriptor of an
   open network connection, takes the local and remote address and local and
   remote ports instead.  This is the most complete of the ident lookup
   functions and can be used to authenticate other open connections on the
   same system provided that the local and remote ports are known.  Returns
   an IDENT struct unless something fundamental goes wrong, in which case
   errno should be set appropriately. */
extern IDENT *ident_query (struct in_addr *laddr, struct in_addr *raddr,
                           int resp_port, int req_port, int timeout);

/* Frees the IDENT struct returned by ident_lookup or ident_query, including
   all data contained in it. */
extern void ident_free(IDENT *);

/* Sets the type of authentication to request of the remote system.  Currently
   there are only three supported values: KERBEROS_V4, GSSAPI, and TRIVIAL.
   TRIVIAL is the same as the normal ident protocol.

   The second parameter is type-specific initialization data.  For
   KERBEROS_V4, this should be the full path to the srvtab file that contains
   the key for the ident.hostname Kerberos principal.  Neither TRIVIAL nor
   GSSAPI take any data.

   Returns IDENT_AUTH_OKAY on success and IDENT_AUTH_NOT_SUPPORTED on
   failure. */
extern int ident_set_authtype(char *auth_type, void *auth_init_data);

/* The S/Ident protocol supports flags that can be set in the initial
   authentication request.  This call sets a flag that will be passed to
   future ident requests.  ident_set_authtype must be called before this call
   can be used.

   Currently, the only supported flag is "USER-INTERACTION" with possible
   values "YES" or "NO", indicating whether the S/Ident server should attempt,
   when possible, to bring up a dialog box to authenticate the user if they
   are not already authenticated.

   Returns IDENT_AUTH_OKAY on success, IDENT_FLAG_NOT_SUPPORTED if the flag
   isn't recognized, and IDENT_INVALID_FLAG_VALUE if the value given isn't one
   of the valid values for that flag. */
extern int ident_set_authflag(char *flag, char *value);

/* Returns the value of a flag set by ident_set_authflag.  As with that
   function, ident_set_authtype must be called before this function.  The
   value returned in value points to internal memory and should not be
   manipulated.  Note that value may be set to NULL if the flag was not set at
   all (but was recognized as valid).

   Returns IDENT_AUTH_OKAY if the flag is valid or IDENT_FLAG_NOT_SUPPORTED if
   it is not a recognized flag. */
extern int ident_get_authflag(char *flag, char **value);

/* Interogates the error string returned from the responder for a given flag
   and corresponding value.  The two currently defined flags are CAPABILITIES
   and AUTH-MECH.  See the S/Ident draft for the corresponding values.  The
   responder uses the extended error codes to allow the requester to attempt
   to reformulate its call in an attempt to complete a successful transaction.
   This can be used to negotiate authentication methods, as well as to
   distinguish between responders capable of user interaction and those that
   are not capable.

   It takes a keyword to search for, the value that keyword should have, and
   the IDENT structure representing the error response.  It returns
   IDENT_AUTH_OKAY if that flag/value pair is found and IDENT_AUTH_FAIL if it
   is not. */
extern int ident_query_error(char *keyword, char *value, IDENT *ident);


/* LOW-LEVEL CALLS AND MACROS */


/* These calls are no longer supported and will probably be removed in the
   future in favor of a more complete high-level interface. */

/* A macro that takes an ident_t handle and returns the actual socket file
   descriptor used for the connection to the remote server. */
#define id_fileno(id) ((id)->fd)

/* Opens a connection to the remote ident server referred to by faddr.  The
   timeout is specified by timeout.  Returns a pointer to an ident_t datum,
   which is an opaque structure to be used as future reference to the opened
   connection.

   timeout is a pointer to a timeval struct indicating how long to wait for a
   response; NULL means wait indefinitely, while a zero-valued timeval struct
   will cause id_open to return if the connection cannot be completed
   immediately.  Specifying a timeout will put the socket in non-blocking
   mode.

   Returns a valid ident_t on success or NULL on failure. */
extern ident_t *id_open(struct in_addr *laddr, struct in_addr *faddr,
                        struct timeval *timeout);

/* Allocate and initialize an ident_auth_client_data struct. */
extern struct ident_auth_client_data *
    id_auth_init(struct ident_auth_client_data *auth_data);

/* Close an ident connection opened with id_open and free all data associated
   with it.  Returns 0 on success, non_zero on failure.  errno will be set on
   failure. */
extern int id_close(ident_t *id);

/* Sends off a query to a remote ident server.  resp_port and req_port
   are sent to the server to identify the connection for which identification
   is needed.  timeout is given as for id_open.  auth_data specifies the
   authentication protocol to use.

   Returns the number of bytes sent to the remote server on success, -1 on
   failure.  On failure, errno is set. */
int id_query(ident_t *id, int resp_port, int req_port, struct timeval *timeout,
             struct ident_auth_client_data *auth_data);

/* Parses the reply to a query sent off by id_query() and returns information
   to the locations pointed to by resp_port, req_port, identifier, opsys, and
   charset.  For string data (identifier, opsys, and charset) pointers to
   allocated space are returned.  The caller is responsible for freeing.

   Returns one of the following codes:

   -3  Illegal reply type from remote server.  identifier is set to the
       illegal reply.

   -2  Cannot parse the reply from the server.  identifier is normally set to
       the illegal reply, unless it could not be saved.

   -1  Some other general error or timeout.

   0   Non-blocking mode is set (a timeout was specified) and id_parse has not
       finished parsing the reply from the server.

   1   Complete success.

   2   The query and reply (the basic protocol) were successful, but the
       remote site experienced some error.  identifier is set to the error
       message from the remote server. */
extern int id_parse(ident_t *id, struct timeval *timeout,
                    int *resp_port, int *req_port,
                    char **identifier, char **opsys, char **charset,
                    struct ident_auth_client_data *auth_data);


/* INTERNAL DEFINITIONS */


/* Everything below this point is strictly for the internal use of the S/Ident
   daemon and library and should not be used by clients.  It will all
   eventually move out of this file. */

/* Maximum length of an authenticator. */
#define MAX_AUTH_LEN 4096

/* Minimum length of an authenticator. */
#define MIN_AUTH_LEN 80 

/* Maximum length of an identifier.  Should be the same as MAX_K_NAME_SZ in
   krb.h, but we don't want to depend on krb.h. */
#define MAX_AUTH_NAME 123 

/* Bit to determine if mutual authentication is needed. */
#define MUTUAL_AUTH_BIT 0x01 

/* Internal structure containing requester information. */
struct ident_auth_client_data {
    /* Authenticated identity. */
    char user_ident[MAX_AUTH_NAME];

    /* Authenticated identity in local realm, if available. */
    char user_principal[MAX_AUTH_NAME];

    /* Authentication data from the network. */
    char authenticate_data[MAX_AUTH_LEN];

    int requester_port;          /* Port of connection on requester. */
    int responder_port;          /* Port of connection on responder. */
    int fd;                      /* File descriptor of connection. */
    struct timeval *timeout;     /* I/O timeout in seconds. */
    time_t expires;              /* Expiration of authenticating ticket. */
    struct in_addr *local_addr;  /* Local IP address. */
    struct in_addr *remote_addr; /* Remote IP address. */

    /* Pointer to authentication methods. */
    struct ident_requester_auth *auth_struct;

    /* Pointer to method-specific data used for authentication. */
    void *auth_method_data;
};

/* Internal structure containing responder information. */
struct ident_auth_data {
    FILE *fp;                    /* Input stream. */
    char *port_data;             /* Points to port data part of auth_line. */
    char *cmd_data;              /* Points to command part of line. */
    char *authenticate_data;     /* Points to AUTHENTICATE part of line. */
    int uid;                     /* UID of process. */
    int pid;                     /* PID of process. */

    /* Pointer to authentication methods. */
    struct ident_responder_auth *auth_struct;

    int local_port;              /* Local port of connection. */
    int remote_port;             /* Remote port of connection. */
    struct in_addr *local_addr;  /* Local IP address. */
    struct in_addr *remote_addr; /* Remote IP address. */

    /* Pointer to method-specific data used for authentication. */
    void *auth_method_data;
};

/* Internal structure detailing how to do requester authentication. */
struct ident_requester_auth {
    char *auth_method;          /* Name of authentication mechanism. */
    char *response;             /* Response from server. */
    void *auth_method_init;     /* Type-specific data (e.g. srvtab name). */
    char *auth_flags;           /* Char string of requester flags. */

    /* Start a responder->requester authentication. */
    char *(*start)(struct ident_auth_client_data *);

    /* Do an authentication protocol exchange. */
    int (*auth)(struct ident_auth_client_data *);

    /* Free an authentication state structure. */
    void (*free_state)(void *);

    /* Set an authentication flag value. */
    int (*set_flag)(char *flag, char *value);

    /* Get the value of an authentication flag. */
    int (*get_flag)(char *flag, char **value);
};

/* Internal structure detailing how to do responder authentication. */
struct ident_responder_auth {
    char *auth_method;		/* Name of authentication mechanism. */

    /* Start a responder->requester authentication. */
    int (*start)(struct ident_auth_data *);

    /* Do an authentication protocol exchange. */
    int (*auth)(struct ident_auth_data *);

    /* Free an authentication state structure. */
    void (*free_state)(void *);
};

END_DECLS

#endif /* SIDENT_H */