1import logging
2
3
4class Proxy(object):
5
6    def __init__(self, config):
7        self.config = config
8        self.controller = None
9
10        self.host = config.get('host', '127.0.0.1')
11        self.port = config.get('port', 'default')
12
13        self.cookie_backup = None
14
15    def address(self):
16
17        #####
18        # Proxy configuration
19        from contextlib import closing
20        from socks import socksocket
21        from socket import AF_INET, SOCK_STREAM
22
23        try:
24            if self.port == 'default':
25                with closing(socksocket(AF_INET, SOCK_STREAM)) as sock:
26                    if sock.connect_ex((self.host, 9050)) == 0:
27                        self.port = 9050
28
29            if self.port == 'default':
30                with closing(socksocket(AF_INET, SOCK_STREAM)) as sock:
31                    if sock.connect_ex((self.host, 9150)) == 0:
32                        self.port = 9150
33
34            if self.port == 'default':
35                return None
36            else:
37                return '{}:{}'.format(self.host, self.port)
38
39        except:
40            return None
41
42    def assure_cookie(self, host, cookie):
43
44        from controller import create_controller
45        boxLog = logging.getLogger('theonionbox')
46
47        if host is None or cookie is None:
48            return True
49
50        if self.controller is None:
51            try:
52                self.controller = create_controller(self.config, None, None)
53            except:
54                boxLog.debug('Failed to create controller.')
55                return False
56
57        if self.controller.is_authenticated() is False:
58            try:
59                self.controller.authenticate()
60            except Exception as exc:
61                boxLog.debug('Failed to authenticate.')
62                return False
63
64        if self.cookie_backup is None:
65            self.cookie_backup = self.controller.get_conf('HidServAuth', default=[], multiple=True)
66
67        try:
68            self.controller.set_conf('HidServAuth', '{} {}'.format(host, cookie))
69        except:
70            boxLog.debug('Failed to set Hidden Service Authentication cookie.')
71            return False
72
73        try:
74            check = self.controller.get_conf('HidServAuth', default=[], multiple=True)
75        except:
76            boxLog.debug('Failed to confirm Hidden Service Authentication cookie.')
77            return False
78
79        ok = False
80        for cookie_line in check:
81            cl = cookie_line.split(" ")
82            if len(cl) == 2:
83                if cl[0] == host and cl[1] == cookie:
84                    ok = True
85                    break
86
87        boxLog.debug('Hidden Service Authentication cookie {}.'.format('confirmed' if ok is True else 'missing'))
88        return ok
89
90    def shutdown(self):
91        boxLog = logging.getLogger('theonionbox')
92        if self.controller is not None:
93
94            if self.controller.is_alive() is False:
95                self.controller.connect()
96            if self.controller.is_authenticated() is True:
97                self.controller.reset_conf('HidServAuth')
98                if len(self.cookie_backup) > 0:
99                    for cookie_line in self.cookie_backup:
100                        boxLog.debug('Restoring Hidden Service Authentication cookie.')
101                        self.controller.set_conf('HidServAuth', cookie_line)
102            else:
103                boxLog.debug('Failed to authenticate controller.')
104
105            boxLog.debug('Closing controller.')
106            self.controller.close()
107