On Oct 18, 2012, at 11:56 PM, Adi Roiban <a...@roiban.ro> wrote:

> On 19 October 2012 09:28, Glyph <gl...@twistedmatrix.com> wrote:
>> On Oct 18, 2012, at 9:41 PM, Nathan Mower <nath...@securitymetrics.com> 
>> wrote:
>> 
>>> The following sample code worked until Twisted began to prefer memory BIOs 
>>> over socket BIOs.  Now it produces this error...
>>> 
>>> exceptions.AttributeError: 'NoneType' object has no attribute 'getpeername'
>>> 
>>> ...on line 9 where getpeername() is called by the verify() callback.
>>> 
>>> Is there any way to obtain the peer name, given the OpenSSL.SSL.Connection 
>>> object passed into verify()?  Anything that surfaces the underlying socket? 
>>>  (Perhaps something similar to what is done in connectionMade(), which does 
>>> work.)  Or alternatively, is there a way to tell the reactor to employ 
>>> socket BIOs?
>> 
>> The 'socket' attribute that you're accessing is not a documented attribute 
>> of ITransport, so in a way I'm glad that your code broke - this wasn't a 
>> valid way to use Twisted in the first place :).  See 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.ITransport.html>.
>> 
>> Now, as it happens, 
>> <http://twistedmatrix.com/documents/current/api/twisted.protocols.tls.TLSMemoryBIOProtocol.html>
>>  implements 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.ISSLTransport.html>
>>  which is a subinterface of 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.ITCPTransport.html>,
>>  which is therefore guaranteed to have a getPeer method 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.ITCPTransport.html#getPeer>
>>  that returns an IPv4Address 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.address.IPv4Address.html>
>>  or IPv6Address 
>> <http://twistedmatrix.com/documents/current/api/twisted.internet.address.IPv6Address.html>,
>>  both of which have a 'host' attribute that is the hostname.
>> 
>> So, in short, substitute "self.transport.getPeer().host" and your code 
>> should work again.
> 
> Hi,
> 
> Thanks for the explanation about new interfaces.
> 
> I think that the initial question was about the
> SSL.Context.set_verify(connection, certificate, errnum, errdepth,
> code) callback.
> 
> From what I can see, SSL.Context or SSL.Connection has no transport attribute.
> 
> In previous version there was SSL.Connection.getpeername()

In this case, you actually want to pass in the hostname to verify against, not 
look at the connection.  getpeername() ought to return the IP of the host you 
actually connected to, not the hostname, which is not meaningful to verify 
against.  You need to pass in the host name that the user specified, so that 
needs to be an argument to the verifying context factory.

If you need really need information from the connection itself for verification 
(although that is usually a bad idea, with the exception of the very specific 
case that SSH uses it for - although that grants little in the way of useful 
security, in my opinion), you will have to use connectTCP and startTLS rather 
than connectSSL, so you can construct a new TLS context once you already have a 
reference to the protocol object.

This is a good thing, though; connectSSL is a slightly silly API and something 
that I hope will eventually go away; now that we have memory BIOs, TLS can be 
accomplished just fine without adding additional APIs for every reactor to 
support.

-glyph
_______________________________________________
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

Reply via email to