b5b8bb2e34a8ee823b5810d4dd9404ac039e1086
[citadel.git] / webcit-ng / server / webcit.h
1 // webcit.h - "header of headers"
2 //
3 // Copyright (c) 1996-2024 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, or
6 // disclosure is subject to the GNU General Public License v3.
7
8 // uncomment one or more of these to see raw http transactions
9 #define DEBUG_HTTP
10 #define REQUEST_BODY_TO_STDERR
11 //#define RESPONSE_BODY_TO_STDERR
12
13 #define SHOW_ME_VAPPEND_PRINTF
14
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <syslog.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <netdb.h>
28 #include <sys/un.h>
29 #include <sys/poll.h>
30 #include <time.h>
31 #include <sys/time.h>
32 #include <string.h>
33 #include <pwd.h>
34 #include <errno.h>
35 #include <stdarg.h>
36 #include <pthread.h>
37 #include <signal.h>
38 #include <syslog.h>
39 #include <stdarg.h>
40 #include <limits.h>
41 #include <iconv.h>
42 #include <libical/ical.h>
43 #include <libcitadel.h>
44 #define OPENSSL_NO_KRB5                         // Work around RedHat's b0rken OpenSSL includes
45 #include <openssl/ssl.h>
46 #include <openssl/err.h>
47 #include <openssl/rand.h>
48 #include <expat.h>
49 #define _(x)    x                               // temporary hack until we add i18n back in
50
51 // XML_StopParser is present in expat 2.x
52 #if XML_MAJOR_VERSION < 2
53 #error WebCit requires expat v2.0 or newer.
54 #endif
55
56 struct client_handle {                          // this gets passed up the stack from the webserver to the application code
57         int sock;
58         SSL *ssl_handle;
59 };
60
61 struct keyval {                                 // key/value pair (for array)
62         char *key;
63         char *val;
64 };
65
66 struct http_transaction {                       // The lifetime of an HTTP request goes through this data structure.
67         char *method;                           // The top half is built up by the web server and sent up to the
68         char *url;                              // application stack.  The second half is built up by the application
69         char *http_version;                     // stack and sent back down to the web server, which transmits it to
70         char *site_prefix;                      // the client.
71         Array *request_headers;
72         char *request_body_with_synth_headers;  // This is the request body with some synthetic headers prepended into it.
73         char *request_body;                     // this is just going to be a pointer into request_body_with_synth_headers
74         long request_body_length;
75         Array *request_parms;                   // anything after the "?" in the URL
76         int response_code;
77         char *response_string;
78         Array *response_headers;
79         char *response_body;
80         long response_body_length;
81 };
82
83 #define AUTH_MAX 256                            // Maximum length of an HTTP AUTH header or equivalent cookie data
84 struct ctdlsession {
85         struct ctdlsession *next;
86         int is_bound;                           // Nonzero if this record is currently bound to a running thread
87         int sock;                               // Socket connection to Citadel server
88         char auth[AUTH_MAX];                    // Auth string (empty if not logged in)
89         char whoami[64];                        // Display name of currently logged in user (empty if not logged in)
90         char room[128];                         // What room we are currently in
91         int room_current_view;
92         int room_default_view;
93         int is_trash_folder;                    // nonzero if this room is the user's Trash folder
94         int is_room_aide;                       // nonzero if the user has aide rights to THIS room
95         int can_delete_messages;                // nonzero if the user is permitted to delete messages in THIS room
96         long last_seen;
97         int new_messages;
98         int total_messages;
99         time_t last_access;                     // Timestamp of last request that used this session
100         time_t num_requests_handled;
101         time_t room_mtime;                      // Timestampt of the most recent write activity in this room
102 };
103
104 struct uploaded_file {                          // things that have been uploaded to the server (such as email attachments)
105         char id[10];
106         char filename[256];
107         char content_type[256];
108         long length;
109         FILE *fp;
110 };
111
112 extern char *ssl_cipher_list;
113 extern int is_https;                            // nonzero if we are an HTTPS server today
114 extern char *ctdl_dir;                          // directory where Citadel Server is running
115 void init_ssl(void);
116 void starttls(struct client_handle *);
117 void endtls(struct client_handle *);
118 int client_write_ssl(struct client_handle *ch, char *buf, int nbytes);
119 int client_read_ssl(struct client_handle *ch, char *buf, int nbytes);
120
121 enum {
122         WEBSERVER_HTTP,
123         WEBSERVER_HTTPS,
124         WEBSERVER_UDS
125 };
126
127 #define TRACE syslog(LOG_DEBUG, "\033[3%dmCHECKPOINT: %s:%d\033[0m", ((__LINE__%6)+1), __FILE__, __LINE__)
128 #define SLEEPING                180             // TCP connection timeout
129 #define MAX_WORKER_THREADS      32              // Maximum number of worker threads permitted to exist
130 #define DEFAULT_SSL_CIPHER_LIST "DEFAULT"       // See http://openssl.org/docs/apps/ciphers.html
131 #define WEBSERVER_PORT          80
132 #define WEBSERVER_INTERFACE     "*"
133 #define CTDL_DIR                "/usr/local/citadel"
134 #define DEVELOPER_ID            0
135 #define CLIENT_ID               4
136 #define TARGET                  "webcit02"      // Window target for inline URL's
137 #define ROOMNAMELEN             128             // The size of a roomname string
138 #define DAV_MOVE                0               // MOVE=0 COPY=1 don't change these!
139 #define DAV_COPY                1               // they are the values used in the Citadel Server MOVE command
140
141
142 // Everything below here is generated with this command:
143 // cproto -f2 *.c 2>/dev/null |sed 's/^\/\*/\n\/\//g' | sed 's/\ \*\/$//g'
144
145 // admin_functions.c
146 void try_login(struct http_transaction *, struct ctdlsession *);
147 void logout(struct http_transaction *, struct ctdlsession *);
148 void whoami(struct http_transaction *, struct ctdlsession *);
149 void biff(struct http_transaction *, struct ctdlsession *);
150 void ctdl_a(struct http_transaction *, struct ctdlsession *);
151
152 // caldav_reports.c
153 void caldav_xml_start(void *, const char *, const char **);
154 void caldav_xml_end(void *, const char *);
155 void caldav_xml_chardata(void *, const XML_Char *, int);
156 StrBuf *fetch_ical(struct ctdlsession *, long);
157 void caldav_report_one_item(struct http_transaction *, struct ctdlsession *, StrBuf *, StrBuf *);
158 void caldav_report(struct http_transaction *, struct ctdlsession *);
159
160 // ctdlclient.c
161 int ctdl_read_binary(struct ctdlsession *, char *, int);
162 int ctdl_readline(struct ctdlsession *, char *, int);
163 StrBuf *ctdl_readtextmsg(struct ctdlsession *);
164 ssize_t ctdl_write(struct ctdlsession *, const void *, size_t);
165 void ctdl_printf(struct ctdlsession *, const char *, ...);
166 int uds_connectsock(char *);
167 void extract_auth(struct http_transaction *, char *, int);
168 int login_to_citadel(struct ctdlsession *, char *, char *);
169 struct ctdlsession *connect_to_citadel(struct http_transaction *);
170 void disconnect_from_citadel(struct ctdlsession *);
171
172 // ctdl_commands.c
173 void serv_info(struct http_transaction *, struct ctdlsession *);
174 void ctdl_c(struct http_transaction *, struct ctdlsession *);
175
176 // ctdlfunctions.c
177 void ctdl_delete_msgs(struct ctdlsession *, long *, int);
178
179 // floor_functions.c
180 void floor_list(struct http_transaction *, struct ctdlsession *);
181 void ctdl_f(struct http_transaction *, struct ctdlsession *);
182
183 // forum_view.c
184 void setup_for_forum_view(struct ctdlsession *);
185 JsonValue *json_tokenize_recipients(const char *, long, char *);
186 void json_render_one_message(struct http_transaction *, struct ctdlsession *, long);
187
188 // html2html.c
189 void stripquotes(char *);
190 void extract_charset_from_meta(char *, char *, char *);
191 StrBuf *html2html(const char *, int, char *, long, StrBuf *);
192 void UrlizeText(StrBuf *, StrBuf *, StrBuf *);
193 void url(char *, size_t);
194
195 // http.c
196 int client_write(struct client_handle *, char *, int);
197 int client_read(struct client_handle *, char *, int);
198 int client_readline(struct client_handle *, char *, int);
199 void client_printf(struct client_handle *, const char *, ...);
200 void add_response_header(struct http_transaction *, char *, char *);
201 void perform_one_http_transaction(struct client_handle *);
202 char *header_val(struct http_transaction *, char *);
203 char *get_url_param(struct http_transaction *, char *);
204
205 // main.c
206 int main(int, char **);
207
208 // messages.c
209 long locate_message_by_uid(struct ctdlsession *, char *);
210 void dav_delete_message(struct http_transaction *, struct ctdlsession *, long);
211 void dav_move_or_copy_message(struct http_transaction *, struct ctdlsession *, long, int);
212 void dav_get_message(struct http_transaction *, struct ctdlsession *, long);
213 void dav_put_message(struct http_transaction *, struct ctdlsession *, char *, long);
214 void download_mime_component(struct http_transaction *, struct ctdlsession *, long, char *);
215
216 // request.c
217 void do_404(struct http_transaction *);
218 void do_405(struct http_transaction *);
219 void do_412(struct http_transaction *);
220 void do_204(struct http_transaction *);
221 void do_502(struct http_transaction *);
222 void request_http_authenticate(struct http_transaction *);
223 void http_redirect(struct http_transaction *, char *);
224 void perform_request(struct http_transaction *);
225
226 // room_functions.c
227 Array *get_msglist(struct ctdlsession *, char *);
228 int match_etags(char *, long);
229 void json_stat(struct http_transaction *, struct ctdlsession *);
230 void json_mailbox(struct http_transaction *, struct ctdlsession *);
231 void json_msglist(struct http_transaction *, struct ctdlsession *, char *);
232 void read_room_info_banner(struct http_transaction *, struct ctdlsession *);
233 void set_last_read_pointer(struct http_transaction *, struct ctdlsession *);
234 void object_in_room(struct http_transaction *, struct ctdlsession *);
235 void report_the_room_itself(struct http_transaction *, struct ctdlsession *);
236 void options_the_room_itself(struct http_transaction *, struct ctdlsession *);
237 void propfind_the_room_itself(struct http_transaction *, struct ctdlsession *);
238 void get_the_room_itself(struct http_transaction *, struct ctdlsession *);
239 void the_room_itself(struct http_transaction *, struct ctdlsession *);
240 void room_list(struct http_transaction *, struct ctdlsession *);
241 void ctdl_r(struct http_transaction *, struct ctdlsession *);
242
243 // static.c
244 void output_static(struct http_transaction *);
245
246 // tcp_sockets.c
247 int lingering_close(int);
248 int webcit_tcp_server(const char *, int, int);
249 int webcit_uds_server(char *, int);
250
251 // text2html.c
252 StrBuf *text2html(const char *, int, char *, long, StrBuf *);
253 StrBuf *variformat2html(StrBuf *);
254
255 // tls.c
256 void bind_to_key_and_certificate(void);
257 void init_ssl(void);
258 void update_key_and_cert_if_needed(void);
259 void starttls(struct client_handle *);
260 void endtls(struct client_handle *);
261 int client_write_ssl(struct client_handle *, char *, int);
262 int client_read_ssl(struct client_handle *, char *, int);
263
264 // upload.c
265 void upload_handler(char *, char *, char *, char *, void *, char *, char *, size_t, char *, char *, void *);
266 void upload_files(struct http_transaction *, struct ctdlsession *);
267 void ctdl_p_base(struct http_transaction *, struct ctdlsession *);
268 void delete_upload(struct uploaded_file);
269 void dav_delete_upload(struct http_transaction *, struct ctdlsession *, struct uploaded_file);
270 struct uploaded_file pop_upload(char *);
271 void attachment_filter(char *, char *, char *, char *, void *, char *, char *, size_t, char *, char *, void *);
272 void load_attachments_from_message(struct http_transaction *, struct ctdlsession *, char *);
273 void specific_upload(struct http_transaction *, struct ctdlsession *, char *);
274 void ctdl_p(struct http_transaction *, struct ctdlsession *);
275
276 // user_functions.c
277 void fetch_user_photo(struct http_transaction *, struct ctdlsession *, char *);
278 void fetch_user_bio(struct http_transaction *, struct ctdlsession *, char *);
279 void object_in_user(struct http_transaction *, struct ctdlsession *, char *);
280 void the_user_itself(struct http_transaction *, struct ctdlsession *, char *);
281 void user_list(struct http_transaction *, struct ctdlsession *);
282 void ctdl_u(struct http_transaction *, struct ctdlsession *);
283
284 // util.c
285 int unescape_input(char *);
286 char *http_datestring(time_t);
287
288 // webserver.c
289 void spawn_another_worker_thread(int *);
290 void worker_entry(int *);
291 int webserver(char *, int, int);