aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/util.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2018-08-07 07:48:37 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2018-08-07 07:48:37 -0400
commit04c503bc3787af6c405af73071c5ddc9bcccf79a (patch)
treefd60129758e787eac02b3e1bafec6545d754b113 /src/firejail/util.c
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-04c503bc3787af6c405af73071c5ddc9bcccf79a.tar.gz
firejail-04c503bc3787af6c405af73071c5ddc9bcccf79a.tar.zst
firejail-04c503bc3787af6c405af73071c5ddc9bcccf79a.zip
xdg support: split xdg whitelist code in a different module
Diffstat (limited to 'src/firejail/util.c')
-rw-r--r--src/firejail/util.c334
1 files changed, 0 insertions, 334 deletions
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 @@
34#define MAX_GROUPS 1024 34#define MAX_GROUPS 1024
35#define MAXBUF 4098 35#define MAXBUF 4098
36 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 37
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}
167 38
168// send the error to /var/log/auth.log and exit after a small delay 39// send the error to /var/log/auth.log and exit after a small delay
169void errLogExit(char* fmt, ...) { 40void errLogExit(char* fmt, ...) {
@@ -855,173 +726,6 @@ void notify_other(int fd) {
855} 726}
856 727
857 728
858// This function takes a pathname supplied by the user and expands '~' and
859// '${HOME}' at the start, to refer to a path relative to the user's home
860// directory (supplied).
861// The return value is allocated using malloc and must be freed by the caller.
862// The function returns NULL if there are any errors.
863char *expand_home(const char *path, const char* homedir) {
864 assert(path);
865 assert(homedir);
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
878 // Replace home macro
879 char *new_name = NULL;
880 if (strncmp(path, "${HOME}", 7) == 0) {
881 if (asprintf(&new_name, "%s%s", homedir, path + 7) == -1)
882 errExit("asprintf");
883 if(called_as_root)
884 EUID_ROOT();
885 return new_name;
886 }
887 else if (*path == '~') {
888 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
889 errExit("asprintf");
890 if(called_as_root)
891 EUID_ROOT();
892 return new_name;
893 }
894 else if (strncmp(path, "${CFG}", 6) == 0) {
895 if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1)
896 errExit("asprintf");
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 }
1014 }
1015
1016 char *rv = strdup(path);
1017 if (!rv)
1018 errExit("strdup");
1019
1020 if(called_as_root)
1021 EUID_ROOT();
1022
1023 return rv;
1024}
1025 729
1026 730
1027// Equivalent to the GNU version of basename, which is incompatible with 731// Equivalent to the GNU version of basename, which is incompatible with
@@ -1082,44 +786,6 @@ uid_t pid_get_uid(pid_t pid) {
1082} 786}
1083 787
1084 788
1085void invalid_filename(const char *fname, int globbing) {
1086// EUID_ASSERT();
1087 assert(fname);
1088 const char *ptr = fname;
1089
1090 if (strncmp(ptr, "${HOME}", 7) == 0)
1091 ptr = fname + 7;
1092 else if (strncmp(ptr, "${PATH}", 7) == 0)
1093 ptr = fname + 7;
1094 else if (strcmp(fname, "${DOWNLOADS}") == 0)
1095 return;
1096 else if (strcmp(fname, "${MUSIC}") == 0)
1097 return;
1098 else if (strcmp(fname, "${VIDEOS}") == 0)
1099 return;
1100 else if (strcmp(fname, "${PICTURES}") == 0)
1101 return;
1102 else if (strcmp(fname, "${DESKTOP}") == 0)
1103 return;
1104 else if (strcmp(fname, "${DOCUMENTS}") == 0)
1105 return;
1106
1107 int len = strlen(ptr);
1108
1109 if (globbing) {
1110 // file globbing ('*?[]') is allowed
1111 if (strcspn(ptr, "\\&!\"'<>%^(){};,") != (size_t)len) {
1112 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr);
1113 exit(1);
1114 }
1115 }
1116 else {
1117 if (strcspn(ptr, "\\&!?\"'<>%^(){};,*[]") != (size_t)len) {
1118 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", ptr);
1119 exit(1);
1120 }
1121 }
1122}
1123 789
1124 790
1125uid_t get_group_id(const char *group) { 791uid_t get_group_id(const char *group) {