From 555f21649b909fd37a6153843249d72ca80ac427 Mon Sep 17 00:00:00 2001 From: cflip Date: Fri, 14 Jul 2023 19:16:02 -0600 Subject: Run executable files as CGI scripts Now if the server encounters an executable file that doesn't have a .php extension, it will run it as a CGI script. There should maybe be better heuristics for determining whether a file actually is a CGI script (sometimes files copied from Windows can be marked as executable) but this works for now. --- cfws.c | 7 ++++++- file.c | 11 +++++++++-- file.h | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/cfws.c b/cfws.c index 930264a..04ec3c3 100644 --- a/cfws.c +++ b/cfws.c @@ -126,7 +126,12 @@ static void handle_request(const struct http_request *req, int sockfd) case SERVE_METHOD_PHP: if (flag_verbose) printf(" -> PHP %s\n", filepath); - file_read_php(filepath, req, sockfd); + file_read_cgi(filepath, "/usr/bin/php-cgi", req, sockfd); + break; + case SERVE_METHOD_CGI: + if (flag_verbose) + printf(" -> CGI %s\n", filepath); + file_read_cgi(filepath, filepath, req, sockfd); break; case SERVE_METHOD_ERROR: { if (flag_verbose) diff --git a/file.c b/file.c index b64480c..4e42c58 100644 --- a/file.c +++ b/file.c @@ -48,6 +48,8 @@ const char *file_path_for_uri(const char *uri) enum serve_method file_method_for_path(const char *filepath, enum http_res_code *code) { + struct stat statbuf; + if (access(filepath, F_OK) != 0) { *code = HTTP_RESPONSE_NOTFOUND; return SERVE_METHOD_ERROR; @@ -57,6 +59,11 @@ enum serve_method file_method_for_path(const char *filepath, enum http_res_code if (strstr(filepath, ".php") != 0) return SERVE_METHOD_PHP; + stat(filepath, &statbuf); + if (statbuf.st_mode & S_IXUSR) { + return SERVE_METHOD_CGI; + } + return SERVE_METHOD_FILE; } @@ -128,7 +135,7 @@ static void cgi_setup_env(const char *filepath, const struct http_request *req) } } -int file_read_php(const char *filepath, const struct http_request *req, int sockfd) +int file_read_cgi(const char *filepath, const char *program, const struct http_request *req, int sockfd) { int readfds[2]; int writefds[2]; @@ -171,7 +178,7 @@ int file_read_php(const char *filepath, const struct http_request *req, int sock } } - execl("/usr/bin/php-cgi", "php-cgi", NULL); + execl(program, program, NULL); /* We should only end up here if there's an error. */ perror("exec"); exit(1); diff --git a/file.h b/file.h index 9c48425..ce76a7f 100644 --- a/file.h +++ b/file.h @@ -8,6 +8,7 @@ enum serve_method { SERVE_METHOD_FILE, SERVE_METHOD_PHP, + SERVE_METHOD_CGI, SERVE_METHOD_ERROR }; @@ -16,6 +17,6 @@ const char *file_path_for_uri(const char *); enum serve_method file_method_for_path(const char *, enum http_res_code *); int file_read(const char *, int); -int file_read_php(const char *, const struct http_request *, int); +int file_read_cgi(const char *, const char *, const struct http_request *, int); #endif -- cgit v1.2.3