/* * HttpAuth * * Copyright (C) 2004 Stefan Walter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ #ifndef __HTTPAUTHD_H__ #define __HTTPAUTHD_H__ #include #include "buffer.h" #include #include /* ----------------------------------------------------------------------- * HTTP Auth Handlers */ struct ha_context; struct ha_request; /* * This function initializes the handler. It gets called * after the configuration gets loaded so if a config func * is registered it'll get called before this. */ typedef int (*auth_init_t)(struct ha_context* ctx); /* * This function is called when the app exits. All threads * should have completed at this point, so it's not necessary * to be thread safe in here */ typedef void (*auth_destroy_t)(struct ha_context* ctx); /* * Called once for each configuration parameter. This is * called before the initialization function. 'name' will * always be lower case. White space will always be trimmed * from the value. */ typedef int (*auth_config_t)(struct ha_context* ctx, const char* name, const char* value); /* * Called for each authentication request that is designated * for this handler. Note that all data access in this * function must be thread-safe. */ typedef int (*auth_process_t)(struct ha_request* rq); /* An authentication handler */ typedef struct ha_handler { const char* type; auth_init_t f_init; /* #1 Called to initialize handler */ auth_destroy_t f_destroy; /* #3 Called when exiting */ auth_config_t f_config; /* #0 Called for each config param */ auth_process_t f_process; /* #2 Called for each auth request */ const void* context_default; /* The default context */ const size_t context_size; /* Bytes of extra context needed */ } ha_handler_t; /* * OK signifies that things went according to plan. */ #define HA_OK 0 /* * FALSE: the process failed but it wasn't an error. */ #define HA_FALSE 1 /* * ERROR means a bad error happened which will kill the * current processing thread. Examples are out of memory * errors or the like. */ #define HA_CRITERROR -1 /* * FAILED: something internal to the server failed. */ #define HA_FAILED -2 /* * BADREQ means that we got a bad request or call. */ #define HA_BADREQ -3 /* Context passed to the handler functions above */ typedef struct ha_context { const char* name; /* A name assigned by the configuration file */ const ha_handler_t* handler; /* The original handler structure */ void* ctx_data; /* Handler specific data */ /* Context specific options */ unsigned int allowed_types; int cache_timeout; int cache_max; /* For basic and digest auth: */ const char* realm; /* For digest auth: */ unsigned int digest_allowany : 1; unsigned int digest_ignorenc : 1; const char* digest_debugnonce; } ha_context_t; /* ----------------------------------------------------------------------- * Request Stuff */ /* * The maximum number of commands in any httpauth * command. This is defined by the protocol. There * should be no need to change it unless we're * adding or removing commands */ #define HA_MAX_ARGS 4 /* * The maximum number of pertinent headers to read/send * from/to the client. If you need to add valid headers * make sure to update this number *and* the list * of valid headers in httpauthd.c */ #define HA_MAX_HEADERS 8 /* * The maximum number of handlers. If you add * handlers make sure to update this number. */ #define HA_MAX_HANDLERS 4 /* A single header in memory */ typedef struct ha_header { const char* name; const char* data; } ha_header_t; /* The various command codes */ #define REQTYPE_IGNORE 0 #define REQTYPE_QUIT 1 #define REQTYPE_AUTH 2 #define REQTYPE_SET 3 #define AUTH_ARG_CONN 0 #define AUTH_ARG_METHOD 1 #define AUTH_ARG_URI 2 /* A single request from client along with response */ typedef struct ha_request { unsigned int id; /* Unique connection identifier */ int ifd; /* Input file descriptor */ int ofd; /* Output file descriptor */ int req_type; /* The command type */ const char* req_args[HA_MAX_ARGS]; /* Arguments for the command */ ha_header_t req_headers[HA_MAX_HEADERS]; /* Headers for command */ /* Additional request info */ ha_context_t* context; const char* digest_domain; char** requested_groups; /* Shortcut to req_buf below, for compatibility */ ha_buffer_t *buf; /* The buffer in use for the request */ ha_buffer_t req_buf; /* The buffer in use for the connection */ ha_buffer_t conn_buf; int resp_code; /* The response code */ const char* resp_detail; /* The details for response */ ha_header_t resp_headers[HA_MAX_HEADERS]; /* Headers for the response */ } ha_request_t; /* The various response codes for the client */ #define HA_SERVER_READY 100 #define HA_SERVER_OK 200 #define HA_SERVER_ACCEPTED 202 #define HA_SERVER_DECLINE 401 #define HA_SERVER_BADREQ 400 #define HA_SERVER_BUSY 500 /* Request functions */ const ha_header_t* ha_findheader(const ha_request_t* rq, const char* name); const char* ha_getheader(const ha_request_t* rq, const char* name, const char* prefix); /* Response functions */ void ha_addheader(ha_request_t* rq, const char* name, const char* data); /* Implemented in request.c */ void ha_request_destroy (ha_request_t *rq); ha_request_t* ha_request_setup (int ifd, int ofd); void ha_request_setup_handler (void *arg); int ha_request_process (ha_request_t *rq); void ha_request_process_handler (void *arg); void ha_request_loop (int ifd, int ofd); /* Implemented in httpauthd.c */ int ha_register_request (ha_request_t *rq); int ha_register_watch (ha_request_t *rq); void ha_unregister_request (ha_request_t *rq); ha_context_t* ha_lookup_handler (const char *name); /* ----------------------------------------------------------------------- * Configuration */ int ha_confbool(const char* name, const char* conf, int* value); int ha_confint(const char* name, const char* conf, int min, int max, int* value); /* ----------------------------------------------------------------------- * Error Handling */ void ha_message(const ha_request_t* rq, int level, const char* msg, ...); void ha_messagex(const ha_request_t* rq, int level, const char* msg, ...); void ha_memerr(const ha_request_t* rq); /* ----------------------------------------------------------------------- * Authentication types */ /* The various types of authentication */ #define HA_TYPE_BASIC 1 << 1 #define HA_PREFIX_BASIC "Basic " #define HA_TYPE_DIGEST 1 << 2 #define HA_PREFIX_DIGEST "Digest " #define HA_TYPE_NTLM 1 << 3 #define HA_PREFIX_NTLM "NTLM " /* ----------------------------------------------------------------------- * URI Parse Support */ typedef struct ha_uri { const char* scheme; const char* user; const char* pw; const char* host; unsigned short port; const char* path; const char* query; const char* fragment; } ha_uri_t; char* ha_uriformat(ha_buffer_t* buf, const ha_uri_t* uri); int ha_uriparse(ha_buffer_t* buf, const char* suri, ha_uri_t* uri); int ha_uricmp(ha_uri_t* one, ha_uri_t* two); /* ----------------------------------------------------------------------- * Locking */ void ha_lock (pthread_mutex_t* mtx); void ha_unlock (pthread_mutex_t* mtx); /* ----------------------------------------------------------------------- * Miscellaneous */ int ha_genrandom(unsigned char* data, size_t len); #endif /* __HTTPAUTHD_H__ */