Skip to content

Commit 06b2e18

Browse files
committed
Security enhancements
- chroot support - privilege separation Signed-off-by: Scott R. Shinn <scott@atomicorp.com>
1 parent 39a9313 commit 06b2e18

2 files changed

Lines changed: 62 additions & 60 deletions

File tree

src/addagent/validate.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ char *OS_AddNewAgent(const char *name, const char *ip, const char *id)
109109
}
110110

111111
char authentication_file[2048 + 1];
112-
snprintf(authentication_file, 2048, "%s%s", DEFAULTDIR, AUTH_FILE);
112+
snprintf(authentication_file, 2048, "%s", AUTH_FILE);
113113

114114
fp = fopen(authentication_file, "a");
115115
if (!fp) {

src/os_auth/main-server.c

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,6 @@
2222
*
2323
*/
2424

25-
#ifndef LIBOPENSSL_ENABLED
26-
27-
#include <stdlib.h>
28-
#include <stdio.h>
29-
int main()
30-
{
31-
printf("ERROR: Not compiled. Missing OpenSSL support.\n");
32-
exit(0);
33-
}
34-
35-
#else
36-
3725
#include <sys/wait.h>
3826
#include "auth.h"
3927
#include "os_crypto/md5/md5_op.h"
@@ -161,11 +149,13 @@ int main(int argc, char **argv)
161149
int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0;
162150
int use_pass = 1;
163151
int run_foreground = 0;
152+
gid_t uid;
164153
gid_t gid;
165154
int client_sock = 0, sock = 0, portnum, ret = 0;
166155
char *port = DEFAULT_PORT;
167156
char *ciphers = DEFAULT_CIPHERS;
168157
const char *dir = DEFAULTDIR;
158+
const char *user = MAILUSER;
169159
const char *group = GROUPGLOBAL;
170160
const char *server_cert = NULL;
171161
const char *server_key = NULL;
@@ -191,7 +181,7 @@ int main(int argc, char **argv)
191181
/* Set the name */
192182
OS_SetName(ARGV0);
193183

194-
while ((c = getopt(argc, argv, "Vdhtfig:D:m:p:c:v:x:k:n")) != -1) {
184+
while ((c = getopt(argc, argv, "Vdhtfiu:g:D:m:p:c:v:x:k:n")) != -1) {
195185
switch (c) {
196186
case 'V':
197187
print_version();
@@ -205,6 +195,12 @@ int main(int argc, char **argv)
205195
case 'i':
206196
use_ip_address = 1;
207197
break;
198+
case 'u':
199+
if (!optarg) {
200+
ErrorExit("%s: -u needs an argument", ARGV0);
201+
}
202+
user = optarg;
203+
break;
208204
case 'g':
209205
if (!optarg) {
210206
ErrorExit("%s: -g needs an argument", ARGV0);
@@ -266,56 +262,52 @@ int main(int argc, char **argv)
266262
}
267263
}
268264

269-
/* Start daemon -- NB: need to double fork and setsid */
270-
debug1(STARTED_MSG, ARGV0);
265+
if (chdir(dir) == -1) {
266+
ErrorExit(CHDIR_ERROR, ARGV0, dir, errno, strerror(errno));
267+
}
268+
269+
/* Exit here if test config is set */
270+
if (test_config) {
271+
exit(0);
272+
}
273+
271274

272275
/* Check if the user/group given are valid */
276+
uid = Privsep_GetUser(user);
273277
gid = Privsep_GetGroup(group);
274-
if (gid == (gid_t) - 1) {
275-
ErrorExit(USER_ERROR, ARGV0, "", group);
278+
if (uid == (uid_t) - 1 || gid == (gid_t) - 1) {
279+
ErrorExit(USER_ERROR, ARGV0, user, group);
276280
}
277281

282+
278283
if (!run_foreground) {
279284
nowDaemon();
280285
goDaemon();
281286
}
282287

283-
/* Create PID files */
284-
if (CreatePID(ARGV0, getpid()) < 0) {
285-
ErrorExit(PID_ERROR, ARGV0);
286-
}
287288

288-
/* Exit here if test config is set */
289-
if (test_config) {
290-
exit(0);
291-
}
292-
293-
/* Privilege separation */
294-
if (Privsep_SetGroup(gid) < 0) {
295-
ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
296-
}
297-
298-
/* chroot -- TODO: this isn't a chroot. Should also close
299-
* unneeded open file descriptors (like stdin/stdout)
300-
*/
301-
if (chdir(dir) == -1) {
302-
ErrorExit(CHDIR_ERROR, ARGV0, dir, errno, strerror(errno));
303-
}
304289

305290
/* Signal manipulation */
306291
StartSIG(ARGV0);
307292

308-
309293
/* Create PID files */
310294
if (CreatePID(ARGV0, getpid()) < 0) {
311-
ErrorExit(PID_ERROR, ARGV0);
295+
ErrorExit(PID_ERROR, ARGV0);
312296
}
313297

314298
atexit(cleanup);
315299

316-
/* Start up message */
317300
verbose(STARTUP_MSG, ARGV0, (int)getpid());
318301

302+
303+
/* load keys */
304+
fp = fopen(KEYSFILE_PATH, "a");
305+
if (!fp) {
306+
merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
307+
exit(1);
308+
}
309+
fclose(fp);
310+
319311
if (use_pass) {
320312

321313
/* Checking if there is a custom password file */
@@ -345,16 +337,12 @@ int main(int argc, char **argv)
345337
verbose("Accepting connections. No password required (not recommended)");
346338
}
347339

348-
/* Getting SSL cert. */
349340

350-
fp = fopen(KEYSFILE_PATH, "a");
351-
if (!fp) {
352-
merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
353-
exit(1);
354-
}
355-
fclose(fp);
341+
/* Setup random */
342+
srandom_init();
356343

357344
/* Start SSL */
345+
/* Getting SSL cert. */
358346
ctx = os_ssl_keys(1, dir, ciphers, server_cert, server_key, ca_cert);
359347
if (!ctx) {
360348
merror("%s: ERROR: SSL error. Exiting.", ARGV0);
@@ -368,22 +356,35 @@ int main(int argc, char **argv)
368356
exit(1);
369357
}
370358

371-
/* initialize select() save area */
372-
fdsave = netinfo->fdset;
373-
fdmax = netinfo->fdmax; /* value preset to max fd + 1 */
359+
/* Privilege separation */
360+
if (Privsep_SetGroup(gid) < 0) {
361+
ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
362+
}
374363

375-
debug1("%s: DEBUG: Going into listening mode.", ARGV0);
364+
/* Chroot to the specified directory */
365+
if (Privsep_Chroot(dir) < 0) {
366+
ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
367+
}
376368

377-
/* Setup random */
378-
srandom_init();
369+
if (Privsep_SetUser(uid) < 0) {
370+
ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
371+
}
379372

380-
/* Chroot */
381-
/*
382-
if (Privsep_Chroot(dir) < 0)
383-
ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
384373

374+
/* Log that we are now in the chrooted environment */
385375
nowChroot();
386-
*/
376+
377+
/* Change working directory to / within the chroot */
378+
if (chdir("/") < 0) {
379+
ErrorExit(CHDIR_ERROR, ARGV0, "/", errno, strerror(errno));
380+
}
381+
382+
383+
/* initialize select() save area */
384+
fdsave = netinfo->fdset;
385+
fdmax = netinfo->fdmax; /* value preset to max fd + 1 */
386+
387+
debug1("%s: DEBUG: Going into listening mode.", ARGV0);
387388

388389
while (1) {
389390
/* No need to completely pin the cpu, 100ms should be fast enough */
@@ -555,6 +556,8 @@ int main(int argc, char **argv)
555556
finalkey = OS_AddNewAgent(agentname, NULL, NULL);
556557
}
557558
if (!finalkey) {
559+
merror("%s: ERROR: Unable to add agent: %s (internal error - debug check paths and files)", ARGV0, agentname);
560+
558561
merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname);
559562
snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname);
560563
SSL_write(ssl, response, strlen(response));
@@ -598,4 +601,3 @@ int main(int argc, char **argv)
598601
static void cleanup() {
599602
DeletePID(ARGV0);
600603
}
601-
#endif /* LIBOPENSSL_ENABLED */

0 commit comments

Comments
 (0)