some RFB 3.3 compatibility and DES auth - #160
Conversation
|
Thanks for the contribution. I'll be a bit busy the next couple of weeks. I'll give this a look when I have the time. |
|
Thanks for the positive feedback @any1 I am happy there is a way to get this merged. Would you prefer a new PR with logically re-organized commits or few smaller separate PRs? Perhaps one PR with smaller fixes + one for DES auth? Re #146 - I feel it would take too long to make it fully working and I personally see more value in supporting legacy protocols that will work in many clients. In many cases weak authorization and no encryption is not an issue (similar to Basic HTTP auth) - ssh and vpn are sufficient already. To be honest only reason I bother with auth at all, because Apple client cannot skip it entirely. Re #149 - I saw it later. It feels a bit abandoned and I don't need to bring complete DES implementation to the source tree. |
You can make one PR for miscellaneous improvements and fixes and keep this one for the DES stuff, but I would suggest changing the name to "Add DES Authentication" or something like that.
Fair enough. I really wanted to keep out worst legacy bits for sake of keeping things neat, but for better or worse, RFB is a legacy protocol.
I definitely do not want a whole DES implementation in there. |
4cac5b6 to
b44b93f
Compare
|
Hey @any1 - I have updated the PR and PR description. Please take a look when you will have time. |
|
I should have mentioned this earlier, but all cryptography dependencies (except gnutls) are wrapped inside |
|
@any1 moved to src/crypto |
any1
left a comment
There was a problem hiding this comment.
I like that you wrote tests.
I'd rather have the first commit squashed with the second one instead of having a broken commit in there. Ideally, their order should be swapped, but I understand if you don't have the patience for such git gymnastics. It is easier to review PRs when commits are logically ordered, each commit changing only "one thing" and not breaking anything.
| { | ||
| nvnc_log(NVNC_LOG_WARNING, "Connection rejected: %s", reason_string); | ||
|
|
||
| return security_send_failure(client, RFB_SECURITY_TYPE_INVALID, |
There was a problem hiding this comment.
RFB_SECURITY_TYPE_INVALID is not a result code.
There was a problem hiding this comment.
I get what you're doing now, but it's confusing because it conflates two different message types.
This would probably be clearer if these functions had duplicate code. It's not as if it's a lot of code anyway.
It might even be better to inline this function.
| #endif | ||
|
|
||
| if (server->auth_flags & NVNC_AUTH_REQUIRE_AUTH) { | ||
| security_type_invalid(client, |
There was a problem hiding this comment.
In this situation, 3.3 is an unsupported version, so it should be treated as such, by calling handle_unsupported_version.
There was a problem hiding this comment.
3.3 protocol can't handle "unsupported version" message see https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#security
The server decides the security type and sends a single word... A value of 0 means that the connection has failed and is followed by a string giving the reason...
The difference is subtle:
3.7+ will send U8 with 0 and then U32 len of reason and reason
3.3 will send U32 with all zeroes, then U32 len of reason and reason
If you want - i can do 3.7 way here - we are going to close the connection anyway. Probably clients will show just a bit more obscure error.
There was a problem hiding this comment.
Well, it's better to give a good error if possible, so this is functionally correct.
| int security_type_invalid(struct nvnc_client* client, | ||
| const char* reason_string) | ||
| { | ||
| nvnc_log(NVNC_LOG_WARNING, "Connection rejected: %s", reason_string); |
There was a problem hiding this comment.
Nit: This should be an info-level message.
5e00683 to
a25548e
Compare
|
Hey @any1 - thanks for your review and your patience with this. I squashed first two commits as you suggested. Also I fixed everything and wrote new tests covering RFB 3.7 RFC compliance. |
|
Can you squash fixups into the individual commits that they're supposed to fix? Except that one that I commented on, of course. That whole commit can be dropped. |
|
@any1 How would you like the commits to tell the story? We could split it into three commits: DES (unreachable), RFB 3.3/3.7, and tests. Or do the broader RFB 3.3/3.7 work first (excluding DES), then DES, then tests. TDD-style with failing tests first would also work. |
The best order would be: Thank you. |
Implement DES challenge-response auth for RFB 3.8 clients. Refactor auth callback to use nvnc_auth_creds struct with accessor functions. Requires NVNC_AUTH_ALLOW_BROKEN_CRYPTO flag.
Parse RFB version with sscanf instead of exact string match. Extract on_version_message_rfb33() for RFB 3.3 clients (U32 security type). Send SecurityResult reason string only for RFB 3.8+.
14 Python tests covering DES auth (RFB 3.3, 3.7, 3.8) and VeNCrypt X509_PLAIN auth, using a minimal rfb-test-server.
a25548e to
dffc44a
Compare
|
done, rearranged in 3 commits; I run my tests after commit 1 (DES, only subset of tests) and commit 2 (DES + RFB compatibility). |
| #endif | ||
|
|
||
| if (server->auth_flags & NVNC_AUTH_REQUIRE_AUTH) { | ||
| security_handshake_failed(client, NULL, |
There was a problem hiding this comment.
This was supposed to be the sec type plus reason string but inlined, but that can be fixed later. It's good enough for now.
|
Thanks! I wouldn't object to having tests like this for attempted authentication bypasses. I.e. if a client tries to select an unsupported security type after receiving the list of types. |
|
Oops, I forgot, it would have been good to have the changes for wayvnc ready before merging this. Can you make a PR for that soon? |
|
@any1 thanks - appreciate your patience. I am glad we've got this merged! I'll open the wayvnc PR shortly. I already have a working version that I’ve been using to test neatvnc. |
This PR introduces some RFB < 3.8 compatibility (primarily at handshake time) and DES auth.
Because of the way DES auth work, nvnc_auth_fn had to be updated too - which brings some minor changes to other auth implementations.
Additionally, because of some prior incidents at code review level with auth-related bugs, I decided to implement some functional tests. Functional tests now use special harness-binary rfb-test-server (based on examples) and few hundred lines of stdlib-only python code (because it is a bit nicer to write tests in).
We now test: handshake, none, DES and some vencrypt (just to test something from 3.8).
Feedback is welcome. I haven't opened a wayvnc PR yet since it depends on these changes.
I've read and understood CONTRIBUTING.md.