On 07/03/16 13:20, Domen Vrankar wrote:
Hi,

I'm using qpid C++ 0.34 both for broker and client.
For authentication I'm using SSL without encryption.

What I'm trying to do is to set user Id on every sent message:
qpid_message.setUserId(connection_.getAuthenticatedUsername());
Reason for this is that I'd like to know on the receiver side who put
the message in the exchange on the sending side.
So now I have a few questions:

First of I was experimenting with different nicknames for nss database
and inside the certificate. Clients expect QPID_SSL_CERT_NAME to be
set to nss database nickname while user Id in message has to be set to
nickname inside of certificate (ACL file also has to contain the
nickname that is located inside of the certificate). Is there a way to
map/change the functionality so that nss database nickname would be
used in all cases?

It is important that the identity used is actually signed as part of the certificate. That is why it is the based on the subject of the certificate.

The nickname in the database is similar to a filename. It is just a way of identifying a given certificate.

Next I wanted to get user Id from connection
(connection_.getAuthenticatedUsername()) but I always got "dummy"
string. I traced that to SslConnector.cpp (getSecuritySettings
function) where the string is hardcoded. Is there a way to get user id
(certificate nickname) from this function?
I tried to add this functionality myself:
In SslSocket.cpp:
std::string SslSocket::getCertNickname() const
{
     std::string nickname;
     CERTCertificate* cert = SSL_LocalCertificate(nssSocket);
     if (cert) {
         nickname = cert->nickname;
         CERT_DestroyCertificate(cert);
     }
     return nickname;
}
There is already function getClientAuthId but on client side this
returns server cert domain (which in my case is the same as
gettingserver cert nickname - not certain if that is always the
case)...
In SslConnector.cpp function getSecuritySettings():

std::string nickname(socket.getCertNickname());
securitySettings.authid = (nickname.size() ? nickname + "@QPID" :
"dummy"); //"dummy";//set to non-empty string to enable external
authentication

I'm not certain if this solution is OK/would be something that would
be accepted by qpid devs?

I think it is mostly right, but instead of using the nickname, it should extract the identity from the local certificate in the same way the server will.

I.e. we need a similar method to SslSocket::getClientAuthId() (which was a poor choice of name, getPeerAuthId() might have been better) but use the SSL_LocalCertificate rather than the SSL_PeerCertificate.

We would be very grateful for a contribution that fixed this problem.

Also there is an issue that "@QPID" part is hardcoded and I'm not
certain if this is always true.

This part shouldn't even be needed.

Maybe this part should be attached
somewhere else (right before return of getAuthenticatedUsername()?
Haven't checked how that code is connected)?

My last question is if I am even on the right track and could this
(knowing who sent the message on the receiving side from
authentication data) be done any other simpler way that I missed?

If you use userid, then the broker will ensure that the message was in fact published on a connection authenticated as that user. (This is why the id used needs to match the servers view of it).

You can set a custom application property to indicate the sender in some way. That won't be authenticated by the broker though.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@qpid.apache.org
For additional commands, e-mail: users-h...@qpid.apache.org

Reply via email to