Use getopt(), restrict upload access
This commit is contained in:
parent
6dfd30e508
commit
1c103e0952
|
@ -25,6 +25,7 @@
|
|||
" <body>"
|
||||
|
||||
#define FOOTER \
|
||||
" <p><small>Generated by fileshare " VERSION ".</small></p>" \
|
||||
" </body>" \
|
||||
"</html>"
|
||||
|
||||
|
@ -84,6 +85,7 @@
|
|||
" <li>You are trying to access a file that the server isn't allowed to read</li>" \
|
||||
" <li>The target filesystem entry is not a regular file or directory</li>" \
|
||||
" <li>The URL contains \"/..\", which is blocked for security reasons</li>" \
|
||||
" <li>You are trying to upload a file, and uploads are not enabled for this server</li>" \
|
||||
" </ul>" \
|
||||
FOOTER
|
||||
|
||||
|
|
100
src/main.c
100
src/main.c
|
@ -11,6 +11,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
@ -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 <dir> [<port>]", 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] <dir>", 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
|
||||
|
|
Loading…
Reference in a new issue