mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-04 07:19:59 +00:00
bbf6d9b026
Bugfix for feeds - removed categories related and up - load new books now working - category random now working login page is free of non accessible elements boolean custom column is vivible in UI books with only with certain languages can be shown book shelfs can be deleted from UI Anonymous user view is more resticted Added browse of series in sidebar Dependencys in vendor folder are updated to newer versions (licencs files are now present) Bugfix editing Authors names Made upload on windows working
116 lines
4.4 KiB
Python
116 lines
4.4 KiB
Python
"""
|
|
NTLM authenticating pool, contributed by erikcederstran
|
|
|
|
Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
|
|
"""
|
|
from __future__ import absolute_import
|
|
|
|
try:
|
|
from http.client import HTTPSConnection
|
|
except ImportError:
|
|
from httplib import HTTPSConnection
|
|
from logging import getLogger
|
|
from ntlm import ntlm
|
|
|
|
from urllib3 import HTTPSConnectionPool
|
|
|
|
|
|
log = getLogger(__name__)
|
|
|
|
|
|
class NTLMConnectionPool(HTTPSConnectionPool):
|
|
"""
|
|
Implements an NTLM authentication version of an urllib3 connection pool
|
|
"""
|
|
|
|
scheme = 'https'
|
|
|
|
def __init__(self, user, pw, authurl, *args, **kwargs):
|
|
"""
|
|
authurl is a random URL on the server that is protected by NTLM.
|
|
user is the Windows user, probably in the DOMAIN\\username format.
|
|
pw is the password for the user.
|
|
"""
|
|
super(NTLMConnectionPool, self).__init__(*args, **kwargs)
|
|
self.authurl = authurl
|
|
self.rawuser = user
|
|
user_parts = user.split('\\', 1)
|
|
self.domain = user_parts[0].upper()
|
|
self.user = user_parts[1]
|
|
self.pw = pw
|
|
|
|
def _new_conn(self):
|
|
# Performs the NTLM handshake that secures the connection. The socket
|
|
# must be kept open while requests are performed.
|
|
self.num_connections += 1
|
|
log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s',
|
|
self.num_connections, self.host, self.authurl)
|
|
|
|
headers = {}
|
|
headers['Connection'] = 'Keep-Alive'
|
|
req_header = 'Authorization'
|
|
resp_header = 'www-authenticate'
|
|
|
|
conn = HTTPSConnection(host=self.host, port=self.port)
|
|
|
|
# Send negotiation message
|
|
headers[req_header] = (
|
|
'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser))
|
|
log.debug('Request headers: %s', headers)
|
|
conn.request('GET', self.authurl, None, headers)
|
|
res = conn.getresponse()
|
|
reshdr = dict(res.getheaders())
|
|
log.debug('Response status: %s %s', res.status, res.reason)
|
|
log.debug('Response headers: %s', reshdr)
|
|
log.debug('Response data: %s [...]', res.read(100))
|
|
|
|
# Remove the reference to the socket, so that it can not be closed by
|
|
# the response object (we want to keep the socket open)
|
|
res.fp = None
|
|
|
|
# Server should respond with a challenge message
|
|
auth_header_values = reshdr[resp_header].split(', ')
|
|
auth_header_value = None
|
|
for s in auth_header_values:
|
|
if s[:5] == 'NTLM ':
|
|
auth_header_value = s[5:]
|
|
if auth_header_value is None:
|
|
raise Exception('Unexpected %s response header: %s' %
|
|
(resp_header, reshdr[resp_header]))
|
|
|
|
# Send authentication message
|
|
ServerChallenge, NegotiateFlags = \
|
|
ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value)
|
|
auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge,
|
|
self.user,
|
|
self.domain,
|
|
self.pw,
|
|
NegotiateFlags)
|
|
headers[req_header] = 'NTLM %s' % auth_msg
|
|
log.debug('Request headers: %s', headers)
|
|
conn.request('GET', self.authurl, None, headers)
|
|
res = conn.getresponse()
|
|
log.debug('Response status: %s %s', res.status, res.reason)
|
|
log.debug('Response headers: %s', dict(res.getheaders()))
|
|
log.debug('Response data: %s [...]', res.read()[:100])
|
|
if res.status != 200:
|
|
if res.status == 401:
|
|
raise Exception('Server rejected request: wrong '
|
|
'username or password')
|
|
raise Exception('Wrong server response: %s %s' %
|
|
(res.status, res.reason))
|
|
|
|
res.fp = None
|
|
log.debug('Connection established')
|
|
return conn
|
|
|
|
def urlopen(self, method, url, body=None, headers=None, retries=3,
|
|
redirect=True, assert_same_host=True):
|
|
if headers is None:
|
|
headers = {}
|
|
headers['Connection'] = 'Keep-Alive'
|
|
return super(NTLMConnectionPool, self).urlopen(method, url, body,
|
|
headers, retries,
|
|
redirect,
|
|
assert_same_host)
|