Use getopt(), restrict upload access
This commit is contained in:
parent
6dfd30e508
commit
1c103e0952
|
@ -25,6 +25,7 @@
|
||||||
" <body>"
|
" <body>"
|
||||||
|
|
||||||
#define FOOTER \
|
#define FOOTER \
|
||||||
|
" <p><small>Generated by fileshare " VERSION ".</small></p>" \
|
||||||
" </body>" \
|
" </body>" \
|
||||||
"</html>"
|
"</html>"
|
||||||
|
|
||||||
|
@ -84,6 +85,7 @@
|
||||||
" <li>You are trying to access a file that the server isn't allowed to read</li>" \
|
" <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 target filesystem entry is not a regular file or directory</li>" \
|
||||||
" <li>The URL contains \"/..\", which is blocked for security reasons</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>" \
|
" </ul>" \
|
||||||
FOOTER
|
FOOTER
|
||||||
|
|
||||||
|
|
94
src/main.c
94
src/main.c
|
@ -11,6 +11,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ magic_t magicCookie;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int running = 1;
|
int running = 1;
|
||||||
int uploadEnabled = 1;
|
int uploadEnabled = 0;
|
||||||
|
|
||||||
void request_completed(void *cls,
|
void request_completed(void *cls,
|
||||||
struct MHD_Connection * connection,
|
struct MHD_Connection * connection,
|
||||||
|
@ -398,8 +399,15 @@ static int connection_handler(void * cls,
|
||||||
connstate->postProcessor = NULL;
|
connstate->postProcessor = NULL;
|
||||||
connstate->requestType = GET;
|
connstate->requestType = GET;
|
||||||
} else if(0 == strcmp(method, "POST")) {
|
} else if(0 == strcmp(method, "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->postProcessor = MHD_create_post_processor(connection, 1024*1024, post_processor, connstate);
|
||||||
connstate->requestType = POST;
|
connstate->requestType = POST;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(LVL_WARN, "Unexpected method: %s.", method);
|
LOG(LVL_WARN, "Unexpected method: %s.", method);
|
||||||
return MHD_NO;
|
return MHD_NO;
|
||||||
|
@ -442,7 +450,7 @@ static int connection_handler(void * cls,
|
||||||
if(S_ISREG(connstate->targetStat.st_mode)) {
|
if(S_ISREG(connstate->targetStat.st_mode)) {
|
||||||
return serv_regular_file(connection, connstate);
|
return serv_regular_file(connection, connstate);
|
||||||
} else if(S_ISDIR(connstate->targetStat.st_mode)) {
|
} else if(S_ISDIR(connstate->targetStat.st_mode)) {
|
||||||
if(connstate->uploadRequest) {
|
if(uploadEnabled && connstate->uploadRequest) {
|
||||||
return MHD_queue_response(connection, MHD_HTTP_OK, uploadFormResponse);
|
return MHD_queue_response(connection, MHD_HTTP_OK, uploadFormResponse);
|
||||||
} else {
|
} else {
|
||||||
return serv_directory(connection, connstate);
|
return serv_directory(connection, connstate);
|
||||||
|
@ -541,6 +549,53 @@ void print_urls(int port) {
|
||||||
freeifaddrs(ifaddr);
|
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) {
|
int main(int argc, char ** argv) {
|
||||||
struct MHD_Daemon *d, *d6;
|
struct MHD_Daemon *d, *d6;
|
||||||
struct stat sBuf;
|
struct stat sBuf;
|
||||||
|
@ -556,14 +611,24 @@ int main(int argc, char ** argv) {
|
||||||
logger_set_verbosity(LVL_INFO);
|
logger_set_verbosity(LVL_INFO);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc < 2) {
|
// parse command line arguments
|
||||||
LOG(LVL_ERR, "Too few arguments!");
|
if(parse_cmdline(argc, argv, &port, &uploadEnabled, &shareRoot)) {
|
||||||
LOG(LVL_INFO, "Usage: %s <dir> [<port>]", argv[0]);
|
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;
|
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
|
// check if shareRoot is an existing directory
|
||||||
shareRoot = argv[1];
|
|
||||||
if(stat(shareRoot, &sBuf) == -1) {
|
if(stat(shareRoot, &sBuf) == -1) {
|
||||||
LOG(LVL_FATAL, "Cannot stat %s: %s", shareRoot, strerror(errno));
|
LOG(LVL_FATAL, "Cannot stat %s: %s", shareRoot, strerror(errno));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -578,24 +643,7 @@ int main(int argc, char ** argv) {
|
||||||
remove_trailing_slash(shareRoot);
|
remove_trailing_slash(shareRoot);
|
||||||
|
|
||||||
LOG(LVL_INFO, "Shared directory is: %s", 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);
|
LOG(LVL_INFO, "Using port: %i", port);
|
||||||
} else {
|
|
||||||
LOG(LVL_INFO, "Using default port: %i", DEFAULT_PORT);
|
|
||||||
port = DEFAULT_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_MAGIC
|
#ifdef HAVE_MAGIC
|
||||||
// initialize libmagic
|
// initialize libmagic
|
||||||
|
|
Loading…
Reference in a new issue