comparison sat/plugins/plugin_misc_nat-port.py @ 3028:ab2696e34d29

Python 3 port: /!\ this is a huge commit /!\ starting from this commit, SàT is needs Python 3.6+ /!\ SàT maybe be instable or some feature may not work anymore, this will improve with time This patch port backend, bridge and frontends to Python 3. Roughly this has been done this way: - 2to3 tools has been applied (with python 3.7) - all references to python2 have been replaced with python3 (notably shebangs) - fixed files not handled by 2to3 (notably the shell script) - several manual fixes - fixed issues reported by Python 3 that where not handled in Python 2 - replaced "async" with "async_" when needed (it's a reserved word from Python 3.7) - replaced zope's "implements" with @implementer decorator - temporary hack to handle data pickled in database, as str or bytes may be returned, to be checked later - fixed hash comparison for password - removed some code which is not needed anymore with Python 3 - deactivated some code which needs to be checked (notably certificate validation) - tested with jp, fixed reported issues until some basic commands worked - ported Primitivus (after porting dependencies like urwid satext) - more manual fixes
author Goffi <goffi@goffi.org>
date Tue, 13 Aug 2019 19:08:41 +0200
parents 003b8b4b56a7
children 9d0df638c8b4
comparison
equal deleted inserted replaced
3027:ff5bcb12ae60 3028:ab2696e34d29
1 #!/usr/bin/env python2 1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 # SAT plugin for NAT port mapping 4 # SAT plugin for NAT port mapping
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
6 6
30 30
31 try: 31 try:
32 import miniupnpc 32 import miniupnpc
33 except ImportError: 33 except ImportError:
34 raise exceptions.MissingModule( 34 raise exceptions.MissingModule(
35 u"Missing module MiniUPnPc, please download/install it (and its Python binding) at http://miniupnp.free.fr/ (or use pip install miniupnpc)" 35 "Missing module MiniUPnPc, please download/install it (and its Python binding) at http://miniupnp.free.fr/ (or use pip install miniupnpc)"
36 ) 36 )
37 37
38 38
39 PLUGIN_INFO = { 39 PLUGIN_INFO = {
40 C.PI_NAME: "NAT port mapping", 40 C.PI_NAME: "NAT port mapping",
45 C.PI_DESCRIPTION: _("""Automatic NAT port mapping using UPnP"""), 45 C.PI_DESCRIPTION: _("""Automatic NAT port mapping using UPnP"""),
46 } 46 }
47 47
48 STARTING_PORT = 6000 # starting point to automatically find a port 48 STARTING_PORT = 6000 # starting point to automatically find a port
49 DEFAULT_DESC = ( 49 DEFAULT_DESC = (
50 u"SaT port mapping" 50 "SaT port mapping"
51 ) # we don't use "à" here as some bugged NAT don't manage charset correctly 51 ) # we don't use "à" here as some bugged NAT don't manage charset correctly
52 52
53 53
54 class MappingError(Exception): 54 class MappingError(Exception):
55 pass 55 pass
72 discover_d.chainDeferred(self._initialised) 72 discover_d.chainDeferred(self._initialised)
73 self._initialised.addErrback(self._init_failed) 73 self._initialised.addErrback(self._init_failed)
74 74
75 def unload(self): 75 def unload(self):
76 if self._to_unmap: 76 if self._to_unmap:
77 log.info(u"Cleaning mapped ports") 77 log.info("Cleaning mapped ports")
78 return threads.deferToThread(self._unmapPortsBlocking) 78 return threads.deferToThread(self._unmapPortsBlocking)
79 79
80 def _init_failed(self, failure_): 80 def _init_failed(self, failure_):
81 e = failure_.trap(exceptions.NotFound, exceptions.FeatureNotFound) 81 e = failure_.trap(exceptions.NotFound, exceptions.FeatureNotFound)
82 if e == exceptions.FeatureNotFound: 82 if e == exceptions.FeatureNotFound:
83 log.info(u"UPnP-IGD seems to be not activated on the device") 83 log.info("UPnP-IGD seems to be not activated on the device")
84 else: 84 else:
85 log.info(u"UPnP-IGD not available") 85 log.info("UPnP-IGD not available")
86 self._upnp = None 86 self._upnp = None
87 87
88 def _discover(self): 88 def _discover(self):
89 devices = self._upnp.discover() 89 devices = self._upnp.discover()
90 if devices: 90 if devices:
91 log.info(u"{nb} UPnP-IGD device(s) found".format(nb=devices)) 91 log.info("{nb} UPnP-IGD device(s) found".format(nb=devices))
92 else: 92 else:
93 log.info(u"Can't find UPnP-IGD device on the local network") 93 log.info("Can't find UPnP-IGD device on the local network")
94 raise failure.Failure(exceptions.NotFound()) 94 raise failure.Failure(exceptions.NotFound())
95 self._upnp.selectigd() 95 self._upnp.selectigd()
96 try: 96 try:
97 self._external_ip = self._upnp.externalipaddress() 97 self._external_ip = self._upnp.externalipaddress()
98 except Exception: 98 except Exception:
117 def _unmapPortsBlocking(self): 117 def _unmapPortsBlocking(self):
118 """Unmap ports mapped in this session""" 118 """Unmap ports mapped in this session"""
119 self._mutex.acquire() 119 self._mutex.acquire()
120 try: 120 try:
121 for port, protocol in self._to_unmap: 121 for port, protocol in self._to_unmap:
122 log.info(u"Unmapping port {}".format(port)) 122 log.info("Unmapping port {}".format(port))
123 unmapping = self._upnp.deleteportmapping( 123 unmapping = self._upnp.deleteportmapping(
124 # the last parameter is remoteHost, we don't use it 124 # the last parameter is remoteHost, we don't use it
125 port, 125 port,
126 protocol, 126 protocol,
127 "", 127 "",
128 ) 128 )
129 129
130 if not unmapping: 130 if not unmapping:
131 log.error( 131 log.error(
132 u"Can't unmap port {port} ({protocol})".format( 132 "Can't unmap port {port} ({protocol})".format(
133 port=port, protocol=protocol 133 port=port, protocol=protocol
134 ) 134 )
135 ) 135 )
136 del self._to_unmap[:] 136 del self._to_unmap[:]
137 finally: 137 finally:
172 int_port, 172 int_port,
173 desc, 173 desc,
174 "", 174 "",
175 ) 175 )
176 except Exception as e: 176 except Exception as e:
177 log.error(_(u"addportmapping error: {msg}").format(msg=e)) 177 log.error(_("addportmapping error: {msg}").format(msg=e))
178 raise failure.Failure(MappingError()) 178 raise failure.Failure(MappingError())
179 179
180 if not mapping: 180 if not mapping:
181 raise failure.Failure(MappingError()) 181 raise failure.Failure(MappingError())
182 else: 182 else:
199 if self._upnp is None: 199 if self._upnp is None:
200 return defer.succeed(None) 200 return defer.succeed(None)
201 201
202 def mappingCb(ext_port): 202 def mappingCb(ext_port):
203 log.info( 203 log.info(
204 u"{protocol} mapping from {int_port} to {ext_port} successful".format( 204 "{protocol} mapping from {int_port} to {ext_port} successful".format(
205 protocol=protocol, int_port=int_port, ext_port=ext_port 205 protocol=protocol, int_port=int_port, ext_port=ext_port
206 ) 206 )
207 ) 207 )
208 return ext_port 208 return ext_port
209 209
210 def mappingEb(failure_): 210 def mappingEb(failure_):
211 failure_.trap(MappingError) 211 failure_.trap(MappingError)
212 log.warning(u"Can't map internal {int_port}".format(int_port=int_port)) 212 log.warning("Can't map internal {int_port}".format(int_port=int_port))
213 213
214 def mappingUnknownEb(failure_): 214 def mappingUnknownEb(failure_):
215 log.error(_(u"error while trying to map ports: {msg}").format(msg=failure_)) 215 log.error(_("error while trying to map ports: {msg}").format(msg=failure_))
216 216
217 d = threads.deferToThread( 217 d = threads.deferToThread(
218 self._mapPortBlocking, int_port, ext_port, protocol, desc 218 self._mapPortBlocking, int_port, ext_port, protocol, desc
219 ) 219 )
220 d.addCallbacks(mappingCb, mappingEb) 220 d.addCallbacks(mappingCb, mappingEb)