예제 #1
0
 def _validate_ssl_fingerprint(self, transp, host, port):
     has_cert = transp.get_extra_info('sslcontext')
     if has_cert and self._fingerprint:
         sock = transp.get_extra_info('socket')
         if not hasattr(sock, 'getpeercert'):
             # Workaround for asyncio 3.5.0
             # Starting from 3.5.1 version
             # there is 'ssl_object' extra info in transport
             sock = transp._ssl_protocol._sslpipe.ssl_object
         # gives DER-encoded cert as a sequence of bytes (or None)
         cert = sock.getpeercert(binary_form=True)
         assert cert
         got = self._hashfunc(cert).digest()
         expected = self._fingerprint
         if got != expected:
             transp.close()
             if not self._cleanup_closed_disabled:
                 self._cleanup_closed_transports.append(transp)
             raise aiohttp.ServerFingerprintMismatch(
                 expected, got, host, port)
예제 #2
0
    async def _create_socks_connection(self, req):
        sslcontext = self._get_ssl_context(req)
        fingerprint, hashfunc = self._get_fingerprint_and_hashfunc(req)

        if not self._remote_resolve:
            try:
                dst_hosts = list(await self._resolve_host(req.host, req.port))
                dst = dst_hosts[0]['host'], dst_hosts[0]['port']
            except OSError as exc:
                raise aiohttp.ClientConnectorError(req.connection_key,
                                                   exc) from exc
        else:
            dst = req.host, req.port

        try:
            proxy_hosts = await self._resolve_host(req.proxy.host,
                                                   req.proxy.port)
        except OSError as exc:
            raise aiohttp.ClientConnectorError(req.connection_key,
                                               exc) from exc

        last_exc = None

        for hinfo in proxy_hosts:
            if req.proxy.scheme == 'socks4':
                proxy = Socks4Addr(hinfo['host'], hinfo['port'])
            else:
                proxy = Socks5Addr(hinfo['host'], hinfo['port'])

            try:
                transp, proto = await self._wrap_create_socks_connection(
                    self._factory,
                    proxy,
                    req.proxy_auth,
                    dst,
                    loop=self._loop,
                    remote_resolve=self._remote_resolve,
                    ssl=sslcontext,
                    family=hinfo['family'],
                    proto=hinfo['proto'],
                    flags=hinfo['flags'],
                    local_addr=self._local_addr,
                    req=req,
                    server_hostname=req.host if sslcontext else None)
            except aiohttp.ClientConnectorError as exc:
                last_exc = exc
                continue

            has_cert = transp.get_extra_info('sslcontext')
            if has_cert and fingerprint:
                sock = transp.get_extra_info('socket')
                if not hasattr(sock, 'getpeercert'):
                    # Workaround for asyncio 3.5.0
                    # Starting from 3.5.1 version
                    # there is 'ssl_object' extra info in transport
                    sock = transp._ssl_protocol._sslpipe.ssl_object
                # gives DER-encoded cert as a sequence of bytes (or None)
                cert = sock.getpeercert(binary_form=True)
                assert cert
                got = hashfunc(cert).digest()
                expected = fingerprint
                if got != expected:
                    transp.close()
                    if not self._cleanup_closed_disabled:
                        self._cleanup_closed_transports.append(transp)
                    last_exc = aiohttp.ServerFingerprintMismatch(
                        expected, got, req.host, req.port)
                    continue
            return transp, proto
        else:
            raise last_exc