Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hiding hidden (. dot) files as an option #72

Open
vashpan opened this issue Jan 1, 2025 · 6 comments
Open

Hiding hidden (. dot) files as an option #72

vashpan opened this issue Jan 1, 2025 · 6 comments

Comments

@vashpan
Copy link

vashpan commented Jan 1, 2025

Hello, it would be nice to be able to not displaying hidden files on directory listings.

My motivation is mostly macOS, which tends to leave a ton of "noise" in shared folders it accesses on my server. Sometimes I want to share those files with darkhttpd and then I'm quite annoyed with all those .DS_Store and other files.

I changed that myself in my build, but it probably should be done cleaner, with an option probably set to false by default.

Change is two lines of code in make_sorted_dirlist:

if (ent->d_name[0] == '.')
    continue; /* skip hidden files (any filename starting with '.') */

I can probably add an option parsing and make a proper pull request if there'll be such need.

@hhartzer
Copy link
Contributor

I think this is clever if there's other interest in it. I don't know if if I have a use for it.

Could possibly make it a settable prefix, although dotfiles would be the most common case.

@vashpan
Copy link
Author

vashpan commented Jan 21, 2025

Another motivation would be some configuration files/metadata, that maybe someones would like to hide from sharing. I can imagine someone is sharing its entire home folder (😅), but doesn't necessarily want to also share its SSH configuration and other stuff 🙂

@g-rden
Copy link
Contributor

g-rden commented Jan 22, 2025

imagine someone is sharing its entire home folder

At this point a blacklist would be preferable instead of just not serving dotfiles. Which is probably out of the scope of this project.

This patch works fine for me

From 2681ddd5f2dcc5a431074f2b3bb50fac65893fae Mon Sep 17 00:00:00 2001
From: g-rden <localhost>
Date: Wed, 22 Jan 2025 09:31:41 +0100
Subject: [PATCH] hide dotfiles option

---
 darkhttpd.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/darkhttpd.c b/darkhttpd.c
index ea778b4..ccdcaef 100644
--- a/darkhttpd.c
+++ b/darkhttpd.c
@@ -327,7 +327,8 @@ static char *logfile_name = NULL;   /* NULL = no logging */
 static FILE *logfile = NULL;
 static char *pidfile_name = NULL;   /* NULL = no pidfile */
 static int want_chroot = 0, want_daemon = 0, want_accf = 0,
-           want_keepalive = 1, want_server_id = 1, want_single_file = 0;
+           want_keepalive = 1, want_server_id = 1, want_single_file = 0,
+           want_hidden = 1;
 static char *server_hdr = NULL;
 static char *auth_key = NULL;       /* NULL or "Basic base64_of_password" */
 static char *custom_hdrs = NULL;
@@ -969,6 +970,8 @@ static void usage(const char *argv0) {
     printf("\t--single-file\n"
     "\t\tOnly serve a single file provided as /path/to/file instead\n"
     "\t\tof a whole directory.\n\n");
+    printf("\t--hide_dotfiles\n"
+    "\t\tDon't serve dotfiles.\n\n");
     printf("\t--forward host url (default: don't forward)\n"
     "\t\tWeb forward (301 redirect).\n"
     "\t\tRequests to the host are redirected to the corresponding url.\n"
@@ -1182,6 +1185,9 @@ static void parse_commandline(const int argc, char *argv[]) {
         else if (strcmp(argv[i], "--single-file") == 0) {
             want_single_file = 1;
         }
+        else if (strcmp(argv[i], "--hide_dotfiles") == 0) {
+            want_hidden = 0;
+        }
         else if (strcmp(argv[i], "--forward") == 0) {
             const char *host, *url;
             if (++i >= argc)
@@ -1916,6 +1922,8 @@ static ssize_t make_sorted_dirlist(const char *path, struct dlent ***output) {
 
         if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
             continue; /* skip "." and ".." */
+        if (!want_hidden && ent->d_name[0] == '.')
+            continue;
         assert(strlen(ent->d_name) <= MAXNAMLEN);
         sprintf(currname, "%s%s", path, ent->d_name);
         if (stat(currname, &s) == -1)
-- 
2.48.1

@vashpan
Copy link
Author

vashpan commented Jan 22, 2025

I never meant to always not serve them, but rather adding it as a flag, like you just did - so thanks and hope it'll go mainline 👍

@emikulic
Copy link
Owner

emikulic commented Jan 25, 2025

I'm a little bit worried about hiding dotfiles from directory listings but then still serving them if someone enters it in the address bar, because of the potential security consequences.

@g-rden I like your patch. Would you like to send it as a PR? Couple of nits:

want_hidden -> want_hide_dotfiles

"Don't serve dotfiles." -> this needs to be really clear -> "Hide dotfiles from directory listings, but still serve them if requested."

--hide_dotfiles -> --hide-dotfiles (hyphens for flags)

@g-rden
Copy link
Contributor

g-rden commented Jan 25, 2025

still serving them if someone enters it in the address bar

I missed that. That seems like a bad idea and not serving them would not conflict with the interests of this issue.

I made a quick patch. I don't know if it's any good.

From 11e5fee2b109cbb2dbd44804a0d8b3b5002b0986 Mon Sep 17 00:00:00 2001
From: g-rden <localhost>
Date: Sat, 25 Jan 2025 08:38:15 +0100
Subject: [PATCH] Don't serve dotfiles option

---
 darkhttpd.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/darkhttpd.c b/darkhttpd.c
index ea778b4..eee9f71 100644
--- a/darkhttpd.c
+++ b/darkhttpd.c
@@ -327,7 +327,8 @@ static char *logfile_name = NULL;   /* NULL = no logging */
 static FILE *logfile = NULL;
 static char *pidfile_name = NULL;   /* NULL = no pidfile */
 static int want_chroot = 0, want_daemon = 0, want_accf = 0,
-           want_keepalive = 1, want_server_id = 1, want_single_file = 0;
+           want_keepalive = 1, want_server_id = 1, want_single_file = 0,
+           want_hide_dotfiles = 0;
 static char *server_hdr = NULL;
 static char *auth_key = NULL;       /* NULL or "Basic base64_of_password" */
 static char *custom_hdrs = NULL;
@@ -969,6 +970,8 @@ static void usage(const char *argv0) {
     printf("\t--single-file\n"
     "\t\tOnly serve a single file provided as /path/to/file instead\n"
     "\t\tof a whole directory.\n\n");
+    printf("\t--hide-dotfiles\n"
+    "\t\tDon't serve dotfiles.\n\n");
     printf("\t--forward host url (default: don't forward)\n"
     "\t\tWeb forward (301 redirect).\n"
     "\t\tRequests to the host are redirected to the corresponding url.\n"
@@ -1182,6 +1185,9 @@ static void parse_commandline(const int argc, char *argv[]) {
         else if (strcmp(argv[i], "--single-file") == 0) {
             want_single_file = 1;
         }
+        else if (strcmp(argv[i], "--hide-dotfiles") == 0) {
+            want_hide_dotfiles = 1;
+        }
         else if (strcmp(argv[i], "--forward") == 0) {
             const char *host, *url;
             if (++i >= argc)
@@ -1916,6 +1922,8 @@ static ssize_t make_sorted_dirlist(const char *path, struct dlent ***output) {
 
         if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
             continue; /* skip "." and ".." */
+        if (want_hide_dotfiles && ent->d_name[0] == '.')
+            continue;
         assert(strlen(ent->d_name) <= MAXNAMLEN);
         sprintf(currname, "%s%s", path, ent->d_name);
         if (stat(currname, &s) == -1)
@@ -2174,6 +2182,20 @@ static void process_get(struct connection *conn) {
         return;
     }
 
+    if (want_hide_dotfiles) {
+               size_t i;
+        for (i = 0; i < strlen(decoded_url) - 1; i++) {
+            if (decoded_url[i] == '/' && decoded_url[i + 1] == '.') {
+                free(decoded_url);
+                /* Don't serve dot files when using --hide-dotfiles */
+                default_reply(conn, 404, "Not Found",
+                    "The URL you requested was not found.");
+                return;
+            }
+        }
+    }
+
+
     if (want_single_file) {
         target = xstrdup(wwwroot);
         mimetype = url_content_type(wwwroot);
-- 
2.48.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants