Blame


1 aac8053c 2021-08-12 xhr /*
2 aac8053c 2021-08-12 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
3 aac8053c 2021-08-12 xhr *
4 aac8053c 2021-08-12 xhr * Permission to use, copy, modify, and distribute this software for any
5 aac8053c 2021-08-12 xhr * purpose with or without fee is hereby granted, provided that the above
6 aac8053c 2021-08-12 xhr * copyright notice and this permission notice appear in all copies.
7 aac8053c 2021-08-12 xhr *
8 aac8053c 2021-08-12 xhr * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 aac8053c 2021-08-12 xhr * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 aac8053c 2021-08-12 xhr * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 aac8053c 2021-08-12 xhr * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 aac8053c 2021-08-12 xhr * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 aac8053c 2021-08-12 xhr * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 aac8053c 2021-08-12 xhr * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 aac8053c 2021-08-12 xhr */
16 aac8053c 2021-08-12 xhr
17 0f9df5ff 2021-08-06 xhr #include <sys/socket.h>
18 edc334c2 2021-08-05 xhr #include <sys/stat.h>
19 edc334c2 2021-08-05 xhr
20 edc334c2 2021-08-05 xhr #include <err.h>
21 edc334c2 2021-08-05 xhr #include <errno.h>
22 edc334c2 2021-08-05 xhr #include <fcntl.h>
23 edc334c2 2021-08-05 xhr #include <stdio.h>
24 edc334c2 2021-08-05 xhr #include <string.h>
25 edc334c2 2021-08-05 xhr #include <unistd.h>
26 edc334c2 2021-08-05 xhr
27 0f9df5ff 2021-08-06 xhr #include "log.h"
28 0f9df5ff 2021-08-06 xhr #include "twind.h"
29 edc334c2 2021-08-05 xhr
30 edc334c2 2021-08-05 xhr static void
31 8c443bed 2021-08-10 xhr generate_meta(int status_code, char *meta_response_string, const char *mime)
32 edc334c2 2021-08-05 xhr {
33 edc334c2 2021-08-05 xhr switch(status_code) {
34 0f9df5ff 2021-08-06 xhr case STATUS_INPUT:
35 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Present input\r\n", status_code);
36 edc334c2 2021-08-05 xhr break;
37 edc334c2 2021-08-05 xhr case STATUS_SENSITIVE_INPUT:
38 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Present sensitive input\r\n",
39 0f5f93fa 2021-08-12 xhr status_code);
40 edc334c2 2021-08-05 xhr break;
41 edc334c2 2021-08-05 xhr case STATUS_SUCCESS:
42 774afac7 2021-08-15 xhr if (mime == NULL)
43 774afac7 2021-08-15 xhr /* Could not deducte mime type, so send text/gemini as default */
44 774afac7 2021-08-15 xhr snprintf(meta_response_string, 1024, "%d text/gemini\r\n", status_code);
45 774afac7 2021-08-15 xhr else
46 774afac7 2021-08-15 xhr snprintf(meta_response_string, 1024, "%d %s\r\n", status_code, mime);
47 edc334c2 2021-08-05 xhr break;
48 edc334c2 2021-08-05 xhr case STATUS_REDIRECT_TEMP:
49 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Temporary redirect\r\n",
50 0f5f93fa 2021-08-12 xhr status_code);
51 edc334c2 2021-08-05 xhr break;
52 edc334c2 2021-08-05 xhr case STATUS_REDIRECT_PERM:
53 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Permanent redirect\r\n",
54 0f5f93fa 2021-08-12 xhr status_code);
55 edc334c2 2021-08-05 xhr break;
56 edc334c2 2021-08-05 xhr case STATUS_TEMP_UNAVAILABLE:
57 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Temporary failure\r\n",
58 0f5f93fa 2021-08-12 xhr status_code);
59 edc334c2 2021-08-05 xhr break;
60 edc334c2 2021-08-05 xhr case STATUS_SERVER_UNAVAILABLE:
61 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Server unavailable\r\n",
62 0f5f93fa 2021-08-12 xhr status_code);
63 edc334c2 2021-08-05 xhr break;
64 edc334c2 2021-08-05 xhr case STATUS_CGI_ERROR:
65 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d CGI Error\r\n", status_code);
66 edc334c2 2021-08-05 xhr break;
67 edc334c2 2021-08-05 xhr case STATUS_PROXY_ERROR:
68 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Proxy error\r\n", status_code);
69 edc334c2 2021-08-05 xhr break;
70 edc334c2 2021-08-05 xhr case STATUS_SLOW_DOWN:
71 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Slow down\r\n", status_code);
72 edc334c2 2021-08-05 xhr break;
73 edc334c2 2021-08-05 xhr case STATUS_PERM_FAILURE:
74 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Permanent failure\r\n", status_code);
75 edc334c2 2021-08-05 xhr break;
76 edc334c2 2021-08-05 xhr case STATUS_NOT_FOUND:
77 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Resource not found\r\n",
78 0f5f93fa 2021-08-12 xhr status_code);
79 edc334c2 2021-08-05 xhr break;
80 edc334c2 2021-08-05 xhr case STATUS_GONE:
81 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Resource is gone\r\n", status_code);
82 edc334c2 2021-08-05 xhr break;
83 edc334c2 2021-08-05 xhr case STATUS_PROXY_REQUEST_REFUSED:
84 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Proxy request refused\r\n",
85 0f5f93fa 2021-08-12 xhr status_code);
86 edc334c2 2021-08-05 xhr break;
87 edc334c2 2021-08-05 xhr case STATUS_BAD_REQUEST:
88 0f9df5ff 2021-08-06 xhr snprintf(meta_response_string, 1024, "%d Bad Request\r\n", status_code);
89 edc334c2 2021-08-05 xhr break;
90 edc334c2 2021-08-05 xhr case STATUS_CLIENT_CERT_REQUIRED:
91 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Client Certificate Required\r\n",
92 0f5f93fa 2021-08-12 xhr status_code);
93 edc334c2 2021-08-05 xhr break;
94 edc334c2 2021-08-05 xhr case STATUS_CERT_NOT_AUTHORIZED:
95 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Certificate not authorized\r\n",
96 0f5f93fa 2021-08-12 xhr status_code);
97 edc334c2 2021-08-05 xhr break;
98 edc334c2 2021-08-05 xhr case STATUS_CERT_NOT_VALID:
99 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Certificate not valid\r\n",
100 0f5f93fa 2021-08-12 xhr status_code);
101 edc334c2 2021-08-05 xhr break;
102 0f5f93fa 2021-08-12 xhr default:
103 0f5f93fa 2021-08-12 xhr snprintf(meta_response_string, 1024, "%d Unkown status code\r\n",
104 0f5f93fa 2021-08-12 xhr status_code);
105 edc334c2 2021-08-05 xhr break;
106 edc334c2 2021-08-05 xhr }
107 edc334c2 2021-08-05 xhr }
108 edc334c2 2021-08-05 xhr
109 edc334c2 2021-08-05 xhr int
110 ab99638a 2021-08-08 xhr send_non_success_response(SSL *ssl_peer, int status_code)
111 0f9df5ff 2021-08-06 xhr {
112 0f9df5ff 2021-08-06 xhr char meta[1024];
113 0f9df5ff 2021-08-06 xhr
114 0f9df5ff 2021-08-06 xhr memset(meta, 0, sizeof(meta));
115 0f9df5ff 2021-08-06 xhr
116 8c443bed 2021-08-10 xhr generate_meta(status_code, meta, NULL);
117 0f9df5ff 2021-08-06 xhr
118 0f9df5ff 2021-08-06 xhr log_debug("Send non success response to client: %s", meta);
119 0f9df5ff 2021-08-06 xhr
120 84033a53 2021-08-08 xhr if (SSL_write(ssl_peer, meta, strlen(meta)) <= 0) {
121 84033a53 2021-08-08 xhr log_warn("Could not send response to client");
122 0f9df5ff 2021-08-06 xhr return -1;
123 0f9df5ff 2021-08-06 xhr }
124 0f9df5ff 2021-08-06 xhr
125 0f9df5ff 2021-08-06 xhr return 0;
126 0f9df5ff 2021-08-06 xhr }
127 0f9df5ff 2021-08-06 xhr
128 0f9df5ff 2021-08-06 xhr int
129 0f5f93fa 2021-08-12 xhr send_response(SSL *ssl_peer, int status_code, const char *gemini_file_path,
130 0f5f93fa 2021-08-12 xhr const char *mime)
131 edc334c2 2021-08-05 xhr {
132 edc334c2 2021-08-05 xhr char meta[1024];
133 edc334c2 2021-08-05 xhr char buffer[1024];
134 78e56b5d 2021-08-12 xhr int fd = -1, len;
135 edc334c2 2021-08-05 xhr
136 edc334c2 2021-08-05 xhr // <STATUS><SPACE><META><CR><LF>
137 edc334c2 2021-08-05 xhr
138 edc334c2 2021-08-05 xhr memset(meta, 0, sizeof(meta));
139 edc334c2 2021-08-05 xhr memset(buffer, 0, sizeof(buffer));
140 edc334c2 2021-08-05 xhr
141 8c443bed 2021-08-10 xhr generate_meta(status_code, meta, mime);
142 edc334c2 2021-08-05 xhr
143 84033a53 2021-08-08 xhr if (SSL_write(ssl_peer, meta, strlen(meta)) <= 0) {
144 84033a53 2021-08-08 xhr log_warn("Could not send response to client");
145 bf09eac4 2021-08-06 xhr return -1;
146 bf09eac4 2021-08-06 xhr }
147 edc334c2 2021-08-05 xhr
148 edc334c2 2021-08-05 xhr /* Close connection and do not send a response if status code is not
149 edc334c2 2021-08-05 xhr * a SUCCESS code
150 edc334c2 2021-08-05 xhr */
151 edc334c2 2021-08-05 xhr if (status_code < 30 && status_code >= 20) {
152 edc334c2 2021-08-05 xhr fd = open(gemini_file_path, O_RDONLY);
153 edc334c2 2021-08-05 xhr if (fd == -1) {
154 d034a409 2021-08-13 xhr log_warn("Cannot open requested file");
155 edc334c2 2021-08-05 xhr goto out;
156 edc334c2 2021-08-05 xhr }
157 edc334c2 2021-08-05 xhr
158 edc334c2 2021-08-05 xhr while ((len = read(fd, buffer, sizeof(buffer)-1)) > 0) {
159 b8ccf1a1 2021-08-08 xhr if (SSL_write(ssl_peer, buffer, len) <= 0) {
160 84033a53 2021-08-08 xhr log_warn("Could not send response to client");
161 bf09eac4 2021-08-06 xhr return -1;
162 bf09eac4 2021-08-06 xhr }
163 edc334c2 2021-08-05 xhr }
164 edc334c2 2021-08-05 xhr }
165 edc334c2 2021-08-05 xhr
166 edc334c2 2021-08-05 xhr out:
167 4b19570b 2021-08-12 xhr close(fd);
168 edc334c2 2021-08-05 xhr
169 edc334c2 2021-08-05 xhr return 0;
170 edc334c2 2021-08-05 xhr }
171 edc334c2 2021-08-05 xhr
172 7a5ce97f 2021-08-06 xhr int
173 edc334c2 2021-08-05 xhr check_gemini_file(const char *gemini_file_path)
174 edc334c2 2021-08-05 xhr {
175 edc334c2 2021-08-05 xhr struct stat sb;
176 edc334c2 2021-08-05 xhr
177 edc334c2 2021-08-05 xhr if (stat(gemini_file_path, &sb) == -1) {
178 d034a409 2021-08-13 xhr log_warn("Cannot open requested file");
179 edc334c2 2021-08-05 xhr return -1;
180 edc334c2 2021-08-05 xhr }
181 edc334c2 2021-08-05 xhr
182 edc334c2 2021-08-05 xhr if ((sb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) == 0) {
183 d034a409 2021-08-13 xhr log_warn("Cannot read requested file");
184 edc334c2 2021-08-05 xhr return -1;
185 edc334c2 2021-08-05 xhr }
186 edc334c2 2021-08-05 xhr
187 5bbe30c9 2021-08-11 xhr if ((sb.st_mode & S_IFMT) == S_IFDIR)
188 5bbe30c9 2021-08-11 xhr return 1;
189 5bbe30c9 2021-08-11 xhr
190 edc334c2 2021-08-05 xhr return 0;
191 edc334c2 2021-08-05 xhr }