[zeromq-dev] How do I find out which ZAP user I'm talking to? (zap rely field 5)
Drew Crawford
drew at sealedabstract.com
Tue Dec 31 18:27:12 CET 2013
Yes, if the client claims to be billgates and signs their message with the known publickey, then they’re authenticated. The question is, did they do this? Or not?
Let me now be more detailed about the problem. The problem is to correlate an incoming message with a publickey of the sender.
When a message arrives from a ROUTER, you have 3 pieces of information. These pieces of information tell you WHAT messages are being sent. But they do not tell you WHO (publickey) is sending them.
For example, a router message looks like this:
[b'\x00\x80\x00A\xa7', b’’, b'message']
An “identity” or “source". As best as I can tell this field of bytes has no broader meaning than an opaque set of bytes set by the router. If it had a broader meaning, and the public key could be worked out from it, that would solve the problem.
An empty delimiter. This is obviously of no use.
A message. Now (if you are using CURVE) this message is signed and encrypted, so it’s not completely untrusted. However, all we know is that SOME valid user signed it. We do not know WHICH user signed it. So we couldn’t rely on some “I’m Bill Gates!” type message to positively identify that the message came from Bill Gates. We could do custom, application-level digital signatures, but the whole point of CurveZMQ is not to roll our own crypto.
Meanwhile, over in the ZAP authentication step, you find out WHO (publickey) is connecting. But there is no way to correlate this with the messages they send.
Under rfc.zeromq.org/spec:27/ZAP, you get the following pieces of information:
> The request message SHALL consist of the following message frames:
>
> • An address delimiter frame, which SHALL have a length of zero.
> • The version frame, which SHALL contain the three octets "1.0".
> • The request id, which MAY contain an opaque binary blob.
> • The domain, which SHALL contain a string.
> • The address, the origin network IP address.
> • The identity, the identity of the originating ZeroMQ socket.
> • The mechanism, which SHALL contain a string.
> • The credentials, which SHALL be zero or more opaque frames.
For example, a ZAP request looks like this. For reasons that are a bit of a mystery to me, it seems to omit the first delimiter frame in the specification, so the version frame is request[0]. This may be an artifact of my test setup.
[b'1.0', b'1', b'', b'127.0.0.1', b'', b'CURVE', b'\x1f4I\r\x920\xbd\x03\xb1\xa9\x12N\x18k\x95TKB:Upf\x13=&1<\xa4Cg\x12h']
You would think, for example, that the identity field request[5] (request[4] in my sample packet) would contain the same “identity” opaque bytes that the router gives you in #1. That would allow you to correlate the publickey with the subsequent messages. In practice, however, the ZAP identity field is the empty string, as you can see. Therefore you cannot correlate messages with public keys via this mechanism.
Another obvious mechanism would be for something in the ZAP response to become associated with the router in some way. Under the spec quoted earlier, the response contains these frames:
> The reply message SHALL consist of the following message frames:
>
> • An address delimiter frame, which SHALL have a length of zero.
> • The version frame, which SHALL contain the three octets "1.0".
> • The request id, which MAY contain an opaque binary blob.
> • The status code, which SHALL contain a string.
> • The status text, which MAY contain a string.
> • The user id, which SHALL contain a string.
> • The metadata, which MAY contain a blob.
One might expect, for example, that the userid here would appear in a lookup table that would allow you to map from the ROUTER’s identity field onto the userid. In practice, the userid appears to be ignored entirely by the implementation. As far as I can tell, none of these fields can be used in practice to create a mapping between public keys and messages.
The result of all this is that there is no way to correlate the public key of a sender with their incoming messages. We at one time verify that the public key is that of an authorized client. And at another time we receive messages, knowing that the messages are sent by some authorized client. But at no time can we find out which client (publickey) particularly is sending which message. These two events cannot be correlated because there is no unique identifier common to both events.
Drew
On Dec 31, 2013, at 2:08 AM, Amir Taaki <zgenjix at yahoo.com> wrote:
> Well any client can pick their own keypair, so unless you have the public key then it's moot. If the client claims to be billgates and signs their message (and you have their pubkey) then they're authenticated, no?
>
>
>
>
>
> On Tuesday, December 31, 2013 7:01 AM, Drew Crawford <drew at sealedabstract.com> wrote:
> Well if I allow just any client to claim to be billgates that’s not going to be very secure…
>
> …or did I misunderstand your proposal?
>
>
> On Dec 31, 2013, at 12:56 AM, Amir Taaki <zgenjix at yahoo.com> wrote:
>
>> Have you thought about a custom frame at the top of your message?
>>
>> Or the clients can set their own custom identity if they have unique names.
>>
>>
>>
>>
>>
>> On Tuesday, December 31, 2013 6:51 AM, Drew Crawford <drew at sealedabstract.com> wrote:
>> Hey folks,
>>
>> I’ve got a REQ-ROUTER architecture where clients (with a REP socket) connect to a server (with a ROUTER socket). This connection is authenticated via CURVE.
>>
>> I need to figure out some person/username/unique identifier that is associated with the incoming REQ. There are a couple of reasons. One is that not all users have the same level of access privileges. For example, there’s an admin user, with more powers than the other users, and so I need to allow some types of REQs only for that user. Another reason is that in this application, users live inside their own sandbox more or less. So a REQ that lists data, should only be listing data that the current user is allowed to see.
>>
>> rfc.zeromq.org/spec:27/ZAP is apparently built to solve this problem, and the reply even has a field (field 5, "The user id, which SHALL contain a string.”) which looks like it is built for the purpose of associating a username with a session. Presumably I would just fill that field with the username (e.g. “billgates”) when I am satisfied that the user has authenticated successfully as Bill Gates.
>>
>> The problem is that at the time that a request comes inbound on my ROUTER, the only data I (seem to) have about the sender is some opaque (to me) identity bytes in the message envelope. And I do not see a way to take those opaque bytes and convert them into either billgates, the client’s public key, or any other identifying information that would let me figure out who is making the request.
>>
>> In an attempt to see where field 5 goes, I have traced the parsing of the zap field into curve_server.cpp (https://github.com/zeromq/libzmq/blob/master/src/curve_server.cpp#L617) and as far as I can tell it’s unused. So it’s possible that the feature I’m looking for isn’t implemented.
>>
>> Any suggestions for how I can identify the sender of a REQ, either within the current 4.0.3 release, or a general sketch of a patch I could write that would solve this problem?
>>
>> Drew
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>> _______________________________________________
>> zeromq-dev mailing list
>> zeromq-dev at lists.zeromq.org
>> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
>
>
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20131231/830f78f3/attachment.htm>
More information about the zeromq-dev
mailing list