40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
#define options \
o('l',lower,mode = lower) \
o('m',mix,mode = mix) \
o('u',upper,mode = upper)\
_cl_opt
enum /* constants */ {
null = 0, true = 1, false = 0
};
typedef enum bad {
ok = 0,
fail = 1,
bad_user,
bad_option,
bad_syntax,
bad_entropy,
bad_copy,
bad_usage = 64, /* fleabsd idiom */
} bad;
typedef _Bool bool;
typedef unsigned long long iaia_word_type;
typedef bad iaia_error_type;
enum /* iaia errors */ {
iaia_e_ok = ok,
iaia_e_base = fail,
iaia_e_domain = fail,
iaia_e_overflow = fail,
................................................................................
#ifdef _CLIPBOARD
char* const* cbd_cmds[] = {
/* NOTE: these commands must be specified in order of
* most- to least-specific. more than one utility may
* be present on a given system, so we need to make sure
* the right one is called. */
(char* const[]){"termux-clipboard-set", null},
(char* const[]){"xsel", "-bi", null},
/* TODO: allow command to be specified by env var */
null
};
#endif
int main(int argc, const char** argv) {
if (argc == 0) return -1;
if (argc == 1) {
size_t namelen = strlen(argv[0]);
say("\x1b[1musage:\x1b[m ");
................................................................................
unsigned long long len, q = 1;
bool gotlen = false;
bool gotq = false;
# ifdef _CLIPBOARD
bool copy = true;
# endif
for (const char** arg = argv; *arg != null; ++arg) {
if ((*arg)[0] == '-') {
if ((*arg)[1] == '-') { /* long opt */
unsigned char a;
if (tblget(sz(argtbl), argtbl, *arg + 2, &a) == ok) switch (a) {
# define o(short, long, code) case arg_##long:code;break;
options
# undef o
................................................................................
}
if (!gotlen) return bad_syntax;
# ifdef _CLIPBOARD
if (geteuid() == 0 && copy) {
/* on a sane system, what we'd do is hike up the process
* tree til we found a non-root user. alas, this is UNIX. */
const char* realuser = getenv("SUDO_USER");
if (realuser == null) realuser = "nobody";
say("\x1b[1;33mwarning:\x1b[m you are running \x1b[4m");
size_t namelen = strlen(argv[0]);
write(2,argv[0],namelen);
say("\x1b[24m as \x1b[1mroot\x1b[m! dropping to \x1b[1m");
write(2,realuser,strlen(realuser));
setenv("USER", realuser, true);
say("\x1b[m to prevent malicious behavior\n");
struct passwd* nobody = getpwnam(realuser);
if (nobody == null) {
say("\x1b[1;31mfatal:\x1b[m could not get UID to drop privileges; bailing");
return bad_user;
} else {
setenv("HOME", nobody -> pw_dir, true);
setenv("SHELL", "/dev/null", true);
setuid(nobody -> pw_uid);
if (geteuid() == 0)
say("\x1b[1;31mnice try:\x1b[m i don't fucking think so, you sneaky bastard");
}
}
# endif
................................................................................
char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg");
// FIXME: allow multiple args
int fds[2];
if (pipe(fds) != 0) return 63;
if (!fork()) {
close(fds[1]);
dup2(fds[0], 0);
if (clipboard_env != null) {
execvp(clipboard_env, (char* const[]){
clipboard_env, clipboard_env_arg, null});
return bad_copy;
} else for(char* const** cmd = cbd_cmds; *cmd != null; ++cmd) {
execvp((*cmd)[0], *cmd);
}
return bad_copy; /* exec failed */
} else {
close(fds[0]);
write(fds[1], buf, len);
write(fds[1], "\n", 1);
|
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
#define options \
o('l',lower,mode = lower) \
o('m',mix,mode = mix) \
o('u',upper,mode = upper)\
_cl_opt
typedef enum bad {
ok = 0,
fail = 1,
bad_user,
bad_option,
bad_syntax,
bad_entropy,
bad_copy,
bad_usage = 64, /* fleabsd idiom */
} bad;
typedef unsigned long long iaia_word_type;
typedef bad iaia_error_type;
enum /* iaia errors */ {
iaia_e_ok = ok,
iaia_e_base = fail,
iaia_e_domain = fail,
iaia_e_overflow = fail,
................................................................................
#ifdef _CLIPBOARD
char* const* cbd_cmds[] = {
/* NOTE: these commands must be specified in order of
* most- to least-specific. more than one utility may
* be present on a given system, so we need to make sure
* the right one is called. */
(char* const[]){"termux-clipboard-set", nullptr},
(char* const[]){"xsel", "-bi", nullptr},
/* TODO: allow command to be specified by env var */
nullptr
};
#endif
int main(int argc, const char** argv) {
if (argc == 0) return -1;
if (argc == 1) {
size_t namelen = strlen(argv[0]);
say("\x1b[1musage:\x1b[m ");
................................................................................
unsigned long long len, q = 1;
bool gotlen = false;
bool gotq = false;
# ifdef _CLIPBOARD
bool copy = true;
# endif
for (const char** arg = argv; *arg != nullptr; ++arg) {
if ((*arg)[0] == '-') {
if ((*arg)[1] == '-') { /* long opt */
unsigned char a;
if (tblget(sz(argtbl), argtbl, *arg + 2, &a) == ok) switch (a) {
# define o(short, long, code) case arg_##long:code;break;
options
# undef o
................................................................................
}
if (!gotlen) return bad_syntax;
# ifdef _CLIPBOARD
if (geteuid() == 0 && copy) {
/* on a sane system, what we'd do is hike up the process
* tree til we found a non-root user. alas, this is UNIX. */
const char* realuser = getenv("SUDO_USER");
if (realuser == nullptr) realuser = "nobody";
say("\x1b[1;33mwarning:\x1b[m you are running \x1b[4m");
size_t namelen = strlen(argv[0]);
write(2,argv[0],namelen);
say("\x1b[24m as \x1b[1mroot\x1b[m! dropping to \x1b[1m");
write(2,realuser,strlen(realuser));
setenv("USER", realuser, true);
say("\x1b[m to prevent malicious behavior\n");
struct passwd* nobody = getpwnam(realuser);
if (nobody == nullptr) {
say("\x1b[1;31mfatal:\x1b[m could not get UID to drop privileges; bailing");
return bad_user;
} else {
setenv("HOME", nobody -> pw_dir, true);
setenv("SHELL", "/dev/nullptr", true);
setuid(nobody -> pw_uid);
if (geteuid() == 0)
say("\x1b[1;31mnice try:\x1b[m i don't fucking think so, you sneaky bastard");
}
}
# endif
................................................................................
char* const clipboard_env_arg = getenv("mkpw_clipboard_setter_arg");
// FIXME: allow multiple args
int fds[2];
if (pipe(fds) != 0) return 63;
if (!fork()) {
close(fds[1]);
dup2(fds[0], 0);
if (clipboard_env != nullptr) {
execvp(clipboard_env, (char* const[]){
clipboard_env, clipboard_env_arg, nullptr});
return bad_copy;
} else for(char* const** cmd = cbd_cmds; *cmd != nullptr; ++cmd) {
execvp((*cmd)[0], *cmd);
}
return bad_copy; /* exec failed */
} else {
close(fds[0]);
write(fds[1], buf, len);
write(fds[1], "\n", 1);
|