From 1c103e09528785fa47299d63a14e48cfa6490025 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Mon, 19 Aug 2013 19:59:54 +0200 Subject: [PATCH] Use getopt(), restrict upload access --- include/templates.h | 2 + src/main.c | 100 ++++++++++++++++++++++++++++++++------------ 2 files changed, 76 insertions(+), 26 deletions(-) diff --git a/include/templates.h b/include/templates.h index ec3782f..1971f15 100644 --- a/include/templates.h +++ b/include/templates.h @@ -25,6 +25,7 @@ " " #define FOOTER \ + "

Generated by fileshare " VERSION ".

" \ " " \ "" @@ -84,6 +85,7 @@ "
  • You are trying to access a file that the server isn't allowed to read
  • " \ "
  • The target filesystem entry is not a regular file or directory
  • " \ "
  • The URL contains \"/..\", which is blocked for security reasons
  • " \ + "
  • You are trying to upload a file, and uploads are not enabled for this server
  • " \ " " \ FOOTER diff --git a/src/main.c b/src/main.c index cb2172b..670b9b8 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -55,7 +56,7 @@ magic_t magicCookie; #endif int running = 1; -int uploadEnabled = 1; +int uploadEnabled = 0; void request_completed(void *cls, struct MHD_Connection * connection, @@ -398,8 +399,15 @@ static int connection_handler(void * cls, connstate->postProcessor = NULL; connstate->requestType = GET; } else if(0 == strcmp(method, "POST")) { - connstate->postProcessor = MHD_create_post_processor(connection, 1024*1024, post_processor, connstate); - connstate->requestType = POST; + if(!uploadEnabled) { + LOG(LVL_WARN, + "Uploads are disabled, so POST requests are denied.", + connstate->localFileName); + return MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, error403Response); + } else { + connstate->postProcessor = MHD_create_post_processor(connection, 1024*1024, post_processor, connstate); + connstate->requestType = POST; + } } else { LOG(LVL_WARN, "Unexpected method: %s.", method); return MHD_NO; @@ -442,7 +450,7 @@ static int connection_handler(void * cls, if(S_ISREG(connstate->targetStat.st_mode)) { return serv_regular_file(connection, connstate); } else if(S_ISDIR(connstate->targetStat.st_mode)) { - if(connstate->uploadRequest) { + if(uploadEnabled && connstate->uploadRequest) { return MHD_queue_response(connection, MHD_HTTP_OK, uploadFormResponse); } else { return serv_directory(connection, connstate); @@ -541,6 +549,53 @@ void print_urls(int port) { freeifaddrs(ifaddr); } +int parse_cmdline(int argc, char **argv, int *port, int *enableUpload, char **shareRoot) { + int c; + + *enableUpload = 0; + *port = DEFAULT_PORT; + + while ((c = getopt (argc, argv, "up:")) != -1) { + switch (c) { + case 'u': + *enableUpload = 1; + break; + case 'p': + // a port was given on the command line, try to parse it + if(sscanf(optarg, "%i", port) != 1) { + LOG(LVL_FATAL, "%s is not a valid port number!", optarg); + return 1; + } + + if(*port < 1 || *port > 65535) { + LOG(LVL_FATAL, "Port %i is out of range [1-65535]!", *port); + return 1; + } + break; + case '?': + if (optopt == 'p') { + LOG(LVL_ERR, "Option -%c requires an argument.\n", optopt); + } else if (isprint (optopt)) { + LOG(LVL_ERR, "Unknown option `-%c'.\n", optopt); + } else { + LOG(LVL_ERR, "Unknown option character `\\x%x'.\n", optopt); + } + return 1; + + default: + return 1; + } + } + + if(optind < argc) { + // found non-option argument -> use as shared dir + *shareRoot = argv[optind]; + return 0; + } + + return 1; +} + int main(int argc, char ** argv) { struct MHD_Daemon *d, *d6; struct stat sBuf; @@ -556,14 +611,24 @@ int main(int argc, char ** argv) { logger_set_verbosity(LVL_INFO); #endif - if (argc < 2) { - LOG(LVL_ERR, "Too few arguments!"); - LOG(LVL_INFO, "Usage: %s []", argv[0]); + // parse command line arguments + if(parse_cmdline(argc, argv, &port, &uploadEnabled, &shareRoot)) { + LOG(LVL_ERR, "Failed to parse command line!"); + LOG(LVL_INFO, "Usage: %s [arguments] ", argv[0]); + LOG(LVL_INFO, ""); + LOG(LVL_INFO, "Arguments:"); + LOG(LVL_INFO, ""); + LOG(LVL_INFO, "\t-u Enable Uploads"); + LOG(LVL_INFO, "\t-p port Change the listening port."); + LOG(LVL_INFO, ""); return 1; } + if(uploadEnabled) { + LOG(LVL_WARN, "Uploads are enabled. Users can create new files anywhere in %s !", shareRoot); + } + // check if shareRoot is an existing directory - shareRoot = argv[1]; if(stat(shareRoot, &sBuf) == -1) { LOG(LVL_FATAL, "Cannot stat %s: %s", shareRoot, strerror(errno)); return EXIT_FAILURE; @@ -578,24 +643,7 @@ int main(int argc, char ** argv) { remove_trailing_slash(shareRoot); LOG(LVL_INFO, "Shared directory is: %s", shareRoot); - - if(argc >= 3) { - // a port was given on the command line, try to parse it - if(sscanf(argv[2], "%i", &port) != 1) { - LOG(LVL_FATAL, "%s is not a valid port number!", argv[2]); - return EXIT_FAILURE; - } - - if(port < 1 || port > 65535) { - LOG(LVL_FATAL, "Port %i is out of range [1-65535]!", port); - return EXIT_FAILURE; - } - - LOG(LVL_INFO, "Using port: %i", port); - } else { - LOG(LVL_INFO, "Using default port: %i", DEFAULT_PORT); - port = DEFAULT_PORT; - } + LOG(LVL_INFO, "Using port: %i", port); #ifdef HAVE_MAGIC // initialize libmagic