File: TCTcpcryptController.m

package info (click to toggle)
tcpcrypt 0.3~rc1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,292 kB
  • ctags: 1,285
  • sloc: ansic: 11,305; asm: 482; sh: 192; objc: 149; makefile: 98
file content (135 lines) | stat: -rw-r--r-- 3,725 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#import "TCTcpcryptController.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>

@interface TCTcpcryptController ()
- (BOOL)daemonIsRunning;
- (NSString *)daemonStatus;
- (void)refreshDaemonStatus;
- (void)checkPermissions;
@end

@implementation TCTcpcryptController

////////////////////////////////////////////////////////////////////////////////////////
#pragma mark NSObject

- (id)init {
	if ((self = [super init])) {
		_wrapperPath = [[[NSBundle mainBundle] pathForResource:@"tcpcryptd_wrapper" ofType:@""] retain];
		_tcpcryptdPath = [[[NSBundle mainBundle] pathForResource:@"tcpcryptd" ofType:@""] retain];
	}
	return self;
}

- (void)dealloc {
	[self stopDaemon:nil];
	[_wrapperPath release];
	[_tcpcryptdPath release];
	[super dealloc];
}

#pragma mark NSWindowDelegate

- (void)windowWillClose:(NSNotification *)notification {
	[self stopDaemon:nil];
	[[NSApplication sharedApplication] terminate:nil];
}

#pragma mark -

- (void)fixPermissionsForFile:(NSString *)path_ setUIDRoot:(BOOL)setUIDRoot {
	int fd, ret;
	mode_t mode;
	struct stat st;
	const char *path = [path_ cStringUsingEncoding:NSUTF8StringEncoding];
	AuthorizationRef authRef;
	OSStatus status;
	
	fd = open(path, O_NOFOLLOW);
	NSAssert(fd != -1, @"open(%s)", path);

	ret = fstat(fd, &st);
	NSAssert(ret != -1, @"fstat(%s)", path);
	
	// chmod
	mode = 0755 | S_IFREG;
	if (setUIDRoot) mode = mode | S_ISUID;
	if (st.st_mode != mode) {
		NSLog(@"%@ is 0%o, will set to 0%o", path_, st.st_mode, mode);
		if (st.st_uid == 0) {
			NSLog(@"lost perms but kept root ownership of %@", path_);
		}
		ret = fchmod(fd, mode);
		NSAssert(ret != -1, @"fchmod()");
	}
	
	// chown root
	if (st.st_uid != 0) {
		const char *args[] = {"root", path, NULL};
		status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
									 kAuthorizationFlagDefaults, &authRef);
		status = AuthorizationExecuteWithPrivileges(authRef, "/usr/sbin/chown", kAuthorizationFlagDefaults,
													  (char *const *)args, NULL);
		NSAssert(status != -1, @"chown");
	}
	
	close(fd);
}

- (void)checkPermissions {
	[self fixPermissionsForFile:_wrapperPath setUIDRoot:YES];
	[self fixPermissionsForFile:_tcpcryptdPath setUIDRoot:NO];
}

- (IBAction)startDaemon:(id)sender {
	NSLog(@"starting tcpcryptd...");
	NSAssert(![self daemonIsRunning], @"tcpcryptd already started");
	
	[self checkPermissions];
	usleep(50000); /* file perms weren't getting set? */
	_daemon = [[NSTask launchedTaskWithLaunchPath:_wrapperPath 
									   arguments:[NSArray arrayWithObject:@"start"]] retain];
	NSLog(@"started tcpcryptd, pid %u", [_daemon processIdentifier]);
	NSAssert([self daemonIsRunning], @"failed to start tcpcryptd");
	[self refreshDaemonStatus];
}

- (IBAction)stopDaemon:(id)sender {
	NSLog(@"stopping tcpcryptd...");
	
	NSTask *stopper = [NSTask launchedTaskWithLaunchPath:_wrapperPath 
											   arguments:[NSArray arrayWithObject:@"stop"]];
	
	[stopper waitUntilExit];
	NSLog(@"stopped tcpcryptd");
	NSAssert(![self daemonIsRunning], @"failed to stop tcpcryptd");
	if (_daemon) {
		[_daemon release];
		_daemon = nil;
	}
	[self refreshDaemonStatus];
}

- (BOOL)daemonIsRunning {
	return _daemon && [_daemon isRunning];
}

- (NSString *)daemonStatus {
	return [self daemonIsRunning] ? @"Tcpcrypt is running on ports 80 (http) and 7777." :
								    @"Tcpcrypt is off.";
}

- (void)refreshDaemonStatus {
	[_startButton setHidden:[self daemonIsRunning]];
	[_stopButton setHidden:![self daemonIsRunning]];
	[_testButton setHidden:![self daemonIsRunning]];
	[_statusLabel setStringValue:[self daemonStatus]];
}

- (IBAction)openTestPage:(id)sender {
	[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://tcpcrypt.org/fame.php"]];
}

@end