aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/util.c
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-08-01 15:39:15 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2018-08-01 15:39:15 +0200
commitfaff9d14de30763b991bd5d0665891e6d8ad2733 (patch)
tree2f503b78e63ce4948439711695d7f744d6b96fa5 /src/firejail/util.c
parentenhance safe_fd function so it can digest arbitrary pathnames (diff)
parentFixed Documents handling (consume trailing /) and hide XDG warnings unless --... (diff)
downloadfirejail-faff9d14de30763b991bd5d0665891e6d8ad2733.tar.gz
firejail-faff9d14de30763b991bd5d0665891e6d8ad2733.tar.zst
firejail-faff9d14de30763b991bd5d0665891e6d8ad2733.zip
Merge branch 'master' of https://github.com/netblue30/firejail
Diffstat (limited to 'src/firejail/util.c')
-rw-r--r--src/firejail/util.c279
1 files changed, 273 insertions, 6 deletions
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 18f837d7e..d79e955a7 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -32,6 +32,138 @@
32#include <fcntl.h> 32#include <fcntl.h>
33 33
34#define MAX_GROUPS 1024 34#define MAX_GROUPS 1024
35#define MAXBUF 4098
36
37char *dentry[] = {
38 "Downloads",
39 "Загрузки",
40 "Téléchargement",
41 NULL
42};
43
44char *mentry[] = {
45 "Music",
46 "Музыка",
47 "Musique",
48 NULL
49};
50
51char *ventry[] = {
52 "Videos",
53 "Видео",
54 "Vidéos",
55 NULL
56};
57
58char *pentry[] = {
59 "Pictures",
60 "Изображения",
61 "Photos",
62 NULL
63};
64
65char *deentry[] = {
66 "Desktop",
67 "Рабочий стол",
68 "Bureau",
69 NULL
70};
71
72char *doentry[] = {
73 "Documents",
74 "Документы",
75 "Documents",
76 NULL
77};
78
79char *resolve_xdg(int flags, const char *var, size_t length, const char *prnt) {
80 char *fname;
81 struct stat s;
82
83 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
84 errExit("asprintf");
85 FILE *fp = fopen(fname, "r");
86 if (!fp) {
87 free(fname);
88 return NULL;
89 }
90 free(fname);
91
92 char buf[MAXBUF];
93 while (fgets(buf, MAXBUF, fp)) {
94 char *ptr = buf;
95
96 // skip blanks
97 while (*ptr == ' ' || *ptr == '\t')
98 ptr++;
99 if (*ptr == '\0' || *ptr == '\n' || *ptr == '#')
100 continue;
101
102 if (strncmp(ptr, var, length) == 0) {
103 char *ptr1 = ptr + length;
104 char *ptr2 = strchr(ptr1, '"');
105 if (ptr2) {
106 fclose(fp);
107 *ptr2 = '\0';
108 if (flags)
109 printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1);
110 if (strlen(ptr1) != 0) {
111 if (flags)
112 printf("%s ",prnt);
113 printf("directory resolved as \"%s\"\n", ptr1);
114
115 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
116 errExit("asprintf");
117
118 if (stat(fname, &s) == -1) {
119 free(fname);
120 goto errout;
121 }
122 free(fname);
123 return ptr1;
124 }
125 else
126 goto errout;
127 }
128 }
129 }
130
131 fclose(fp);
132 return NULL;
133
134 errout:
135 if (!arg_private && arg_debug) {
136 fprintf(stderr, "***\n");
137 fprintf(stderr, "*** Error: %s directory was not found in user home.\n",prnt);
138 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
139 fprintf(stderr, "***\n");
140 }
141 return NULL;
142}
143
144char *resolve_hardcoded(int flags, char *entries[], const char *prnt) {
145 char *fname;
146 struct stat s;
147
148 int i = 0;
149 while (entries[i] != NULL) {
150 if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1)
151 errExit("asprintf");
152
153 if (stat(fname, &s) == 0) {
154 if (flags) {
155 printf("%s ", prnt);
156 printf("directory resolved as \"%s\"\n", fname);
157 }
158 free(fname);
159 return entries[i];
160 }
161 free(fname);
162 i++;
163 }
164
165 return NULL;
166}
35 167
36// send the error to /var/log/auth.log and exit after a small delay 168// send the error to /var/log/auth.log and exit after a small delay
37void errLogExit(char* fmt, ...) { 169void errLogExit(char* fmt, ...) {
@@ -732,27 +864,162 @@ char *expand_home(const char *path, const char* homedir) {
732 assert(path); 864 assert(path);
733 assert(homedir); 865 assert(homedir);
734 866
867 int called_as_root = 0;
868
869 if(geteuid() == 0)
870 called_as_root = 1;
871
872 if(called_as_root) {
873 EUID_USER();
874 }
875
876 EUID_ASSERT();
877
735 // Replace home macro 878 // Replace home macro
736 char *new_name = NULL; 879 char *new_name = NULL;
737 if (strncmp(path, "${HOME}", 7) == 0) { 880 if (strncmp(path, "${HOME}", 7) == 0) {
738 if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1) 881 if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1)
739 errExit("asprintf"); 882 errExit("asprintf");
883 if(called_as_root)
884 EUID_ROOT();
740 return new_name; 885 return new_name;
741 } 886 }
742 else if (*path == '~') { 887 else if (*path == '~') {
743 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) 888 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
744 errExit("asprintf"); 889 errExit("asprintf");
745 return new_name; 890 if(called_as_root)
891 EUID_ROOT();
892 return new_name;
746 } 893 }
747 else if (strncmp(path, "${CFG}", 6) == 0) { 894 else if (strncmp(path, "${CFG}", 6) == 0) {
748 if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1) 895 if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1)
749 errExit("asprintf"); 896 errExit("asprintf");
750 return new_name; 897 if(called_as_root)
898 EUID_ROOT();
899 return new_name;
900 }
901
902 else if (strncmp(path, "${DOWNLOADS}", 12) == 0) {
903 char *tmp = resolve_xdg(arg_debug, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads");
904 char *tmp2 = resolve_hardcoded(arg_debug, dentry, "Downloads");
905 if(tmp) {
906 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
907 errExit("asprintf");
908 if(called_as_root)
909 EUID_ROOT();
910 return new_name;
911 }
912 else if(tmp2) {
913 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
914 errExit("asprintf");
915 if(called_as_root)
916 EUID_ROOT();
917 return new_name;
918 }
919 }
920
921 else if (strncmp(path, "${MUSIC}", 8) == 0) {
922 char *tmp = resolve_xdg(arg_debug, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music");
923 char *tmp2 = resolve_hardcoded(arg_debug, mentry, "Music");
924 if(tmp) {
925 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1)
926 errExit("asprintf");
927 if(called_as_root)
928 EUID_ROOT();
929 return new_name;
930 }
931 else if(tmp2) {
932 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1)
933 errExit("asprintf");
934 if(called_as_root)
935 EUID_ROOT();
936 return new_name;
937 }
938 }
939
940 else if (strncmp(path, "${VIDEOS}", 9) == 0) {
941 char *tmp = resolve_xdg(arg_debug, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos");
942 char *tmp2 = resolve_hardcoded(arg_debug, ventry, "Videos");
943 if(tmp) {
944 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1)
945 errExit("asprintf");
946 if(called_as_root)
947 EUID_ROOT();
948 return new_name;
949 }
950 else if(tmp2) {
951 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1)
952 errExit("asprintf");
953 if(called_as_root)
954 EUID_ROOT();
955 return new_name;
956 }
957 }
958
959 else if (strncmp(path, "${PICTURES}", 11) == 0) {
960 char *tmp = resolve_xdg(arg_debug, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures");
961 char *tmp2 = resolve_hardcoded(arg_debug, pentry, "Pictures");
962 if(tmp) {
963 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1)
964 errExit("asprintf");
965 if(called_as_root)
966 EUID_ROOT();
967 return new_name;
968 }
969 else if(tmp2) {
970 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1)
971 errExit("asprintf");
972 if(called_as_root)
973 EUID_ROOT();
974 return new_name;
975 }
976 }
977
978 else if (strncmp(path, "${DESKTOP}", 10) == 0) {
979 char *tmp = resolve_xdg(arg_debug, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop");
980 char *tmp2 = resolve_hardcoded(arg_debug, deentry, "Desktop");
981 if(tmp) {
982 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1)
983 errExit("asprintf");
984 if(called_as_root)
985 EUID_ROOT();
986 return new_name;
987 }
988 else if(tmp2) {
989 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1)
990 errExit("asprintf");
991 if(called_as_root)
992 EUID_ROOT();
993 return new_name;
994 }
995 }
996
997 else if (strncmp(path, "${DOCUMENTS}", 12) == 0) {
998 char *tmp = resolve_xdg(arg_debug, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents");
999 char *tmp2 = resolve_hardcoded(arg_debug, doentry, "Documents");
1000 if(tmp) {
1001 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
1002 errExit("asprintf");
1003 if(called_as_root)
1004 EUID_ROOT();
1005 return new_name;
1006 }
1007 else if(tmp2) {
1008 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
1009 errExit("asprintf");
1010 if(called_as_root)
1011 EUID_ROOT();
1012 return new_name;
1013 }
751 } 1014 }
752 1015
753 char *rv = strdup(path); 1016 char *rv = strdup(path);
754 if (!rv) 1017 if (!rv)
755 errExit("strdup"); 1018 errExit("strdup");
1019
1020 if(called_as_root)
1021 EUID_ROOT();
1022
756 return rv; 1023 return rv;
757} 1024}
758 1025