Kagera uHTTP Daemon
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

198 lines
6.7 KiB

/**
* @PROJECT Kagera uHTTP Daemon
* @COPYRIGHT See COPYING in the top level directory
* @FILE kuhttpd.h
* @PURPOSE HTTP Server
* @DEVELOPERS Rafal Kupiec <belliash@asiotec.eu.org>
* Jef Poskanzer <jef@acme.com>
*/
#ifndef __KUHTTPD_H
#define __KUHTTPD_H
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define SIZE_T_MAX 2147483647L
#define ERR_DIR "errors"
#define DEFAULT_HTTP_PORT 80
#define DEFAULT_HTTPS_PORT 443
#define DEFAULT_CERTFILE "kuhttpd.pem"
#define DEFAULT_CHARSET "UTF-8"
#define DEFAULT_LANGUAGE "english"
#define DEFAULT_CGI_PATTERN "cgi-bin/**|**.cgi|**.sh"
#define DEFAULT_USER "nobody"
#define CGI_NICE 10
#define CGI_PATH "/usr/local/bin:/usr/ucb:/bin:/usr/bin:/usr/local/sbin:/sbin:/usr/sbin"
#define CGI_LD_LIBRARY_PATH "/usr/local/lib:/usr/lib:/lib"
#define AUTH_FILE ".htpasswd"
#define READ_TIMEOUT 60
#define WRITE_TIMEOUT 300
#define METHOD_UNKNOWN 0
#define METHOD_GET 1
#define METHOD_HEAD 2
#define METHOD_POST 3
#define SERVER_SOFTWARE "Kagera uHTTP Daemon 1.4"
struct mime_entry {
char* ext;
size_t ext_len;
char* val;
size_t val_len;
};
typedef union {
struct sockaddr sa;
struct sockaddr_in sa_in;
struct sockaddr_in6 sa_in6;
struct sockaddr_storage sa_stor;
} usockaddr;
static int b64_decode_table[256] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,
52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
-1, 0, 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,-1,-1,-1,-1,-1,
-1,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,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};
static unsigned char allowDirectoryListing;
static char* argv0;
static char* data_dir;
static char* certfile;
static char* cgi_pattern;
static char* charset;
static char* language;
static char* cipher;
static char cwd[MAXPATHLEN];
static int debug;
static char* defaultPageFile;
static char* defaultRealmName;
static char* defaultRealmPasswordFile;
static char* dir;
static int do_ssl;
static int got_hup;
static char* hostname;
static char hostname_buf[500];
static int listen4_fd, listen6_fd;
static int listen4s_fd, listen6s_fd;
static char* local_pattern;
static char* logfile;
static FILE* logfp;
static int max_age;
static int no_empty_referers;
static char* p3p;
static char* pageNotFoundFile;
static char* pidfile;
static unsigned short port;
static SSL_CTX* ssl_ctx;
static unsigned short sslPort;
static char* url_pattern;
static char* user;
static off_t bytes;
static usockaddr client_addr;
static int conn_fd;
static char* file;
static int method;
static char* path;
static char* pathinfo;
static char* protocol;
static char* query;
static char* request;
static size_t request_size, request_len, request_idx;
struct stat sb;
static SSL* ssl;
static int status;
static char* authorization;
static size_t content_length;
static char* content_type;
static char* cookie;
static char* host;
static time_t if_modified_since;
static char* referer;
static char* remoteuser;
static char* response;
static size_t response_size, response_len;
static char* useragent;
static void add_headers(int s, char* title, char* extra_header, char* me, char* mt, off_t b, time_t mod);
static void add_to_buf(char** bufP, size_t* bufsizeP, size_t* buflenP, char* str, size_t len);
static void add_to_request(char* str, size_t len);
static void add_to_response(char* str, size_t len);
static void auth_check(char* dirname, int is_ssl);
static int b64_decode(const char* str, unsigned char* space, int size);
static char* build_env(char* fmt, char* arg);
static void cgi_interpose_input(int wfd, int is_ssl);
static void cgi_interpose_output(int rfd, int parse_headers, int is_ssl);
static void check_referer(int is_ssl);
static void clear_ndelay(int fd);
extern char* crypt(const char* key, const char* setting);
static void de_dotdot(char* file);
static void do_cgi(int is_ssl, unsigned short port);
static void do_dir(int is_ssl);
static void do_file(int is_ssl, unsigned short conn_port);
static void* e_malloc(size_t size);
static void* e_realloc(void* optr, size_t size);
static char* e_strdup(char* ostr);
static const char* figure_mime(char* name, char* me, size_t me_size);
static char* file_details(const char* dir, const char* name);
static char* get_method_str(int m);
static int get_pathinfo(void);
static char* get_request_line(void);
static void handle_read_timeout(int sig, int is_ssl);
static void handle_read_timeout_sig(int sig);
static void handle_request(int is_ssl, unsigned short conn_port);
static void handle_sigchld(int sig);
static void handle_sighup(int sig);
static void handle_sigterm(int sig);
static void handle_write_timeout(int sig);
static int hexit(char c);
static void init_mime(void);
static int initialize_listen_socket(usockaddr* usaP);
static void lookup_hostname(usockaddr* usa4P, usockaddr* usa4sP, size_t sa4_len, int* gotv4P, int* gotv4sP, usockaddr* usa6P, usockaddr* usa6sP, size_t sa6_len, int* gotv6P, int* gotv6sP);
static char** make_argp(void);
static char** make_envp(int is_sl, unsigned short port);
static void make_log_entry(void);
static char* ntoa(usockaddr* usaP);
static ssize_t my_read(char* buf, size_t size, int is_ssl);
static ssize_t my_write(char* buf, size_t size, int is_ssl);
static void no_value_required(char* name, char* value);
static void post_post_garbage_hack(int is_ssl);
static void read_config(char* filename);
static int really_check_referer(void);
static void reopen_logfile(void);
static void send_authenticate(char* realm, int is_ssl);
static void send_error(int s, char* title, char* extra_header, char* text, int is_ssl);
static void send_error_body(int s, char* title, char* text);
static int send_error_file(char* filename);
static void send_error_tail(void);
static void send_redirect(char* extra_header, char* hostname, char* new_location, int is_ssl);
static void send_response(int is_ssl);
static void send_via_write(int fd, off_t size, int is_ssl);
static void set_ndelay(int fd);
static int sockaddr_check(usockaddr* usaP);
static size_t sockaddr_len(usockaddr* usaP);
static void start_request(void);
static void start_response(void);
static void strdecode(char* to, char* from);
static void strencode(char* to, size_t tosize, const char* from);
static void usage(void);
static void value_required(char* name, char* value);
#endif