From: Calin Crisan Date: Sun, 14 Aug 2016 18:12:34 +0000 (+0300) Subject: allow adding digest auth rtsp cameras (no credentials check though) X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=cdb070d767a8a979d448a7443a14536f14acb2d3;p=motioneye-debian allow adding digest auth rtsp cameras (no credentials check though) --- diff --git a/motioneye/utils.py b/motioneye/utils.py index 923901b..98a9dc5 100644 --- a/motioneye/utils.py +++ b/motioneye/utils.py @@ -430,35 +430,39 @@ def test_mjpeg_url(data, auth_modes, allow_jpeg, callback): def test_rtsp_url(data, callback): import config - data = dict(data) - data.setdefault('scheme', 'rtsp') - data.setdefault('host', '127.0.0.1') - data['port'] = data.get('port') or '554' - data.setdefault('path', '') - data.setdefault('username', None) - data.setdefault('password', None) + scheme = data.get('scheme', 'rtsp') + host = data.get('host', '127.0.0.1') + port = data.get('port') or '554' + path = data.get('path') or '' + username = data.get('username') + password = data.get('password') url = '%(scheme)s://%(host)s%(port)s%(path)s' % { - 'scheme': data['scheme'], - 'host': data['host'], - 'port': ':' + str(data['port']) if data['port'] else '', - 'path': data['path'] or ''} + 'scheme': scheme, + 'host': host, + 'port': (':' + port) if port else '', + 'path': path} called = [False] + send_auth = [False] timeout = [None] stream = None io_loop = IOLoop.instance() def connect(): - logging.debug('testing rtsp netcam at %s' % url) + if send_auth[0]: + logging.debug('testing rtsp netcam at %s (this time with credentials)' % url) + + else: + logging.debug('testing rtsp netcam at %s' % url) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) s.settimeout(settings.MJPG_CLIENT_TIMEOUT) stream = IOStream(s) stream.set_close_callback(on_close) - stream.connect((data['host'], int(data['port'])), on_connect) - + stream.connect((host, int(port)), on_connect) + timeout[0] = io_loop.add_timeout(datetime.timedelta(seconds=settings.MJPG_CLIENT_TIMEOUT), functools.partial(on_connect, _timeout=True)) @@ -481,8 +485,8 @@ def test_rtsp_url(data, callback): 'User-Agent: motionEye' ] - if data['username']: - auth_header = 'Authorization: ' + build_basic_header(data['username'], data['password']) + if username and send_auth[0]: + auth_header = 'Authorization: ' + build_basic_header(username, password) lines.append(auth_header) lines += [ @@ -507,13 +511,18 @@ def test_rtsp_url(data, callback): if data: if data.endswith('200 '): seek_server() - + elif data.endswith('401 '): - handle_error('authentication failed') + if not username or send_auth[0]: + # either credentials not supplied, or already sent + handle_error('authentication failed') + + else: + seek_www_authenticate() else: handle_error('rtsp netcam returned erroneous response: %s' % data) - + else: handle_error('timeout waiting for rtsp netcam response') @@ -537,6 +546,31 @@ def test_rtsp_url(data, callback): handle_success(identifier) + def seek_www_authenticate(): + if check_error(): + return + + stream.read_until_regex('WWW-Authenticate: .*', on_www_authenticate) + timeout[0] = io_loop.add_timeout(datetime.timedelta(seconds=1), on_www_authenticate) + + def on_www_authenticate(data=None): + io_loop.remove_timeout(timeout[0]) + + if data: + scheme = re.findall('WWW-Authenticate: ([^\s]+)', data)[0].strip() + logging.debug('rtsp netcam auth scheme: %s' % scheme) + if scheme.lower() == 'basic': + send_auth[0] = True + connect() + + else: + logging.debug('rtsp auth scheme digest not supported, considering credentials ok') + handle_success('(unknown) ') + + else: + logging.error('timeout waiting for rtsp auth scheme') + handle_error('timeout waiting for rtsp netcam response') + def on_close(): if called[0]: return