From 04c503bc3787af6c405af73071c5ddc9bcccf79a Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 7 Aug 2018 07:48:37 -0400 Subject: xdg support: split xdg whitelist code in a different module --- src/firejail/firejail.h | 18 +-- src/firejail/fs_whitelist.c | 184 ++------------------- src/firejail/macros.c | 381 ++++++++++++++++++++++++++++++++++++++++++++ src/firejail/util.c | 334 -------------------------------------- test/fs/user-dirs.dirs | 15 -- 5 files changed, 398 insertions(+), 534 deletions(-) create mode 100644 src/firejail/macros.c delete mode 100644 test/fs/user-dirs.dirs diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 471f2e55c..f31d6a2bc 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -491,16 +491,14 @@ int arp_check(const char *dev, uint32_t destaddr); // assign an IP address using arp scanning uint32_t arp_assign(const char *dev, Bridge *br); +// macros.c +char *expand_home(const char *path, const char *homedir); +char *resolve_macro(const char *name); +void invalid_filename(const char *fname, int globbing); +int is_macro(const char *name); + + // util.c -extern char *dentry[]; -extern char *mentry[]; -extern char *ventry[]; -extern char *pentry[]; -extern char *deentry[]; -extern char *doentry[]; - -char *resolve_xdg(int flags, const char *var, size_t length, const char *prnt); -char *resolve_hardcoded(int flags, char *entries[], const char *prnt); void errLogExit(char* fmt, ...); void fwarning(char* fmt, ...); void fmessage(char* fmt, ...); @@ -525,10 +523,8 @@ void check_private_dir(void); void update_map(char *mapping, char *map_file); void wait_for_other(int fd); void notify_other(int fd); -char *expand_home(const char *path, const char* homedir); const char *gnu_basename(const char *path); uid_t pid_get_uid(pid_t pid); -void invalid_filename(const char *fname, int globbing); uid_t get_group_id(const char *group); int remove_overlay_directory(void); void flush_stdin(void); diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 6a6e91bc9..a2803ccbc 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c @@ -370,185 +370,21 @@ void fs_whitelist(void) { } char *dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - // resolve ${DOWNLOADS} - if (strcmp(dataptr, "${DOWNLOADS}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, dentry, "Downloads"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else { - if (!nowhitelist_flag && !arg_quiet && !arg_private) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n"); - fprintf(stderr, "***\n"); - } - entry->data = EMPTY_STRING; - continue; - } - } - - // resolve ${MUSIC} - if (strcmp(dataptr, "${MUSIC}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, mentry, "Music"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else { - if (!nowhitelist_flag && !arg_quiet && !arg_private) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Music directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Music directory for your application.\n"); - fprintf(stderr, "***\n"); - } - entry->data = EMPTY_STRING; - continue; - } - } - - // resolve ${VIDEOS} - if (strcmp(dataptr, "${VIDEOS}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, ventry, "Videos"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else { - if (!nowhitelist_flag && !arg_quiet && !arg_private) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Videos directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Videos directory for your application.\n"); - fprintf(stderr, "***\n"); - } - entry->data = EMPTY_STRING; - continue; - } - } - - // resolve ${PICTURES} - if (strcmp(dataptr, "${PICTURES}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, pentry, "Pictures"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; + // resolve macros + if (is_macro(dataptr)) { + char *tmp = resolve_macro(dataptr); + if (tmp != NULL) + tmp = parse_nowhitelist(nowhitelist_flag, tmp); + + if (tmp) { + entry->data = tmp; dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else { - if (!nowhitelist_flag && !arg_quiet && !arg_private) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Pictures directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Pictures directory for your application.\n"); - fprintf(stderr, "***\n"); - } - entry->data = EMPTY_STRING; - continue; - } - } - - // resolve ${DESKTOP} - if (strcmp(dataptr, "${DESKTOP}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, deentry, "Desktop"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else { - if (!nowhitelist_flag && !arg_quiet && !arg_private) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Desktop directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Desktop directory for your application.\n"); - fprintf(stderr, "***\n"); - } - entry->data = EMPTY_STRING; - continue; - } - } - - // resolve ${DOCUMENTS} - if (strcmp(dataptr, "${DOCUMENTS}") == 0) { - char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents"); - char *tmpw1 = NULL; - if (tmp1 != NULL) - tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1); - char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, doentry, "Documents"); - char *tmpw2 = NULL; - if (tmp2 != NULL) - tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2); - if (tmp1 && tmpw1) { - entry->data = tmpw1; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } - else if (tmp2 && tmpw2) { - entry->data = tmpw2; - dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; - } else { if (!nowhitelist_flag && !arg_quiet && !arg_private) { fprintf(stderr, "***\n"); - fprintf(stderr, "*** Warning: cannot whitelist Documents directory\n"); - fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); - fprintf(stderr, "*** \tPlease create a proper Documents directory for your application.\n"); + fprintf(stderr, "*** Warning: cannot whitelist %s directory\n", dataptr); + fprintf(stderr, "*** Any file saved in this directory will be lost when the sandbox is closed.\n"); fprintf(stderr, "***\n"); } entry->data = EMPTY_STRING; diff --git a/src/firejail/macros.c b/src/firejail/macros.c new file mode 100644 index 000000000..f111802d7 --- /dev/null +++ b/src/firejail/macros.c @@ -0,0 +1,381 @@ +/* + * Copyright (C) 2014-2018 Firejail Authors + * + * This file is part of firejail project + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "firejail.h" +#include +#define MAXBUF 4098 + +typedef struct macro_t { + char *name; // macro name + char *xdg; // xdg line in ~/.config/user-dirs.dirs +#define MAX_TRANSLATIONS 3 // several translations in case ~/.config/user-dirs.dirs not found + char *translation[MAX_TRANSLATIONS]; +} Macro; + +Macro macro[] = { + { + "${DOWNLOADS}", + "XDG_DOWNLOAD_DIR=\"$HOME/", + { "Downloads", "Загрузки", "Téléchargement" } + }, + + { + "${MUSIC}", + "XDG_MUSIC_DIR=\"$HOME/", + {"Music", "Музыка", "Musique"} + }, + + { + "${VIDEOS}", + "XDG_VIDEOS_DIR=\"$HOME/", + {"Videos", "Видео", "Vidéos"} + }, + + { + "${PICTURES}", + "XDG_PICTURES_DIR=\"$HOME/", + {"Pictures", "Изображения", "Photos"} + }, + + { + "${DESKTOP}", + "XDG_DESKTOP_DIR=\"$HOME/", + {"Desktop", "Рабочий стол", "Bureau"} + }, + + { + "${DOCUMENTS}", + "XDG_DOCUMENTS_DIR=\"$HOME/", + {"Documents", "Документы", "Documents"} + }, + + { 0 } +}; + +// return -1 if not found +int macro_id(const char *name) { + int i = 0; + while (macro[i].name != NULL) { + if (strcmp(name, macro[i].name) == 0) + return i; + i++; + } + + return -1; +} + +int is_macro(const char *name) { + assert(name); + int len = strlen(name); + if (len <= 4) + return 0; + if (*name == '$' && name[1] == '{' && name[len - 1] == '}') + return 1; + return 0; +} + +static char *resolve_xdg(const char *var) { + char *fname; + struct stat s; + size_t length = strlen(var); + + if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1) + errExit("asprintf"); + FILE *fp = fopen(fname, "r"); + if (!fp) { + free(fname); + return NULL; + } + free(fname); + + char buf[MAXBUF]; + while (fgets(buf, MAXBUF, fp)) { + char *ptr = buf; + + // skip blanks + while (*ptr == ' ' || *ptr == '\t') + ptr++; + if (*ptr == '\0' || *ptr == '\n' || *ptr == '#') + continue; + + if (strncmp(ptr, var, length) == 0) { + char *ptr1 = ptr + length; + char *ptr2 = strchr(ptr1, '"'); + if (ptr2) { + fclose(fp); + *ptr2 = '\0'; + if (strlen(ptr1) != 0) { + if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1) + errExit("asprintf"); + + if (stat(fname, &s) == -1) { + free(fname); + return NULL; + } + free(fname); + + char *rv = strdup(ptr1); + if (!rv) + errExit(ptr1); + return rv; + } + else + return NULL; + } + } + } + + fclose(fp); + return NULL; +} + +static char *resolve_hardcoded(char *entries[]) { + char *fname; + struct stat s; + + int i = 0; + while (entries[i] != NULL) { + if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1) + errExit("asprintf"); + + if (stat(fname, &s) == 0) { + free(fname); + return entries[i]; + } + free(fname); + i++; + } + + return NULL; +} + +char *resolve_macro(const char *name) { + char *rv = NULL; + int id = macro_id(name); + if (id == -1) + return NULL; + + rv = resolve_xdg(macro[id].xdg); + if (rv == NULL) + rv = resolve_hardcoded(macro[id].translation); + if (rv) + printf("Directory %s resolved as %s\n", name, rv); + + return rv; +} + +// This function takes a pathname supplied by the user and expands '~' and +// '${HOME}' at the start, to refer to a path relative to the user's home +// directory (supplied). +// The return value is allocated using malloc and must be freed by the caller. +// The function returns NULL if there are any errors. +char *expand_home(const char *path, const char *homedir) { + assert(path); + assert(homedir); + + int called_as_root = 0; + + if(geteuid() == 0) + called_as_root = 1; + + if(called_as_root) { + EUID_USER(); + } + + EUID_ASSERT(); + + // Replace home macro + char *new_name = NULL; + if (strncmp(path, "${HOME}", 7) == 0) { + if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if (*path == '~') { + if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if (strncmp(path, "${CFG}", 6) == 0) { + if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } +#if 0 + else if (strncmp(path, "${DOWNLOADS}", 12) == 0) { + char *tmp = resolve_xdg("XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); + char *tmp2 = resolve_hardcoded(dentry, "Downloads"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } + + else if (strncmp(path, "${MUSIC}", 8) == 0) { + char *tmp = resolve_xdg("XDG_MUSIC_DIR=\"$HOME/", 21, "Music"); + char *tmp2 = resolve_hardcoded(mentry, "Music"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } + + else if (strncmp(path, "${VIDEOS}", 9) == 0) { + char *tmp = resolve_xdg("XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos"); + char *tmp2 = resolve_hardcoded(ventry, "Videos"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } + + else if (strncmp(path, "${PICTURES}", 11) == 0) { + char *tmp = resolve_xdg("XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures"); + char *tmp2 = resolve_hardcoded(pentry, "Pictures"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } + + else if (strncmp(path, "${DESKTOP}", 10) == 0) { + char *tmp = resolve_xdg("XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop"); + char *tmp2 = resolve_hardcoded(deentry, "Desktop"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } + + else if (strncmp(path, "${DOCUMENTS}", 12) == 0) { + char *tmp = resolve_xdg("XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents"); + char *tmp2 = resolve_hardcoded(doentry, "Documents"); + if(tmp) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + else if(tmp2) { + if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) + errExit("asprintf"); + if(called_as_root) + EUID_ROOT(); + return new_name; + } + } +#endif + char *rv = strdup(path); + if (!rv) + errExit("strdup"); + + if(called_as_root) + EUID_ROOT(); + + return rv; +} + +void invalid_filename(const char *fname, int globbing) { +// EUID_ASSERT(); + assert(fname); + const char *ptr = fname; + + if (strncmp(ptr, "${HOME}", 7) == 0) + ptr = fname + 7; + else if (strncmp(ptr, "${PATH}", 7) == 0) + ptr = fname + 7; + else { + int id = macro_id(fname); + if (id != -1) + return; + } + + int len = strlen(ptr); + + if (globbing) { + // file globbing ('*?[]') is allowed + if (strcspn(ptr, "\\&!\"'<>%^(){};,") != (size_t)len) { + fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); + exit(1); + } + } + else { + if (strcspn(ptr, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) { + fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); + exit(1); + } + } +} diff --git a/src/firejail/util.c b/src/firejail/util.c index d79e955a7..67776b36c 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -34,136 +34,7 @@ #define MAX_GROUPS 1024 #define MAXBUF 4098 -char *dentry[] = { - "Downloads", - "Загрузки", - "Téléchargement", - NULL -}; - -char *mentry[] = { - "Music", - "Музыка", - "Musique", - NULL -}; - -char *ventry[] = { - "Videos", - "Видео", - "Vidéos", - NULL -}; - -char *pentry[] = { - "Pictures", - "Изображения", - "Photos", - NULL -}; - -char *deentry[] = { - "Desktop", - "Рабочий стол", - "Bureau", - NULL -}; - -char *doentry[] = { - "Documents", - "Документы", - "Documents", - NULL -}; - -char *resolve_xdg(int flags, const char *var, size_t length, const char *prnt) { - char *fname; - struct stat s; - - if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1) - errExit("asprintf"); - FILE *fp = fopen(fname, "r"); - if (!fp) { - free(fname); - return NULL; - } - free(fname); - - char buf[MAXBUF]; - while (fgets(buf, MAXBUF, fp)) { - char *ptr = buf; - - // skip blanks - while (*ptr == ' ' || *ptr == '\t') - ptr++; - if (*ptr == '\0' || *ptr == '\n' || *ptr == '#') - continue; - - if (strncmp(ptr, var, length) == 0) { - char *ptr1 = ptr + length; - char *ptr2 = strchr(ptr1, '"'); - if (ptr2) { - fclose(fp); - *ptr2 = '\0'; - if (flags) - printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1); - if (strlen(ptr1) != 0) { - if (flags) - printf("%s ",prnt); - printf("directory resolved as \"%s\"\n", ptr1); - - if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1) - errExit("asprintf"); - - if (stat(fname, &s) == -1) { - free(fname); - goto errout; - } - free(fname); - return ptr1; - } - else - goto errout; - } - } - } - - fclose(fp); - return NULL; - - errout: - if (!arg_private && arg_debug) { - fprintf(stderr, "***\n"); - fprintf(stderr, "*** Error: %s directory was not found in user home.\n",prnt); - fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n"); - fprintf(stderr, "***\n"); - } - return NULL; -} -char *resolve_hardcoded(int flags, char *entries[], const char *prnt) { - char *fname; - struct stat s; - - int i = 0; - while (entries[i] != NULL) { - if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1) - errExit("asprintf"); - - if (stat(fname, &s) == 0) { - if (flags) { - printf("%s ", prnt); - printf("directory resolved as \"%s\"\n", fname); - } - free(fname); - return entries[i]; - } - free(fname); - i++; - } - - return NULL; -} // send the error to /var/log/auth.log and exit after a small delay void errLogExit(char* fmt, ...) { @@ -855,173 +726,6 @@ void notify_other(int fd) { } -// This function takes a pathname supplied by the user and expands '~' and -// '${HOME}' at the start, to refer to a path relative to the user's home -// directory (supplied). -// The return value is allocated using malloc and must be freed by the caller. -// The function returns NULL if there are any errors. -char *expand_home(const char *path, const char* homedir) { - assert(path); - assert(homedir); - - int called_as_root = 0; - - if(geteuid() == 0) - called_as_root = 1; - - if(called_as_root) { - EUID_USER(); - } - - EUID_ASSERT(); - - // Replace home macro - char *new_name = NULL; - if (strncmp(path, "${HOME}", 7) == 0) { - if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if (*path == '~') { - if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if (strncmp(path, "${CFG}", 6) == 0) { - if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - - else if (strncmp(path, "${DOWNLOADS}", 12) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); - char *tmp2 = resolve_hardcoded(arg_debug, dentry, "Downloads"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - else if (strncmp(path, "${MUSIC}", 8) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music"); - char *tmp2 = resolve_hardcoded(arg_debug, mentry, "Music"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - else if (strncmp(path, "${VIDEOS}", 9) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos"); - char *tmp2 = resolve_hardcoded(arg_debug, ventry, "Videos"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - else if (strncmp(path, "${PICTURES}", 11) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures"); - char *tmp2 = resolve_hardcoded(arg_debug, pentry, "Pictures"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - else if (strncmp(path, "${DESKTOP}", 10) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop"); - char *tmp2 = resolve_hardcoded(arg_debug, deentry, "Desktop"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - else if (strncmp(path, "${DOCUMENTS}", 12) == 0) { - char *tmp = resolve_xdg(arg_debug, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents"); - char *tmp2 = resolve_hardcoded(arg_debug, doentry, "Documents"); - if(tmp) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - else if(tmp2) { - if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1) - errExit("asprintf"); - if(called_as_root) - EUID_ROOT(); - return new_name; - } - } - - char *rv = strdup(path); - if (!rv) - errExit("strdup"); - - if(called_as_root) - EUID_ROOT(); - - return rv; -} // Equivalent to the GNU version of basename, which is incompatible with @@ -1082,44 +786,6 @@ uid_t pid_get_uid(pid_t pid) { } -void invalid_filename(const char *fname, int globbing) { -// EUID_ASSERT(); - assert(fname); - const char *ptr = fname; - - if (strncmp(ptr, "${HOME}", 7) == 0) - ptr = fname + 7; - else if (strncmp(ptr, "${PATH}", 7) == 0) - ptr = fname + 7; - else if (strcmp(fname, "${DOWNLOADS}") == 0) - return; - else if (strcmp(fname, "${MUSIC}") == 0) - return; - else if (strcmp(fname, "${VIDEOS}") == 0) - return; - else if (strcmp(fname, "${PICTURES}") == 0) - return; - else if (strcmp(fname, "${DESKTOP}") == 0) - return; - else if (strcmp(fname, "${DOCUMENTS}") == 0) - return; - - int len = strlen(ptr); - - if (globbing) { - // file globbing ('*?[]') is allowed - if (strcspn(ptr, "\\&!\"'<>%^(){};,") != (size_t)len) { - fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); - exit(1); - } - } - else { - if (strcspn(ptr, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) { - fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr); - exit(1); - } - } -} uid_t get_group_id(const char *group) { diff --git a/test/fs/user-dirs.dirs b/test/fs/user-dirs.dirs deleted file mode 100644 index ea3a3a4c2..000000000 --- a/test/fs/user-dirs.dirs +++ /dev/null @@ -1,15 +0,0 @@ -# This file is written by xdg-user-dirs-update -# If you want to change or add directories, just edit the line you're -# interested in. All local changes will be retained on the next run -# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped -# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an -# absolute path. No other format is supported. -# -XDG_DESKTOP_DIR="$HOME/Desktop" -XDG_DOWNLOAD_DIR="$HOME/Downloads" -XDG_TEMPLATES_DIR="$HOME/Templates" -XDG_PUBLICSHARE_DIR="$HOME/Public" -XDG_DOCUMENTS_DIR="$HOME/Documents" -XDG_MUSIC_DIR="$HOME/Music" -XDG_PICTURES_DIR="$HOME/Pictures" -XDG_VIDEOS_DIR="$HOME/Videos" -- cgit v1.2.3-54-g00ecf