/* -*- C -*- * POP3Lite - 3lite POP3 Daemon * Copyright (C) 2000, 2001 Gergely Nagy <8@free.bsd.hu> * * This file is part of POP3Lite. * * POP3Lite 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. * * POP3Lite 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 */ /* * $Id: pop3lite.h.in,v 1.9 2001/01/12 16:02:59 algernon Exp $ */ #ifndef __POP3LITE_H__ #define __POP3LITE_H__ 1 #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define POP3LITE_VERSION "0.2.4a" /** * Some convenience macros **/ #define P3L_GET_OPTION(opt) (GList *) g_hash_table_lookup ( control->config, opt ) #define P3L_GET_NTH_OPTION(opt,n) (char *) g_list_nth_data ( P3L_GET_OPTION(opt), n ) #define P3L_GET_FIRST_OPTION(opt) P3L_GET_NTH_OPTION ( opt, 0 ) #define P3L_GET_DATA(key) (char *) g_hash_table_lookup ( control->data, key ) #define P3L_CALL_HOOK(type,hook) (* (type) g_hash_table_lookup ( control->hooks, hook ) ) #define P3L_CMD_EXISTS(hash,cmd) ( g_hash_table_lookup ( control->hash, cmd ) != NULL ) #define P3L_HOOK_EXISTS(hook) P3L_CMD_EXISTS ( hooks, hook ) #define p3l_clear(str) \ do { \ register char *__xx__; \ if ( ( __xx__ = (str) ) ) \ while ( *__xx__ ) \ *__xx__++ = '\0'; \ } while ( 0 ) /** * POP3Code: Used in conjunction with p3l_respond. * * + POP3_NOTHING: No POP3 status indicator (+OK, -ERR) is sent, * only the message. * + POP3_ANSWERED: Same as POP3_NOTHING, but has a different meaning * when dealing with inheritance. * + POP3_OK: An +OK indicator is sent before the message. * + POP3_OK_HIDDEN: This is the same as POP3_OK, but the indicator * won't be sent. Useful for functions which call their previous * version. (Eg, when a function falls back to something) * + POP3_OK_EXIT: Same as POP3_OK, but exit immediately after * sending the message. * + POP3_ERR: Send an +ERR indicator before the message * + POP3_FATAL: Same as POP3_ERR, but exit immediately after * sending the message. **/ typedef enum { POP3_NOTHING, POP3_ANSWERED, POP3_OK, POP3_OK_HIDDEN, POP3_OK_EXIT, POP3_ERR, POP3_FATAL } POP3Code; /** * POP3State: the actual state of the POP3 Session * + POP3_STATE_AUTH: authentication state. * + POP3_STATE_TRANS: transaction state. * + POP3_STATE_UPDATE: update state. **/ typedef enum { POP3_STATE_AUTH, POP3_STATE_TRANS, POP3_STATE_UPDATE } POP3State; /** * AuthResult: result of authentication * * + AUTH_RESULT_OK: success * + AUTH_RESULT_FAIL: auth. failed, reason unspecified * + AUTH_RESULT_FAIL_USER: wrong username * + AUTH_RESULT_FAIL_PASS: wrong password **/ typedef enum { AUTH_RESULT_OK, AUTH_RESULT_FAIL, AUTH_RESULT_FAIL_USER, AUTH_RESULT_FAIL_PASS } AuthResult; /** * CommandResponse: every command implementation returns this. * * Each and every function that implements a POP3 command, MUST * return a variable of this type. This allows a command to * call another and be sure that the other doesn't send * anything. (In most cases, eg RETR is an exception) **/ typedef struct _CommandResponse CommandResponse; struct _CommandResponse { POP3Code code; char *message; }; /** * UserInfo: information about a user * * This is mainly used by the auth abstraction layer. **/ typedef struct _UserInfo UserInfo; struct _UserInfo { char *name; uid_t uid; gid_t gid; char *gecos; char *home; char *shell; long expire; }; /** Pre-declarations to be used by the hooks **/ typedef struct _P3LControl P3LControl; typedef struct _SysControl SysControl; /*********************************************** * P3LControl & SysControl function prototypes * ***********************************************/ /** * P3LHook_get_mailbox: GET-MAILBOX hook * @control: the main control struct * * This hook is used to retrieve the FILENAME (or equivalent, if it is * not a file) of the mailbox. * * Returns: a newly allocated string containing the result, or NULL on * failure. **/ typedef char *(*P3LHook_get_mailbox) ( P3LControl *control ); /** * P3LControl_greeting: Send the initial greeting. * @control: the main control struct * * This special hook is responsible for sending the initial POP3 * greeting. * * Returns: +OK [Greeting] in a CommandResponse **/ typedef CommandResponse *(*P3LControl_greeting) ( P3LControl *control ); /** * P3LControl_send_response: send POP3 Response * @control: the main control struct * @code: POP3 response code * @message: the message itself * * This hook is used to send almost all server responses. * * Returns: nothing, this is an end-point. **/ typedef void (*P3LControl_send_response) ( P3LControl *control, POP3Code code, const char *message ); /** * P3LControl_send_raw: send RAW data to the client * @control: the main control struct * @data: the data to send * @size: size of the data to send * * This is used to send raw data to the client, ideally, the * send_response hook should call it only. Except for the RETR/TOP/etc * commands, which return multiline input. * * Returns: nothing, this is an end-point. **/ typedef void (*P3LControl_send_raw) ( P3LControl *control, const gpointer data, size_t size ); /** * P3LControl_trans_init: Initialise TRANSACTION state * @control: the main control struct * * This hook should initialise the transaction state, by locking the * mailbox, preparing uidls, etc. When this is called, the user is * authenticated, and the privileges are (hopefully) dropped. * * Returns: +OK [some greeting message] on success, -ERR [reason] * otherwise. **/ typedef CommandResponse *(*P3LControl_trans_init) ( P3LControl *control ); /** * P3LControl_update: handle the UPDATE state * @control: the main control struct * * This one does the really hard job: updating the mailbox. Errors * should always be fatal in this state. * * Returns: +OK [exit message] or -ERR [reason] **/ typedef CommandResponse *(*P3LControl_update) ( P3LControl *control ); /** * P3LSysCon_getuinam: Get UserInfo by name * @control: the main control struct * @name: the user's name * * This hook collects all the information listed in UserInfo about the * specified user. * * Returns: a newly allocated, filled out UserInfo struct. **/ typedef UserInfo *(*P3LSysCon_getuinam) ( P3LControl *control, const char *name ); /** * P3LSysCon_authenticate: Do the effective authentication * @control: the main control struct * @name: username * @pass: password (probably clear-text) * * This hook is intended to authenticate the user. This is not a * command handler, it has nothing to do with the AUTH command. This * is merely here to separate the authentication mechanism from * command handling. Be very careful, when you replace this! * * Returns: the result of the authentication **/ typedef AuthResult (*P3LSysCon_authenticate) ( P3LControl *control, const char *name, const char *pass ); /** * P3LSysCon_drop_privileges: drop all possible privileges * @control: the main control struct * * This hook is used to get rid of ALL special privileges. Do not * change this! The only possible reason you might want to override * this is when you run POP3Lite on a Non-Unix system. * * Returns: nothing. **/ typedef void (*P3LSysCon_drop_privileges) ( P3LControl *control ); /** * P3LSysCon_openlog: open the logfile, or facility * @control: the main control struct * * This hook should open the logfile, or tell syslog about the * program. * * Returns: nothing. **/ typedef void (*P3LSysCon_openlog) ( P3LControl *control ); /** * P3LSysCon_log: do the actual logging * @control: the main control struct * @priority: message priority, see * @format: printf-style format string * * This hooks does the actual logging. * * Returns: nothing **/ typedef void (*P3LSysCon_log) ( P3LControl *control, int priority, const char *format, ... ); /** * P3LSysCon_closelog: close the logfile or facility * @control: the main control struct * * This hook should close the logfile or anything openlog opened. * * Returns: nothing **/ typedef void (*P3LSysCon_closelog) ( P3LControl *control ); /** * SysControl: system-specific control functions * * Change with extreme caution! **/ struct _SysControl { P3LSysCon_getuinam getuinam; P3LSysCon_authenticate authenticate; P3LSysCon_drop_privileges drop_privileges; P3LSysCon_openlog openlog; P3LSysCon_log log; P3LSysCon_closelog closelog; /** A GList of UserInfo structs, serves as a cache **/ GList *users; /** Miscelleanous system-specific data **/ GHashTable *data; }; /** * P3LControl: the main control structure. * * The whole POP3Lite session is controlled via this * structure. See the docs for more info. **/ struct _P3LControl { P3LControl_greeting greeting; P3LControl_send_response send_response; P3LControl_send_raw send_raw; P3LControl_trans_init trans_init; P3LControl_update update; /** Commands available in the AUTHENTICATION state **/ GHashTable *auth_commands; /** Commands available in the TRANSACTION state **/ GHashTable *trans_commands; /** Misc. capabilities, mainly useful for the CAPA module **/ GHashTable *capabilities; /** Session-related data, such as the username, etc **/ GHashTable *data; /** Configuration data, it should NOT be modified **/ GHashTable *config; /** A table of loaded modules **/ GHashTable *modules; /** The current state of our session **/ POP3State state; /** A GList of MessageInfo structs **/ GList *msg_info; /** System-specific hooks **/ SysControl *system; /** Misc. hooks, used throughout the daemon **/ GHashTable *hooks; }; /** * P3LString: NULL-aware string representation **/ typedef struct _P3LString P3LString; struct _P3LString { unsigned long length; char *str; }; /** * p3l_module_hook: module_init/module_done definition * int module_init ( P3LControl *control) * int module_done ( P3LControl *control) * Returns 0 on succes, anything else on failure **/ typedef int (*p3l_module_hook) ( P3LControl *control ); /** * HandlerInfo: information about a signal handler * * This is used by the main SIGALRM handler **/ typedef struct _HandlerInfo HandlerInfo; struct _HandlerInfo { unsigned int counter; unsigned int tick_max; p3l_module_hook hook; }; /** * p3l_pop3_command: definition for POP3 Commands * @control: the main control struct * @arguments: the arguments as read from the client * * Returns: Whatever it likes... **/ typedef CommandResponse *(*p3l_pop3_command) ( P3LControl *control, const char *arguments ); /** * MailInfo: information about a message * * Many default commands use this to give information to the user, * without having to re-read the whole mailbox. * * The fields that are driver-independent: * + virtual_size: the size the message is said to be, * after replacing the From [...] header with our own * Received: header. This should be fully independent * of everything, no matter where the message is read * from, functions using this (and only this or other * independent fields) can be left untouched when * adding a new driver (maildir eg) * + digest: MD5 digest of the message. Should be * independent. * + deleted: deleted state of the message. * * The other fields are: * + driver_data: driver-dependent data **/ typedef struct _MailInfo MailInfo; struct _MailInfo { size_t virtual_size; char digest[16]; gboolean deleted; GHashTable *driver_data; }; /** * p3l_received_header: return a POP3Lite header * @data: control->data * * Constructcs a Received: header * * Returns: the header, which should be freed **/ char *p3l_received_header ( GHashTable *data ); /** * p3l_parse_buffer: replace From [...] with Received: * @buffer: the mail text * @data: control->data * @buffer_size: size of the buffer * @new_size: pointer where the new size will be placed * * Replaces the first line (From [...]) of the message with * the POP3Lite-specific Received: header. (buffer will be * freed!) * * Returns: the new buffer **/ char *p3l_parse_buffer ( char *buffer, GHashTable *data, size_t buffer_size, size_t *new_size ); /** * p3l_respond: generate a POP3Lite response * code: response code see %POP3Code abouce * message: the actual message * * Generates a response suitable to be used as the * return value of POP3 Command implementations. * * Returns: the POP3Lite response struct **/ CommandResponse *p3l_respond ( POP3Code code, const char *message ); /** * p3l_is_enabled: check if an option is enabled * @option: the option string * * Parses @option, and returns a boolean indicating * wheter it is enabled or not. (true, yes, on means * enabled, everything else is disabled) * * Returns: a boolean **/ gboolean p3l_is_enabled ( const char *option ); /** * bintohex: convert a binary string to hexadecimal * @ptr: the binary sequence * @size: length of the sequence * @checkendian: wheter to check endianness, or not * * Converts a binary sequence to its hexadecimal * representation. * * Returns: the hexadecimal representation **/ const char *bintohex ( const void *ptr, size_t size, const int checkendian ); /** * p3l_command_replace: replace a command * @commands: the command table (control->{auth,trans}_commands * @name: the command name * @new_command: the new command * * Replaces a command in a given table. * * Returns: the old command **/ const gpointer p3l_command_replace ( GHashTable *commands, const char *name, gpointer new_command ); /** * p3l_split_lines: split a buffer into lines * @buffer: source * @size: the buffer's size * * Splits the buffer into lines. This is NULL-aware, that means, * that the strings are NOT null terminated, therefore, their * size must be stored. * * Returns: a pointer to a P3LString array **/ P3LString **p3l_split_lines ( char *buffer, size_t size, size_t *lines ); /** * p3l_lock_fd: lock a file * @fd: file descriptor * @fn: file name, in case we use lockfile_create * * Locks a file. * * Returns: 0 on success, -1 otherwise **/ int p3l_lock_fd ( int fd, char *fn ); /** * p3l_unlock_fd: unlock a file * @fd: file descriptor * @fn: file name, in case we use lockfile_create * * Unlocks a file. * * Returns: 0 on success, -1 otherwise **/ int p3l_unlock_fd ( int fd, char *fn ); /** * p3l_read_file: read the contents of a file * @fn: filename * @size: variable to put filesize into * * Opens the file and reads its contents. * * Returns: the contents, free-able **/ gpointer p3l_read_file ( const char *filename, size_t *size ); /** * p3l_read_fd: read the contents of an opened file * @fd: file descriptor * @size: variable to put filesize into * * Reads the contents of an already opened file. * * Returns: the contents, free-able **/ gpointer p3l_read_fd ( int fd, size_t *size ); /** * p3l_load_config: loads configuration * @control: the usual control struct * @filename: where to load configuration from * @table: destination * * This loads a configuration file. * * Returns: nothing **/ void p3l_load_config ( P3LControl *control, const char *filename, GHashTable *table ); /** * p3l_get_peer_name: get the peer's hostname * * This one figures out the remote end's hostname. * * Returns: the hostname. **/ char *p3l_get_peer_name ( void ); /** * p3l_is_numeric: check if a string represents a number * @str: the string to check * * Determines if a string represents a number or not. * * Returns: TRUE if it does, FALSE if not. **/ gboolean p3l_is_numeric ( const char* str ); /** * p3l_register_alarm: register an alarm hook * @hook: the hook to run * @interval: the interval (in seconds) to wait between calls * * Installs a new hook to run on SIGALRM. * * Returns: nothing. **/ void p3l_register_alarm ( p3l_module_hook hook, unsigned int interval ); /** * p3l_get_alarm_hooks: returns the registered SIGALRM hooks * * This function returns a GList of HandlerInfo structs of the * registered SIGALRM hooks. * * Returns: the list **/ GList *p3l_get_alarm_hooks ( void ); /** * p3l_unregister_alarm: unregister an alarm hook * @hook: the hook to remove * * Removes an registered SIGALRM hook. * * Returns: nothing. **/ void p3l_unregister_alarm ( p3l_module_hook hook ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ! __POP3LITE_H__ */