2 f224a3fe 2021-08-24 xhr * Copyright (c) 2021 Matthias Schmidt <xhr@giessen.ccc.de>
4 f224a3fe 2021-08-24 xhr * Permission to use, copy, modify, and distribute this software for any
5 f224a3fe 2021-08-24 xhr * purpose with or without fee is hereby granted, provided that the above
6 f224a3fe 2021-08-24 xhr * copyright notice and this permission notice appear in all copies.
8 f224a3fe 2021-08-24 xhr * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 f224a3fe 2021-08-24 xhr * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 f224a3fe 2021-08-24 xhr * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 f224a3fe 2021-08-24 xhr * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 f224a3fe 2021-08-24 xhr * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 f224a3fe 2021-08-24 xhr * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 f224a3fe 2021-08-24 xhr * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 f224a3fe 2021-08-24 xhr #include <sys/socket.h>
18 f224a3fe 2021-08-24 xhr #include <sys/stat.h>
20 f224a3fe 2021-08-24 xhr #include <err.h>
21 f224a3fe 2021-08-24 xhr #include <errno.h>
22 f224a3fe 2021-08-24 xhr #include <fcntl.h>
23 f224a3fe 2021-08-24 xhr #include <stdio.h>
24 f224a3fe 2021-08-24 xhr #include <string.h>
25 f224a3fe 2021-08-24 xhr #include <unistd.h>
27 f224a3fe 2021-08-24 xhr #include "log.h"
28 f224a3fe 2021-08-24 xhr #include "twind.h"
31 f224a3fe 2021-08-24 xhr generate_meta(int status_code, char *meta_response_string, const char *mime)
33 f224a3fe 2021-08-24 xhr switch(status_code) {
34 f224a3fe 2021-08-24 xhr case STATUS_INPUT:
35 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Present input\r\n", status_code);
37 f224a3fe 2021-08-24 xhr case STATUS_SENSITIVE_INPUT:
38 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Present sensitive input\r\n",
39 f224a3fe 2021-08-24 xhr status_code);
41 f224a3fe 2021-08-24 xhr case STATUS_SUCCESS:
42 f224a3fe 2021-08-24 xhr if (mime == NULL)
43 f224a3fe 2021-08-24 xhr /* Could not deducte mime type, so send text/gemini as default */
44 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d text/gemini\r\n", status_code);
46 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d %s\r\n", status_code, mime);
48 f224a3fe 2021-08-24 xhr case STATUS_REDIRECT_TEMP:
49 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Temporary redirect\r\n",
50 f224a3fe 2021-08-24 xhr status_code);
52 f224a3fe 2021-08-24 xhr case STATUS_REDIRECT_PERM:
53 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Permanent redirect\r\n",
54 f224a3fe 2021-08-24 xhr status_code);
56 f224a3fe 2021-08-24 xhr case STATUS_TEMP_UNAVAILABLE:
57 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Temporary failure\r\n",
58 f224a3fe 2021-08-24 xhr status_code);
60 f224a3fe 2021-08-24 xhr case STATUS_SERVER_UNAVAILABLE:
61 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Server unavailable\r\n",
62 f224a3fe 2021-08-24 xhr status_code);
64 f224a3fe 2021-08-24 xhr case STATUS_CGI_ERROR:
65 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d CGI Error\r\n", status_code);
67 f224a3fe 2021-08-24 xhr case STATUS_PROXY_ERROR:
68 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Proxy error\r\n", status_code);
70 f224a3fe 2021-08-24 xhr case STATUS_SLOW_DOWN:
71 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Slow down\r\n", status_code);
73 f224a3fe 2021-08-24 xhr case STATUS_PERM_FAILURE:
74 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Permanent failure\r\n", status_code);
76 f224a3fe 2021-08-24 xhr case STATUS_NOT_FOUND:
77 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Resource not found\r\n",
78 f224a3fe 2021-08-24 xhr status_code);
80 f224a3fe 2021-08-24 xhr case STATUS_GONE:
81 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Resource is gone\r\n", status_code);
83 f224a3fe 2021-08-24 xhr case STATUS_PROXY_REQUEST_REFUSED:
84 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Proxy request refused\r\n",
85 f224a3fe 2021-08-24 xhr status_code);
87 f224a3fe 2021-08-24 xhr case STATUS_BAD_REQUEST:
88 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Bad Request\r\n", status_code);
90 f224a3fe 2021-08-24 xhr case STATUS_CLIENT_CERT_REQUIRED:
91 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Client Certificate Required\r\n",
92 f224a3fe 2021-08-24 xhr status_code);
94 f224a3fe 2021-08-24 xhr case STATUS_CERT_NOT_AUTHORIZED:
95 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Certificate not authorized\r\n",
96 f224a3fe 2021-08-24 xhr status_code);
98 f224a3fe 2021-08-24 xhr case STATUS_CERT_NOT_VALID:
99 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Certificate not valid\r\n",
100 f224a3fe 2021-08-24 xhr status_code);
103 f224a3fe 2021-08-24 xhr snprintf(meta_response_string, 1024, "%d Unkown status code\r\n",
104 f224a3fe 2021-08-24 xhr status_code);
110 f224a3fe 2021-08-24 xhr send_non_success_response(SSL *ssl_peer, int status_code)
112 f224a3fe 2021-08-24 xhr char meta[1024];
114 f224a3fe 2021-08-24 xhr memset(meta, 0, sizeof(meta));
116 f224a3fe 2021-08-24 xhr generate_meta(status_code, meta, NULL);
118 f224a3fe 2021-08-24 xhr log_debug("Send non success response to client: %d", status_code);
120 f224a3fe 2021-08-24 xhr if (SSL_write(ssl_peer, meta, strlen(meta)) <= 0) {
121 f224a3fe 2021-08-24 xhr log_warn("Could not send response to client");
129 f224a3fe 2021-08-24 xhr send_response(SSL *ssl_peer, int status_code, const char *gemini_file_path,
130 f224a3fe 2021-08-24 xhr const char *mime)
132 f224a3fe 2021-08-24 xhr char meta[1024];
133 f224a3fe 2021-08-24 xhr char buffer[1024];
134 f224a3fe 2021-08-24 xhr int fd = -1, len;
136 f224a3fe 2021-08-24 xhr // <STATUS><SPACE><META><CR><LF>
138 f224a3fe 2021-08-24 xhr memset(meta, 0, sizeof(meta));
139 f224a3fe 2021-08-24 xhr memset(buffer, 0, sizeof(buffer));
141 f224a3fe 2021-08-24 xhr generate_meta(status_code, meta, mime);
143 f224a3fe 2021-08-24 xhr if (SSL_write(ssl_peer, meta, strlen(meta)) <= 0) {
144 f224a3fe 2021-08-24 xhr log_warn("Could not send response to client");
148 f224a3fe 2021-08-24 xhr /* Close connection and do not send a response if status code is not
149 f224a3fe 2021-08-24 xhr * a SUCCESS code
151 f224a3fe 2021-08-24 xhr if (status_code < 30 && status_code >= 20) {
152 f224a3fe 2021-08-24 xhr fd = open(gemini_file_path, O_RDONLY);
153 f224a3fe 2021-08-24 xhr if (fd == -1) {
154 f224a3fe 2021-08-24 xhr log_warn("Cannot open requested file");
158 f224a3fe 2021-08-24 xhr while ((len = read(fd, buffer, sizeof(buffer)-1)) > 0) {
159 f224a3fe 2021-08-24 xhr if (SSL_write(ssl_peer, buffer, len) <= 0) {
160 f224a3fe 2021-08-24 xhr log_warn("Could not send response to client");
173 f224a3fe 2021-08-24 xhr check_gemini_file(const char *gemini_file_path)
175 f224a3fe 2021-08-24 xhr struct stat sb;
177 f224a3fe 2021-08-24 xhr if (stat(gemini_file_path, &sb) == -1) {
178 f224a3fe 2021-08-24 xhr log_warn("Cannot open requested file");
182 f224a3fe 2021-08-24 xhr if ((sb.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) == 0) {
183 f224a3fe 2021-08-24 xhr log_warn("Cannot read requested file");
187 f224a3fe 2021-08-24 xhr if ((sb.st_mode & S_IFMT) == S_IFDIR)