1 // webcit.h - "header of headers"
3 // Copyright (c) 1996-2024 by the citadel.org team
5 // This program is open source software. Use, duplication, or
6 // disclosure is subject to the GNU General Public License v3.
8 // uncomment one or more of these to see raw http transactions
10 //#define REQUEST_BODY_TO_STDERR
11 //#define RESPONSE_BODY_TO_STDERR
12 //#define DEBUG_XML_PARSE
14 #define SHOW_ME_VAPPEND_PRINTF
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <arpa/inet.h>
43 #include <libical/ical.h>
44 #include <libcitadel.h>
45 #define OPENSSL_NO_KRB5 // Work around RedHat's b0rken OpenSSL includes
46 #include <openssl/ssl.h>
47 #include <openssl/err.h>
48 #include <openssl/rand.h>
50 #define _(x) x // temporary hack until we add i18n back in
52 // XML_StopParser is present in expat 2.x
53 #if XML_MAJOR_VERSION < 2
54 #error WebCit requires expat v2.0 or newer.
57 struct client_handle { // this gets passed up the stack from the webserver to the application code
62 struct keyval { // key/value pair (for array)
67 struct http_transaction { // The lifetime of an HTTP request goes through this data structure.
68 char *method; // The top half is built up by the web server and sent up to the
69 char *url; // application stack. The second half is built up by the application
70 char *http_version; // stack and sent back down to the web server, which transmits it to
71 char *site_prefix; // the client.
72 Array *request_headers;
73 char *request_body_with_synth_headers; // This is the request body with some synthetic headers prepended into it.
74 char *request_body; // this is just going to be a pointer into request_body_with_synth_headers
75 long request_body_length;
76 Array *request_parms; // anything after the "?" in the URL
78 char *response_string;
79 Array *response_headers;
81 long response_body_length;
84 #define AUTH_MAX 256 // Maximum length of an HTTP AUTH header or equivalent cookie data
86 struct ctdlsession *next;
87 int is_bound; // Nonzero if this record is currently bound to a running thread
88 int sock; // Socket connection to Citadel server
89 char auth[AUTH_MAX]; // Auth string (empty if not logged in)
90 char whoami[64]; // Display name of currently logged in user (empty if not logged in)
91 char room[128]; // What room we are currently in
92 int room_current_view;
93 int room_default_view;
94 int is_trash_folder; // nonzero if this room is the user's Trash folder
95 int is_room_aide; // nonzero if the user has aide rights to THIS room
96 int can_delete_messages; // nonzero if the user is permitted to delete messages in THIS room
100 time_t last_access; // Timestamp of last request that used this session
101 time_t num_requests_handled;
102 time_t room_mtime; // Timestampt of the most recent write activity in this room
105 struct uploaded_file { // things that have been uploaded to the server (such as email attachments)
108 char content_type[256];
113 extern char *ssl_cipher_list;
114 extern int is_https; // nonzero if we are an HTTPS server today
115 extern char *ctdl_dir; // directory where Citadel Server is running
117 void starttls(struct client_handle *);
118 void endtls(struct client_handle *);
119 int client_write_ssl(struct client_handle *ch, char *buf, int nbytes);
120 int client_read_ssl(struct client_handle *ch, char *buf, int nbytes);
128 #define TRACE syslog(LOG_DEBUG, "\033[3%dmCHECKPOINT: %s:%d\033[0m", ((__LINE__%6)+1), __FILE__, __LINE__)
129 #define SLEEPING 180 // TCP connection timeout
130 #define MAX_WORKER_THREADS 32 // Maximum number of worker threads permitted to exist
131 #define DEFAULT_SSL_CIPHER_LIST "DEFAULT" // See http://openssl.org/docs/apps/ciphers.html
132 #define WEBSERVER_PORT 80
133 #define WEBSERVER_INTERFACE "*"
134 #define CTDL_DIR "/usr/local/citadel"
135 #define DEVELOPER_ID 0
137 #define TARGET "webcit02" // Window target for inline URL's
138 #define ROOMNAMELEN 128 // The size of a roomname string
139 #define DAV_MOVE 0 // MOVE=0 COPY=1 don't change these!
140 #define DAV_COPY 1 // they are the values used in the Citadel Server MOVE command
143 // Everything below here is generated with this command:
144 // cproto -f2 *.c 2>/dev/null |sed 's/^\/\*/\n\/\//g' | sed 's/\ \*\/$//g'
147 void try_login(struct http_transaction *, struct ctdlsession *);
148 void logout(struct http_transaction *, struct ctdlsession *);
149 void whoami(struct http_transaction *, struct ctdlsession *);
150 void biff(struct http_transaction *, struct ctdlsession *);
151 void ctdl_a(struct http_transaction *, struct ctdlsession *);
154 void caldav_xml_start(void *, const char *, const char **);
155 void caldav_xml_end(void *, const char *);
156 void caldav_xml_chardata(void *, const XML_Char *, int);
157 StrBuf *fetch_ical(struct ctdlsession *, long);
158 void cal_multiget_out(long, StrBuf *, StrBuf *, StrBuf *);
159 void caldav_report_one_item(struct http_transaction *, struct ctdlsession *, StrBuf *, StrBuf *);
160 int caldav_apply_one_filter(void *, char *);
161 int caldav_apply_filters(void *, Array *, int);
162 void caldav_report(struct http_transaction *, struct ctdlsession *);
165 int ctdl_read_binary(struct ctdlsession *, char *, int);
166 int ctdl_readline(struct ctdlsession *, char *, int);
167 StrBuf *ctdl_readtextmsg(struct ctdlsession *);
168 ssize_t ctdl_write(struct ctdlsession *, const void *, size_t);
169 void ctdl_printf(struct ctdlsession *, const char *, ...);
170 int uds_connectsock(char *);
171 void extract_auth(struct http_transaction *, char *, int);
172 int login_to_citadel(struct ctdlsession *, char *, char *);
173 struct ctdlsession *connect_to_citadel(struct http_transaction *);
174 void disconnect_from_citadel(struct ctdlsession *);
177 void serv_info(struct http_transaction *, struct ctdlsession *);
178 void ctdl_c(struct http_transaction *, struct ctdlsession *);
181 void ctdl_delete_msgs(struct ctdlsession *, long *, int);
184 void floor_list(struct http_transaction *, struct ctdlsession *);
185 void ctdl_f(struct http_transaction *, struct ctdlsession *);
188 void setup_for_forum_view(struct ctdlsession *);
189 JsonValue *json_tokenize_recipients(const char *, long, char *);
190 void json_render_one_message(struct http_transaction *, struct ctdlsession *, long);
193 void stripquotes(char *);
194 void extract_charset_from_meta(char *, char *, char *);
195 StrBuf *html2html(const char *, int, char *, long, StrBuf *);
196 void UrlizeText(StrBuf *, StrBuf *, StrBuf *);
197 void url(char *, size_t);
200 int client_write(struct client_handle *, char *, int);
201 int client_read(struct client_handle *, char *, int);
202 int client_readline(struct client_handle *, char *, int);
203 void client_printf(struct client_handle *, const char *, ...);
204 void add_response_header(struct http_transaction *, char *, char *);
205 void perform_one_http_transaction(struct client_handle *);
206 char *header_val(struct http_transaction *, char *);
207 char *get_url_param(struct http_transaction *, char *);
210 int main(int, char **);
213 long locate_message_by_uid(struct ctdlsession *, char *);
214 void dav_delete_message(struct http_transaction *, struct ctdlsession *, long);
215 void dav_move_or_copy_message(struct http_transaction *, struct ctdlsession *, long, int);
216 void dav_get_message(struct http_transaction *, struct ctdlsession *, long);
217 void dav_put_message(struct http_transaction *, struct ctdlsession *, char *, long);
218 void download_mime_component(struct http_transaction *, struct ctdlsession *, long, char *);
221 void do_404(struct http_transaction *);
222 void do_405(struct http_transaction *);
223 void do_412(struct http_transaction *);
224 void do_204(struct http_transaction *);
225 void do_502(struct http_transaction *);
226 void request_http_authenticate(struct http_transaction *);
227 void http_redirect(struct http_transaction *, char *);
228 void perform_request(struct http_transaction *);
231 Array *get_msglist(struct ctdlsession *, char *);
232 int match_etags(char *, long);
233 void json_stat(struct http_transaction *, struct ctdlsession *);
234 void json_mailbox(struct http_transaction *, struct ctdlsession *);
235 void json_msglist(struct http_transaction *, struct ctdlsession *, char *);
236 void read_room_info_banner(struct http_transaction *, struct ctdlsession *);
237 void set_last_read_pointer(struct http_transaction *, struct ctdlsession *);
238 void object_in_room(struct http_transaction *, struct ctdlsession *);
239 void report_the_room_itself(struct http_transaction *, struct ctdlsession *);
240 void options_the_room_itself(struct http_transaction *, struct ctdlsession *);
241 void propfind_the_room_itself(struct http_transaction *, struct ctdlsession *);
242 void get_the_room_itself(struct http_transaction *, struct ctdlsession *);
243 void the_room_itself(struct http_transaction *, struct ctdlsession *);
244 void room_list(struct http_transaction *, struct ctdlsession *);
245 void ctdl_r(struct http_transaction *, struct ctdlsession *);
248 void output_static(struct http_transaction *);
251 int lingering_close(int);
252 int webcit_tcp_server(const char *, int, int);
253 int webcit_uds_server(char *, int);
256 StrBuf *text2html(const char *, int, char *, long, StrBuf *);
257 StrBuf *variformat2html(StrBuf *);
260 void bind_to_key_and_certificate(void);
262 void update_key_and_cert_if_needed(void);
263 void starttls(struct client_handle *);
264 void endtls(struct client_handle *);
265 int client_write_ssl(struct client_handle *, char *, int);
266 int client_read_ssl(struct client_handle *, char *, int);
269 void upload_handler(char *, char *, char *, char *, void *, char *, char *, size_t, char *, char *, void *);
270 void upload_files(struct http_transaction *, struct ctdlsession *);
271 void ctdl_p_base(struct http_transaction *, struct ctdlsession *);
272 void delete_upload(struct uploaded_file);
273 void dav_delete_upload(struct http_transaction *, struct ctdlsession *, struct uploaded_file);
274 struct uploaded_file pop_upload(char *);
275 void attachment_filter(char *, char *, char *, char *, void *, char *, char *, size_t, char *, char *, void *);
276 void load_attachments_from_message(struct http_transaction *, struct ctdlsession *, char *);
277 void specific_upload(struct http_transaction *, struct ctdlsession *, char *);
278 void ctdl_p(struct http_transaction *, struct ctdlsession *);
281 void fetch_user_photo(struct http_transaction *, struct ctdlsession *, char *);
282 void fetch_user_bio(struct http_transaction *, struct ctdlsession *, char *);
283 void object_in_user(struct http_transaction *, struct ctdlsession *, char *);
284 void the_user_itself(struct http_transaction *, struct ctdlsession *, char *);
285 void user_list(struct http_transaction *, struct ctdlsession *);
286 void ctdl_u(struct http_transaction *, struct ctdlsession *);
289 int unescape_input(char *);
290 char *http_datestring(time_t);
293 void spawn_another_worker_thread(int *);
294 void worker_entry(int *);
295 int webserver(char *, int, int);