Overview
Comment: | Added compile-time support for a fake chroot mode instead of using a real chroot (this may change into a runtime option one day) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5ea7bc000130190bc06ffe49d09549bf |
User & Date: | rkeene on 2016-08-17 16:21:30 |
Other Links: | manifest | tags |
Context
2016-08-17
| ||
16:22 | Filed 1.18 check-in: a78878e047 user: rkeene tags: trunk, 1.18 | |
16:21 | Added compile-time support for a fake chroot mode instead of using a real chroot (this may change into a runtime option one day) check-in: 5ea7bc0001 user: rkeene tags: trunk | |
2016-08-09
| ||
16:51 | Disabled -Werror, it is a bad idea for releases to include check-in: 1a822c0ca5 user: rkeene tags: trunk | |
Changes
Modified README from [d62e07fe87] to [8ec76224c9].
︙ | ︙ | |||
67 68 69 70 71 72 73 | This is an internal option and should only be used during development. 4. Differing HTTP semantics (CFLAGS, -DFILED_NONBLOCK_HTTP=1) It is possible that some HTTP clients may not process the HTTP stream being delivered if they cannot write to the HTTP stream itself. This has not been observed yet, but it is possible. If these semantics are needed (and they should not be) then they can be enabled with this | | > > > > > > > > > | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | This is an internal option and should only be used during development. 4. Differing HTTP semantics (CFLAGS, -DFILED_NONBLOCK_HTTP=1) It is possible that some HTTP clients may not process the HTTP stream being delivered if they cannot write to the HTTP stream itself. This has not been observed yet, but it is possible. If these semantics are needed (and they should not be) then they can be enabled with this flag at the cost of performance. 5. Differing chroot() semantics (CFLAGS, -DFILED_FAKE_CHROOT=1) In some cases it is desirable to mangle paths with a path prefix rather than call chroot() at startup. This is less secure and slower and should be generally avoided -- however it may be necessary to do. In these cases the executable may be compiled with the FILED_FAKE_CHROOT C preprocessor macro defined and instead of calling chroot() all HTTP requests will have the root suffix specified as the argument to the "-r" or "--root" option prepended to them. 6. MIME Types (MIMETYPES) For single-file convenience "filed" compiles the mapping of file extensions (the string in the filename following its last dot (".")) into the executable. This mapping comes from a file in the format of type1 type1_extension1 type1_extension2... type2 type2_extension1 type2_extension2... ... However it may not be desirable to include this mapping, or it may be desirable to use your own mapping rather than the default one. This |
︙ | ︙ |
Modified filed.c from [7391155930] to [e20f1f0a83].
︙ | ︙ | |||
115 116 117 118 119 120 121 122 123 124 125 126 127 128 | attr = attr; } #endif /* Configuration options that work threads need to be aware of */ struct filed_options { int vhosts_enabled; }; /* Arguments for worker threads */ struct filed_worker_thread_args { int fd; struct filed_options options; }; | > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | attr = attr; } #endif /* Configuration options that work threads need to be aware of */ struct filed_options { int vhosts_enabled; const char *fake_newroot; }; /* Arguments for worker threads */ struct filed_worker_thread_args { int fd; struct filed_options options; }; |
︙ | ︙ | |||
862 863 864 865 866 867 868 869 870 | (unsigned long long) time(NULL), (unsigned long long) random(), (unsigned long long) random(), (unsigned long long) random(), (unsigned long long) random() ); } /* Open a file and return file information */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 | (unsigned long long) time(NULL), (unsigned long long) random(), (unsigned long long) random(), (unsigned long long) random(), (unsigned long long) random() ); } #ifdef FILED_FAKE_CHROOT /* Translate a path into a fake chroot path */ static const char *filed_path_translate(const char *path, struct filed_options *options) { static __thread char pathBuffer[8192]; int snprintf_ret; /* If no alternative root is specified, return the unadorned path */ if (!options->fake_newroot) { return(path); } /* Verify that this request will not go outside of the specified root */ if (strstr(path, "/../") != NULL || path[0] != '/') { filed_log_msg_debug("Unable to translate path \"%s\", contains invalid characters", path); return(options->fake_newroot); } /* Create the new path into our local (TLS) static buffer */ snprintf_ret = snprintf(pathBuffer, sizeof(pathBuffer), "%s/%s", options->fake_newroot, path); if (snprintf_ret < 0 || ((unsigned int) snprintf_ret) >= sizeof(pathBuffer)) { filed_log_msg_debug("Unable to translate path \"%s\", will not fit into new buffer", path); return(options->fake_newroot); } filed_log_msg_debug("Translating path \"%s\" into \"%s\"", path, pathBuffer); /* Return the new path */ return(pathBuffer); } static void filed_path_translate_set_root(const char *var, struct filed_options *options, const char *val) { options->fake_newroot = strdup(val); return; /* var is only used in the macro -- discard it here */ var = var; } #else #define filed_path_translate(path, options) path #define filed_path_translate_set_root(var, options, val) var = strdup(val) #endif /* Open a file and return file information */ static struct filed_fileinfo *filed_open_file(const char *path, struct filed_fileinfo *buffer, struct filed_options *options) { struct filed_fileinfo *cache; unsigned int cache_idx; off_t len; int fd; if (filed_fileinfo_fdcache_size != 0) { cache_idx = filed_hash((const unsigned char *) path, filed_fileinfo_fdcache_size); |
︙ | ︙ | |||
890 891 892 893 894 895 896 | cache->path[0] = '\0'; cache->fd = -1; } if (strcmp(path, cache->path) != 0) { filed_log_msg_debug("Cache miss for idx: %lu: OLD \"%s\", NEW \"%s\"", (unsigned long) cache_idx, cache->path, path); | | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 | cache->path[0] = '\0'; cache->fd = -1; } if (strcmp(path, cache->path) != 0) { filed_log_msg_debug("Cache miss for idx: %lu: OLD \"%s\", NEW \"%s\"", (unsigned long) cache_idx, cache->path, path); fd = open(filed_path_translate(path, options), O_RDONLY | O_LARGEFILE); if (fd < 0) { if (filed_fileinfo_fdcache_size != 0) { pthread_mutex_unlock(&cache->mutex); } return(NULL); } |
︙ | ︙ | |||
941 942 943 944 945 946 947 948 949 950 951 952 953 954 | memcpy(buffer->etag, cache->etag, sizeof(buffer->etag)); buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b); pthread_mutex_unlock(&cache->mutex); } return(buffer); } /* Process an HTTP request and return the path requested */ static struct filed_http_request *filed_get_http_request(FILE *fp, struct filed_http_request *buffer_st, struct filed_options *options) { char *method, *path; char *buffer, *workbuffer, *workbuffer_next; char *fgets_ret; | > > > | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | memcpy(buffer->etag, cache->etag, sizeof(buffer->etag)); buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b); pthread_mutex_unlock(&cache->mutex); } return(buffer); /* options is only used if fake chroot is enabled, confuse the compiler */ options = options; } /* Process an HTTP request and return the path requested */ static struct filed_http_request *filed_get_http_request(FILE *fp, struct filed_http_request *buffer_st, struct filed_options *options) { char *method, *path; char *buffer, *workbuffer, *workbuffer_next; char *fgets_ret; |
︙ | ︙ | |||
1235 1236 1237 1238 1239 1240 1241 | /* If the requested path is a directory, redirect to index page */ if (request->type == FILED_REQUEST_TYPE_DIRECTORY) { filed_redirect_index(fp, date_current, path, log); return(FILED_CONNECTION_CLOSE); } | | | 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 | /* If the requested path is a directory, redirect to index page */ if (request->type == FILED_REQUEST_TYPE_DIRECTORY) { filed_redirect_index(fp, date_current, path, log); return(FILED_CONNECTION_CLOSE); } fileinfo = filed_open_file(path, &request->fileinfo, options); if (fileinfo == NULL) { filed_error_page(fp, date_current, 404, request->method, "open_failed", log); return(FILED_CONNECTION_CLOSE); } if (request->headers.range.present) { |
︙ | ︙ | |||
1679 1680 1681 1682 1683 1684 1685 | return(0); } /* Run process */ int main(int argc, char **argv) { struct option options[12]; | | < < < | 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 | return(0); } /* Run process */ int main(int argc, char **argv) { struct option options[12]; struct filed_options thread_options = {0}; const char *bind_addr = BIND_ADDR, *newroot = NULL, *log_file = LOG_FILE; FILE *log_fp; uid_t user = 0; int port = PORT, thread_count = THREAD_COUNT; int cache_size = CACHE_SIZE; int init_ret, chroot_ret, setuid_ret, lookup_ret, chdir_ret; int setuid_enabled = 0, daemon_enabled = 0; int ch; int fd; /* Process arguments */ filed_getopt_long_setopt(&options[0], "port", required_argument, 'p'); filed_getopt_long_setopt(&options[1], "threads", required_argument, 't'); filed_getopt_long_setopt(&options[2], "cache", required_argument, 'c'); filed_getopt_long_setopt(&options[3], "bind", required_argument, 'b'); filed_getopt_long_setopt(&options[4], "user", required_argument, 'u'); filed_getopt_long_setopt(&options[5], "root", required_argument, 'r'); |
︙ | ︙ | |||
1730 1731 1732 1733 1734 1735 1736 | if (lookup_ret != 0) { filed_print_help(stderr, 0, "Invalid username specified"); return(1); } break; case 'r': | | | 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 | if (lookup_ret != 0) { filed_print_help(stderr, 0, "Invalid username specified"); return(1); } break; case 'r': filed_path_translate_set_root(newroot, &thread_options, optarg); break; case 'l': log_file = strdup(optarg); break; case 'd': daemon_enabled = 1; break; |
︙ | ︙ |