Archived

This forum has been archived. Please start a new discussion on GitHub.

Unittesting Access Control Verification via custom Ice::Current objects

simon
simon Netherlands
Hi all,

I was wondering how I can manually construct an Ice::Current object containing a fictional remote IP address and port. I have built an Access Control Verifier inside my server methods. This verifier checks the Ice::Current object that is passed to the method and checks the IP address inside it with a configured list of allowed IP addresses (both IPv4 and IPv6).

To test this, I have created some unit tests to check if the Verifier works as expected. However, in order to do this, I need to be able to pass this method an Ice::Current object with my own IP addresses to check whether it actually allows or denies access for different combinations of ACL's and IP's.

Perhaps I'm approaching this in completely the wrong way though, any hints on IP-based Access control to Ice (apart from firewalling or SSL) are greatly appreciated.

Kind regards,

Simon de Hartog
SpeakUp B.V.

Comments

  • benoit
    benoit Rennes, France
    Hi,

    You can just create an Ice::Current struct and fill it with the attributes you need but I guess you rely on the connection information to get the IP address so you would also need to mock a connection object. It's probably simpler if your access control verifier code relies on Ice::ConnectionInfo instead of Ice::Current ... you can more easily create an Ice::ConnectionInfo instance for testing purposes.

    Access control based on IP addresses isn't as secure as using SSL since IP addresses can be spoofed so this is something you need to take under consideration and see whether or not it's a problem.

    Cheers,
    Benoit
  • simon
    simon Netherlands
    Hello Benoit,

    thank you for your answer. The Ice::Current struct can indeed be easily created. However, I did not manage to create an Ice::ConnectionInfo object, since it's destructor is protected. You are right that I would like to create an Ice::IPConnectionInfo object, but this destructor is also protected. Is inheriting this class and making a public destructor the only option in this case?

    SSL would be more secure indeed, but currently difficult to convert the clients that are used by other organisations. I will put SSL on the roadmap, because you are right, it is better than simple IP ACL's.

    Kind regards,
    Simon
  • benoit
    benoit Rennes, France
    Hi Simon,

    Unlike Ice::Current which is a local Slice struct and can be allocated on the stack, Ice::ConnectionInfo is a local Slice class. Slice classes are allocated on the heap and smart pointers are used to managed their lifetime.

    The following code should work for example to create and return a new connection info object:
    Ice::ConnectionInfoPtr info = new Ice::TCPConnectionInfo();
    info->localAddress = "127.0.0.1";
    info->localPort = 10000;
    return info;
    

    Cheers,
    Benoit.
  • simon
    simon Netherlands
    Hello again Benoit,

    your code was very helpful. It did not compile out-of-the-box, but I restructured it as follows. In my Access Control Verifier, I now accept an Ice::ConnectionInfoPtr parameter instead of Ice::Current. To test the actual method, I use:
    Ice::TCPConnectionInfoPtr tcip = new Ice::TCPConnectionInfo();
    tcip->incoming = true;
    tcip->adapterName = "SomeAdapter";
    tcip->localAddress = "123.45.67.89";
    tcip->localPort = 54321;
    tcip->remoteAddress = "234.56.78.90";
    tcip->remotePort = 56789;
    
    Finally, I added an extra parameter to the method in which I can include the result of current.con->type(), which is "tcp", "udp" or something else. I needed this in order to know if the Ice::ConnectionInfoPtr can safely be casted to an Ice::IPConnectionInfoPtr. This is not the case when the client is on the same machine (collocated connection), as I learned from the Manual...

    So in summary, I can now test my ACL method properly. Thanks for your help!

    Kind regards,
    Simon de Hartog
  • benoit
    benoit Rennes, France
    Hi,

    Rather than passing the type, you could also use a dynamic cast:
    Ice::ConnectionInfoPtr info = ...
    Ice::TCPConnectionInfoPtr tcpInfo = Ice::TCPConnectionInfoPtr::dynamicCast(info);
    if(tcpInfo)
    {
        // The endpoint is a TCP endpoint.
    }
    

    Cheers,
    Benoit.
  • Couldn't Glacier do what you need? You could provide your own verifier (which would take a username, password, even an IP address or whatever). Then you wouldn't need to clutter your servants with verification code, since all verification would be done by Glacier...