Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempting to connect via a proxy throws a DNS error "Host not found" #1184

Closed
obiltschnig opened this issue Mar 10, 2016 · 8 comments
Closed
Assignees
Milestone

Comments

@obiltschnig
Copy link
Member

From http://pocoproject.org/forum/viewtopic.php?f=10&t=6723&sid=5c739c16ce5194ced750a02a6f2a92a3

While troubleshooting a customer issue, I've run into a potential issue in the implementation of SecureSocketImpl.cpp. The method SecureSocketImpl::verifyPeerCertificateImpl causes a DNS error "Host not found" when it tries to determine if the specified host is local host. The parameter passed to the function is not the name of the proxy server, but the host name of the Web server the client is trying to connect to. Since the client's DNS has no entry for the host name, DNS throws HostNotFoundException causing the connection to close. Here is a short code snippet to demonstrate how we establish the secure connection to "somesite.com" via proxy "someproxy.dev.org:3128":

auto pocoContext = new Context(....);
auto pSesssion = new Poco::Net::HTTPSClientSession("somesite.com", 80, pocoContext);
pSession->setProxy("someproxy.dev.org", 3128);
// Proxy requires no credentials

To work around the issue I had to turn off the extended certificate validation using Poco::Net::Context::setExtendedCertificateVerification

@obiltschnig obiltschnig self-assigned this Mar 10, 2016
@obiltschnig
Copy link
Member Author

fixed in ee9477a

@obiltschnig
Copy link
Member Author

Could you please verify if this fix works for you:

bool SecureSocketImpl::isLocalHost(const std::string& hostName)
{
    try
    {
        SocketAddress addr(hostName, 0);
        return addr.host().isLoopback();
    }
    catch (Poco::Exception&)
    {
        return false;
    }
}

@brat000012001
Copy link

Yes, the fix above does prevent HostNotFoundException from being thrown.

@brat000012001
Copy link

Can you also take a look at X509Certificate.cpp, line 112? There is a DNS lookup that can potentially cause SSL connection to close prematurely during certificate validation when a proxy is used. The only difference is the DNS lookup only happens if the hostName parameter is an IP address and not a canonical name.
Thanks!

@obiltschnig
Copy link
Member Author

X509Certificate::verify() catches and ignores NoAddressFoundException and HostNotFoundException, so this should be ok.

@brat000012001
Copy link

True. It seems though that X509 verification would always fail if a) a proxy is used to establish an SSL connection and b) the host name is an IP address. The calls to DNS::resolve with any of the domain names extracted from the certificate would always fail thus causing SSL connection to close, even though the certificate may have come from a trusted source, no? For example, let's say the IP address of "somesite.com" is 10.0.1.1:

auto pocoContext = new Context(....);
auto pSesssion = new Poco::Net::HTTPSClientSession("10.0.1.1", 80, pocoContext);
pSession->setProxy("someproxy.dev.org", 3128);

If I am reading the code correctly, X509Certificate::verify() tries to detect if the hostName is an IP address and then does DNS::resolve on a dns name extracted from the certificate to see if the IP addresses match. Given that the client machine is behind a proxy, DNS::resolve is going to fail, thus causing X509Certificate::verify() to return false.

@obiltschnig
Copy link
Member Author

Correct, this is a fallback mechanism trying to validate a certificate even in case the DNS name is not provided. For OpenSSL it's good practice to always provide a DNS name. AFAIK web browsers don't even try so hard to successfully validate the certificate. If the host name from the URI matches the certificate, then it's okay, otherwise the check fails. Not even sure we should do this fallback mechanism.

However, it should not cause any troubles if a host name is available.

@brat000012001
Copy link

Thanks! Its certainly a borderline case and there is a workaround, i.e. users should specify a canonical name instead of an IP address when connecting to an external address via proxy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants