示例#1
0
def _build_opener(apiurl):
    from osc.core import __version__
    global config
    if 'last_opener' not in _build_opener.__dict__:
        _build_opener.last_opener = (None, None)
    if apiurl == _build_opener.last_opener[0]:
        return _build_opener.last_opener[1]

    # respect no_proxy env variable
    if proxy_bypass(apiurl):
        # initialize with empty dict
        proxyhandler = ProxyHandler({})
    else:
        # read proxies from env
        proxyhandler = ProxyHandler()

    # workaround for http://bugs.python.org/issue9639
    authhandler_class = HTTPBasicAuthHandler
    if sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 1) \
        and not 'reset_retry_count' in dir(HTTPBasicAuthHandler):
        print('warning: your urllib2 version seems to be broken. ' \
            'Using a workaround for http://bugs.python.org/issue9639', file=sys.stderr)

        class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
            def http_error_401(self, *args):
                response = HTTPBasicAuthHandler.http_error_401(self, *args)
                self.retried = 0
                return response

            def http_error_404(self, *args):
                self.retried = 0
                return None

        authhandler_class = OscHTTPBasicAuthHandler
    elif sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 1):

        class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
            def http_error_404(self, *args):
                self.reset_retry_count()
                return None

        authhandler_class = OscHTTPBasicAuthHandler
    elif sys.version_info >= (2, 6, 5) and sys.version_info < (2, 6, 6):
        # workaround for broken urllib2 in python 2.6.5: wrong credentials
        # lead to an infinite recursion
        class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler):
            def retry_http_basic_auth(self, host, req, realm):
                # don't retry if auth failed
                if req.get_header(self.auth_header, None) is not None:
                    return None
                return HTTPBasicAuthHandler.retry_http_basic_auth(
                    self, host, req, realm)

        authhandler_class = OscHTTPBasicAuthHandler

    options = config['api_host_options'][apiurl]
    # with None as first argument, it will always use this username/password
    # combination for urls for which arg2 (apisrv) is a super-url
    authhandler = authhandler_class( \
        HTTPPasswordMgrWithDefaultRealm())
    authhandler.add_password(None, apiurl, options['user'], options['pass'])

    if options['sslcertck']:
        try:
            from . import oscssl
            from M2Crypto import m2urllib2
        except ImportError as e:
            print(e)
            raise NoSecureSSLError(
                'M2Crypto is needed to access %s in a secure way.\nPlease install python-m2crypto.'
                % apiurl)

        cafile = options.get('cafile', None)
        capath = options.get('capath', None)
        if not cafile and not capath:
            for i in ['/etc/pki/tls/cert.pem', '/etc/ssl/certs']:
                if os.path.isfile(i):
                    cafile = i
                    break
                elif os.path.isdir(i):
                    capath = i
                    break
        if not cafile and not capath:
            raise oscerr.OscIOError(None, 'No CA certificates found')
        ctx = oscssl.mySSLContext()
        if ctx.load_verify_locations(capath=capath, cafile=cafile) != 1:
            raise oscerr.OscIOError(None, 'No CA certificates found')
        opener = m2urllib2.build_opener(
            ctx, oscssl.myHTTPSHandler(ssl_context=ctx, appname='osc'),
            HTTPCookieProcessor(cookiejar), authhandler, proxyhandler)
    else:
        handlers = [HTTPCookieProcessor(cookiejar), authhandler, proxyhandler]
        try:
            # disable ssl cert check in python >= 2.7.9
            ctx = ssl._create_unverified_context()
            handlers.append(HTTPSHandler(context=ctx))
        except AttributeError:
            pass
        print(
            "WARNING: SSL certificate checks disabled. Connection is insecure!\n",
            file=sys.stderr)
        opener = build_opener(*handlers)
    opener.addheaders = [('User-agent', 'osc/%s' % __version__)]
    _build_opener.last_opener = (apiurl, opener)
    return opener
示例#2
0
def _build_opener(apiurl):
    from osc.core import __version__
    global config

    class OscHTTPBasicAuthHandler(HTTPBasicAuthHandler, object):
        # python2: inherit from object in order to make it a new-style class
        # (HTTPBasicAuthHandler is not a new-style class)
        def _rewind_request(self, req):
            if hasattr(req.data, 'seek'):
                # if the request is issued again (this time with an
                # Authorization header), the file's offset has to be
                # repositioned to the beginning of the file (otherwise,
                # a 0-length body is sent which most likely does not match
                # the Content-Length header (if present))
                req.data.seek(0)

        def retry_http_basic_auth(self, host, req, realm):
            self._rewind_request(req)
            return super(self.__class__,
                         self).retry_http_basic_auth(host, req, realm)

    if 'last_opener' not in _build_opener.__dict__:
        _build_opener.last_opener = (None, None)
    if apiurl == _build_opener.last_opener[0]:
        return _build_opener.last_opener[1]

    # respect no_proxy env variable
    if proxy_bypass(apiurl):
        # initialize with empty dict
        proxyhandler = ProxyHandler({})
    else:
        # read proxies from env
        proxyhandler = ProxyHandler()

    authhandler_class = OscHTTPBasicAuthHandler
    # workaround for http://bugs.python.org/issue9639
    if sys.version_info >= (2, 6, 6) and sys.version_info < (2, 7, 9):

        class OscHTTPBasicAuthHandlerCompat(OscHTTPBasicAuthHandler):
            # The following two functions were backported from upstream 2.7.
            def http_error_auth_reqed(self, authreq, host, req, headers):
                authreq = headers.get(authreq, None)

                if authreq:
                    mo = AbstractBasicAuthHandler.rx.search(authreq)
                    if mo:
                        scheme, quote, realm = mo.groups()
                        if quote not in ['"', "'"]:
                            warnings.warn("Basic Auth Realm was unquoted",
                                          UserWarning, 2)
                        if scheme.lower() == 'basic':
                            return self.retry_http_basic_auth(host, req, realm)

            def retry_http_basic_auth(self, host, req, realm):
                self._rewind_request(req)
                user, pw = self.passwd.find_user_password(realm, host)
                if pw is not None:
                    raw = "%s:%s" % (user, pw)
                    auth = 'Basic %s' % base64.b64encode(raw).strip()
                    if req.get_header(self.auth_header, None) == auth:
                        return None
                    req.add_unredirected_header(self.auth_header, auth)
                    return self.parent.open(req, timeout=req.timeout)
                else:
                    return None

        authhandler_class = OscHTTPBasicAuthHandlerCompat

    options = config['api_host_options'][apiurl]
    # with None as first argument, it will always use this username/password
    # combination for urls for which arg2 (apisrv) is a super-url
    authhandler = authhandler_class( \
        HTTPPasswordMgrWithDefaultRealm())
    authhandler.add_password(None, apiurl, options['user'], options['pass'])

    if options['sslcertck']:
        try:
            from . import oscssl
            from M2Crypto import m2urllib2
        except ImportError as e:
            print(e)
            raise NoSecureSSLError(
                'M2Crypto is needed to access %s in a secure way.\nPlease install python-m2crypto.'
                % apiurl)

        cafile = options.get('cafile', None)
        capath = options.get('capath', None)
        if not cafile and not capath:
            for i in ['/etc/pki/tls/cert.pem', '/etc/ssl/certs']:
                if os.path.isfile(i):
                    cafile = i
                    break
                elif os.path.isdir(i):
                    capath = i
                    break
        if not cafile and not capath:
            raise oscerr.OscIOError(
                None,
                'No CA certificates found. (You may want to install ca-certificates-mozilla package)'
            )
        ctx = oscssl.mySSLContext()
        if ctx.load_verify_locations(capath=capath, cafile=cafile) != 1:
            raise oscerr.OscIOError(
                None,
                'No CA certificates found. (You may want to install ca-certificates-mozilla package)'
            )
        opener = m2urllib2.build_opener(
            ctx, oscssl.myHTTPSHandler(ssl_context=ctx, appname='osc'),
            HTTPCookieProcessor(cookiejar), authhandler, proxyhandler)
    else:
        handlers = [HTTPCookieProcessor(cookiejar), authhandler, proxyhandler]
        try:
            # disable ssl cert check in python >= 2.7.9
            ctx = ssl._create_unverified_context()
            handlers.append(HTTPSHandler(context=ctx))
        except AttributeError:
            pass
        print(
            "WARNING: SSL certificate checks disabled. Connection is insecure!\n",
            file=sys.stderr)
        opener = build_opener(*handlers)
    opener.addheaders = [('User-agent', 'osc/%s' % __version__)]
    _build_opener.last_opener = (apiurl, opener)
    return opener