1 // webcit.h - "header of headers"
3 // Copyright (c) 1996-2023 by the citadel.org team
5 // This program is open source software. You can redistribute it and/or
6 // modify it under the terms of the GNU General Public License, version 3.
8 #define SHOW_ME_VAPPEND_PRINTF
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
37 #include <libical/ical.h>
38 #include <libcitadel.h>
39 #define OPENSSL_NO_KRB5 // Work around RedHat's b0rken OpenSSL includes
40 #include <openssl/ssl.h>
41 #include <openssl/err.h>
42 #include <openssl/rand.h>
44 #define _(x) x // temporary hack until we add i18n back in
45 //#define DEBUG_HTTP // uncomment to debug HTTP headers
47 // XML_StopParser is present in expat 2.x
48 #if XML_MAJOR_VERSION > 1
49 #define HAVE_XML_STOPPARSER
52 struct client_handle { // this gets passed up the stack from the webserver to the application code
57 struct keyval { // key/value pair (for array)
62 struct http_transaction { // The lifetime of an HTTP request goes through this data structure.
63 char *method; // The top half is built up by the web server and sent up to the
64 char *url; // application stack. The second half is built up by the application
65 char *http_version; // stack and sent back down to the web server, which transmits it to
66 char *site_prefix; // the client.
67 Array *request_headers;
68 char *request_body_with_synth_headers; // This is the request body with some synthetic headers prepended into it.
69 char *request_body; // this is just going to be a pointer into request_body_with_synth_headers
70 long request_body_length;
71 Array *request_parms; // anything after the "?" in the URL
73 char *response_string;
74 Array *response_headers;
76 long response_body_length;
79 #define AUTH_MAX 256 // Maximum length of an HTTP AUTH header or equivalent cookie data
81 struct ctdlsession *next;
82 int is_bound; // Nonzero if this record is currently bound to a running thread
83 int sock; // Socket connection to Citadel server
84 char auth[AUTH_MAX]; // Auth string (empty if not logged in)
85 char whoami[64]; // Display name of currently logged in user (empty if not logged in)
86 char room[128]; // What room we are currently in
87 int room_current_view;
88 int room_default_view;
89 int is_trash_folder; // nonzero if this room is the user's Trash folder
90 int is_room_aide; // nonzero if the user has aide rights to THIS room
91 int can_delete_messages; // nonzero if the user is permitted to delete messages in THIS room
95 time_t last_access; // Timestamp of last request that used this session
96 time_t num_requests_handled;
97 time_t room_mtime; // Timestampt of the most recent write activity in this room
100 struct uploaded_file { // things that have been uploaded to the server (such as email attachments)
103 char content_type[256];
108 extern char *ssl_cipher_list;
109 extern int is_https; // nonzero if we are an HTTPS server today
110 extern char *ctdl_dir; // directory where Citadel Server is running
112 void starttls(struct client_handle *);
113 void endtls(struct client_handle *);
114 int client_write_ssl(struct client_handle *ch, char *buf, int nbytes);
115 int client_read_ssl(struct client_handle *ch, char *buf, int nbytes);
123 #define TRACE syslog(LOG_DEBUG, "\033[3%dmCHECKPOINT: %s:%d\033[0m", ((__LINE__%6)+1), __FILE__, __LINE__)
124 #define SLEEPING 180 // TCP connection timeout
125 #define MAX_WORKER_THREADS 32 // Maximum number of worker threads permitted to exist
126 #define DEFAULT_SSL_CIPHER_LIST "DEFAULT" // See http://openssl.org/docs/apps/ciphers.html
127 #define WEBSERVER_PORT 80
128 #define WEBSERVER_INTERFACE "*"
129 #define CTDL_DIR "/usr/local/citadel"
130 #define DEVELOPER_ID 0
132 #define TARGET "webcit02" // Window target for inline URL's
133 #define ROOMNAMELEN 128 // The size of a roomname string
134 #define DAV_MOVE 0 // MOVE=0 COPY=1 don't change these!
135 #define DAV_COPY 1 // they are the values used in the Citadel Server MOVE command
137 void try_login(struct http_transaction *h, struct ctdlsession *c);
138 void logout(struct http_transaction *h, struct ctdlsession *c);
139 void whoami(struct http_transaction *h, struct ctdlsession *c);
140 void biff(struct http_transaction *h, struct ctdlsession *c);
141 void ctdl_a(struct http_transaction *h, struct ctdlsession *c);
142 void caldav_xml_start(void *data, const char *el, const char **attr);
143 void caldav_xml_end(void *data, const char *el);
144 void caldav_xml_chardata(void *data, const XML_Char *s, int len);
145 StrBuf *fetch_ical(struct ctdlsession *c, long msgnum);
146 void caldav_response(struct http_transaction *h, struct ctdlsession *c, StrBuf *ReportOut, StrBuf *ThisHref);
147 void caldav_report(struct http_transaction *h, struct ctdlsession *c);
148 void calendar_msglist(struct http_transaction *h, struct ctdlsession *c, char *range);
149 int ctdl_read_binary(struct ctdlsession *ctdl, char *buf, int bytes_requested);
150 int ctdl_readline(struct ctdlsession *ctdl, char *buf, int maxbytes);
151 StrBuf *ctdl_readtextmsg(struct ctdlsession *ctdl);
152 ssize_t ctdl_write(struct ctdlsession *ctdl, const void *buf, size_t count);
153 void ctdl_printf(struct ctdlsession *ctdl, const char *format, ...);
154 int uds_connectsock(char *sockpath);
155 void extract_auth(struct http_transaction *h, char *authbuf, int authbuflen);
156 int login_to_citadel(struct ctdlsession *c, char *auth, char *resultbuf);
157 struct ctdlsession *connect_to_citadel(struct http_transaction *h);
158 void disconnect_from_citadel(struct ctdlsession *ctdl);
159 void serv_info(struct http_transaction *h, struct ctdlsession *c);
160 void ctdl_c(struct http_transaction *h, struct ctdlsession *c);
161 void ctdl_delete_msgs(struct ctdlsession *c, long *msgnums, int num_msgs);
162 void floor_list(struct http_transaction *h, struct ctdlsession *c);
163 void ctdl_f(struct http_transaction *h, struct ctdlsession *c);
164 void setup_for_forum_view(struct ctdlsession *c);
165 JsonValue *json_tokenize_recipients(const char *Key, long keylen, char *recp);
166 void json_render_one_message(struct http_transaction *h, struct ctdlsession *c, long msgnum);
167 void stripquotes(char *s);
168 void extract_charset_from_meta(char *charset, char *meta_http_equiv, char *meta_content);
169 StrBuf *html2html(const char *supplied_charset, int treat_as_wiki, char *roomname, long msgnum, StrBuf *Source);
170 void UrlizeText(StrBuf *Target, StrBuf *Source, StrBuf *WrkBuf);
171 void url(char *buf, size_t bufsize);
172 int client_write(struct client_handle *ch, char *buf, int nbytes);
173 int client_read(struct client_handle *ch, char *buf, int nbytes);
174 int client_readline(struct client_handle *ch, char *buf, int maxbytes);
175 void client_printf(struct client_handle *ch, const char *format, ...);
176 void add_response_header(struct http_transaction *h, char *key, char *val);
177 void perform_one_http_transaction(struct client_handle *ch);
178 char *header_val(struct http_transaction *h, char *requested_header);
179 char *get_url_param(struct http_transaction *h, char *requested_param);
180 int main(int argc, char **argv);
181 long locate_message_by_uid(struct ctdlsession *c, char *uid);
182 void dav_delete_message(struct http_transaction *h, struct ctdlsession *c, long msgnum);
183 void dav_move_or_copy_message(struct http_transaction *h, struct ctdlsession *c, long msgnum, int move_or_copy);
184 void dav_get_message(struct http_transaction *h, struct ctdlsession *c, long msgnum);
185 void dav_put_message(struct http_transaction *h, struct ctdlsession *c, char *euid, long old_msgnum);
186 void download_mime_component(struct http_transaction *h, struct ctdlsession *c, long msgnum, char *partnum);
187 void do_404(struct http_transaction *h);
188 void do_405(struct http_transaction *h);
189 void do_412(struct http_transaction *h);
190 void do_204(struct http_transaction *h);
191 void do_502(struct http_transaction *h);
192 void request_http_authenticate(struct http_transaction *h);
193 void http_redirect(struct http_transaction *h, char *to_where);
194 void perform_request(struct http_transaction *h);
195 int match_etags(char *taglist, long msgnum);
196 void json_stat(struct http_transaction *h, struct ctdlsession *c);
197 void json_mailbox(struct http_transaction *h, struct ctdlsession *c);
198 void json_msglist(struct http_transaction *h, struct ctdlsession *c, char *which);
199 void read_room_info_banner(struct http_transaction *h, struct ctdlsession *c);
200 void set_last_read_pointer(struct http_transaction *h, struct ctdlsession *c);
201 void object_in_room(struct http_transaction *h, struct ctdlsession *c);
202 void report_the_room_itself(struct http_transaction *h, struct ctdlsession *c);
203 void options_the_room_itself(struct http_transaction *h, struct ctdlsession *c);
204 void propfind_the_room_itself(struct http_transaction *h, struct ctdlsession *c);
205 void get_the_room_itself(struct http_transaction *h, struct ctdlsession *c);
206 void the_room_itself(struct http_transaction *h, struct ctdlsession *c);
207 void room_list(struct http_transaction *h, struct ctdlsession *c);
208 void ctdl_r(struct http_transaction *h, struct ctdlsession *c);
209 void output_static(struct http_transaction *h);
210 int lingering_close(int fd);
211 int webcit_tcp_server(const char *ip_addr, int port_number, int queue_len);
212 int webcit_uds_server(char *sockpath, int queue_len);
213 StrBuf *text2html(const char *supplied_charset, int treat_as_wiki, char *roomname, long msgnum, StrBuf *Source);
214 StrBuf *variformat2html(StrBuf *Source);
215 void bind_to_key_and_certificate(void);
217 void update_key_and_cert_if_needed(void);
218 void starttls(struct client_handle *ch);
219 void endtls(struct client_handle *ch);
220 int client_write_ssl(struct client_handle *ch, char *buf, int nbytes);
221 int client_read_ssl(struct client_handle *ch, char *buf, int nbytes);
222 void upload_handler(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *userdata);
223 void upload_files(struct http_transaction *h, struct ctdlsession *c);
224 void ctdl_p_base(struct http_transaction *h, struct ctdlsession *c);
225 void delete_upload(struct uploaded_file this_one);
226 void dav_delete_upload(struct http_transaction *h, struct ctdlsession *c, struct uploaded_file this_one);
227 struct uploaded_file pop_upload(char *id);
228 void attachment_filter(char *name, char *filename, char *partnum, char *disp, void *content, char *cbtype, char *cbcharset, size_t length, char *encoding, char *cbid, void *userdata);
229 void load_attachments_from_message(struct http_transaction *h, struct ctdlsession *c, char *name);
230 void specific_upload(struct http_transaction *h, struct ctdlsession *c, char *name);
231 void ctdl_p(struct http_transaction *h, struct ctdlsession *c);
232 void fetch_user_photo(struct http_transaction *h, struct ctdlsession *c, char *username);
233 void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c, char *username);
234 void object_in_user(struct http_transaction *h, struct ctdlsession *c, char *requested_username);
235 void the_user_itself(struct http_transaction *h, struct ctdlsession *c, char *username);
236 void user_list(struct http_transaction *h, struct ctdlsession *c);
237 void ctdl_u(struct http_transaction *h, struct ctdlsession *c);
238 int unescape_input(char *buf);
239 char *http_datestring(time_t xtime);
240 void spawn_another_worker_thread(int *pointer_to_master_socket);
241 void worker_entry(int *pointer_to_master_socket);
242 int webserver(char *webserver_interface, int webserver_port, int webserver_protocol);
243 Array *get_msglist(struct ctdlsession *c, char *which_msgs);