diff options
Diffstat (limited to 'daemon/httpauthd.h')
-rw-r--r-- | daemon/httpauthd.h | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/daemon/httpauthd.h b/daemon/httpauthd.h new file mode 100644 index 0000000..536dfdc --- /dev/null +++ b/daemon/httpauthd.h @@ -0,0 +1,328 @@ + +#ifndef __HTTPAUTHD_H__ +#define __HTTPAUTHD_H__ + +/* ----------------------------------------------------------------------- + * Memory Buffers + */ + +/* A buffer which owns memory */ +typedef struct ha_buffer +{ + int _al; + char* _dt; + char* _pp; + char* _rp; +} +ha_buffer_t; + +void ha_bufinit(ha_buffer_t* buf); +void ha_buffree(ha_buffer_t* buf); +void ha_bufreset(ha_buffer_t* buf); + +/* Buffer input functions */ +int ha_readline(int fd, ha_buffer_t* buf); +char* ha_parseline(ha_buffer_t* buf, int trim); +char* ha_parseword(ha_buffer_t* buf, const char* delims); + +/* Buffer output functions */ +void ha_bufnext(ha_buffer_t* buf); +void ha_bufcat(ha_buffer_t* buf, ...); + +/* Buffer encoding functions */ +void ha_bufenc64(ha_buffer_t* buf, const const char* src, size_t len); +void ha_bufdec64(ha_buffer_t* buf, const char* src, size_t len); + +void ha_bufenchex(ha_buffer_t* buf, const unsigned char* src, size_t len); +void ha_bufdechex(ha_buffer_t* buf, const char* src, size_t len); + +/* Memory allocation functions */ +void* ha_bufmalloc(ha_buffer_t* buf, size_t sz); + +#define ha_bufskip(buf) \ + ((buf)->_pp = (buf)->_rp) + +#define ha_buflen(buf) \ + ((buf)->_rp - (buf)->_pp) + +#define ha_bufchar(buf) \ + ((!ha_buferr(buf) && ha_buflen(buf) > 0) ? *((buf)->_pp) : '\0' ) + +#define ha_bufdata(buf) \ + ((buf)->_pp) + +#define ha_bufeat(buf) \ + ((!ha_buferr(buf) && ha_buflen(buf) > 0) ? ++((buf)->_pp) : (buf)->_pp) + +#define ha_buferr(buf) \ + ((buf)->_dt == NULL) + + +/* ----------------------------------------------------------------------- + * HTTP Auth Handlers + */ + +typedef struct ha_context_t; + +/* + * 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)(ha_context_t* 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)(ha_context_t* 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)(ha_context_t* 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)(ha_context_t* ctx, ha_request_t* req, + ha_response_t* resp, ha_buffer_t* mem); + +/* 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 */ + size_t context_size; /* Bytes of extra context needed */ +} +ha_handler_t; + +/* + * OK signifies that things went according to plan. Return + * this even if authentication fails (send auth to user) + * unless something unexpected happens. + */ +#define HA_OK 1 + +/* + * FALSE signifies that we couldn't process but it wasn't + * an error. + */ +#define HA_FALSE 0 + +/* + * ERROR means a bad error happened which will kill the + * current processing thread. Examples are out of memory + * errors or the like. + */ +#define HA_ERROR -1 + + +struct ha_options; + +/* Context passed to the handler functions below */ +typdef struct ha_context +{ + const char* name; /* A name assigned by the configuration file */ + ha_handler_t* handler; /* The original handler structure */ + unsigned int types; /* The types of authentication allowed */ + int timeout; /* Timeout for cached connections */ + void* data; /* Handler specific data */ +} +ha_context_t; + + +/* ----------------------------------------------------------------------- + * HTTP Auth Structures and Constants + */ + +/* + * 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 MAX_ARGS 2 + +/* + * The maximum number of pertinent headers to read + * from 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 MAX_HEADERS 2 + +/* + * The maximum number of handlers. If you add + * handlers make sure to update this number. + */ +#define 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 + +/* A single request from client */ +typedef struct ha_request +{ + int type; + const char* args[MAX_ARGS]; + ha_header_t headers[MAX_HEADERS]; +} +ha_request_t; + +/* The various response codes */ +#define HA_SERVER_READY 100 +#define HA_SERVER_ACCEPT 200 +#define HA_SERVER_DECLINE 401 +#define HA_SERVER_BADREQ 402 +#define HA_SERVER_ERROR 500 +#define HA_SERVER_BUSY 500 + +/* A response to the client */ +typedef struct ha_response +{ + int code; + const char* detail; + ha_header_t headers[MAX_HEADERS]; +} +ha_response_t; + +/* Request functions */ +ha_header_t* ha_findheader(ha_request_t* req, const char* name); +const char* ha_getheader(ha_request_t* req, const char* name, const char* prefix); + +/* Response functions */ +void ha_addheader(ha_response_t* resp, const char* name, const char* data); + +/* Configuration functions */ +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); + +/* A little hashing */ +#ifndef MD5_LEN + #define MD5_LEN 16 +#endif + +void ha_md5string(const char* data, unsigned char* hash); + +/* ----------------------------------------------------------------------- + * Error Handling + */ + +void ha_message(int level, const char* msg, ...); +void ha_messagex(int level, const char* msg, ...); + + +/* ----------------------------------------------------------------------- + * Authentication types + */ + + +/* The various types of authentication */ +#define HA_TYPE_BASIC 1 << 1 +#define HA_PREFIX_BASIC "Basic " + +typedef struct ha_basic_header +{ + const char* user; + const char* password; + unsigned char key[MD5_LEN]; +} +ha_basic_header_t; + +int ha_parsebasic(char* header, ha_buffer_t* buf, ha_basic_header_t* rec); + + +#define HA_TYPE_DIGEST 1 << 2 +#define HA_PREFIX_DIGEST "Digest " +#define HA_DIGEST_NONCE_LEN MD5_LEN * 2 + +/* Parsed Digest response from the client */ +typedef struct ha_digest_header +{ + const char* scheme; + const char* realm; + const char* username; + const char* nonce; + const char* uri; + const char* method; + const char* digest; + const char* algorithm; + const char* cnonce; + const char* opaque; + const char* message_qop; + const char* nc; + unsigned char key[MD5_LEN]; +} +ha_digest_header_t; + +/* Kept by the server for validating the client */ +typedef struct ha_digest_record +{ + unsigned char nonce[HA_DIGEST_NONCE_LEN]; + unsigned char userhash[MD5_LEN]; + unsigned char ha1[MD5_LEN]; + unsigned int nc; +} +ha_digest_record_t; + +int ha_digestparse(char* header, ha_buffer_t* buf, ha_digest_header_t* rec); +int ha_digestcheck(const char* realm, const char* method, const char* uri, + ha_buffer_t* buf, ha_digest_header_t* header, ha_digest_record_t* rec); + + +#define HA_TYPE_NTLM 1 << 3 +#define HA_PREFIX_NTLM "NTLM " + + +/* ----------------------------------------------------------------------- + * URI Parse Support + */ + +struct ha_uri_t +{ + /* Note: We only support HTTP uris */ + const char* user; + const char* pw; + const char* host; + unsigned short port; + const char* path; + const char* query; + const char* bookmark; +}; + + +char* ha_uriformat(const ha_uri_t* uri, ha_buffer_t* buf); +int ha_uriparse(const char* str, ha_uri_t* uri); + + +/* ----------------------------------------------------------------------- + * Locking + */ + +void ha_lock(); +void ha_unlock(); + +#endif /* __HTTPAUTHD_H__ */ |