Discussion:
[Freerdp-devel] FreeRDP in Ubuntu 11.04
Robert Ancell
2011-01-27 03:51:40 UTC
Permalink
Hi FreeRDPers!

I'm currently trying to get Remmina/FreeRDP as the default on the
Ubuntu 11.04 CD, but our pesky security team wants the certificate
checking to work:

RD_BOOL
crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert)
{
/* FIXME: do the actual verification */
return True;
}

So the question is:
- - Any chance of this working by the end of February?
- - Any plans for this?
- - If you guys haven't got plans, I'll work on a patch. I'm not an
expert at certificate, do I just need to pass the information to the
GUI and let the user ACK/NACK it?

Thanks!
- --Robert Ancell
Ubuntu Desktop
Mads Kiilerich
2011-01-27 12:42:56 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi FreeRDPers!
I'm currently trying to get Remmina/FreeRDP as the default on the
Ubuntu 11.04 CD, but our pesky security team wants the certificate
RD_BOOL
crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert)
{
/* FIXME: do the actual verification */
return True;
}
I assume this is from crypto_openssl.c and that you don't care about
other crypto backends. Ok.

This function is only used to verify the individual links in the x509
certificate chain is correct. That alone is far from enough. Note
however that this part works with the gnutls backend.

Finally (so far) there is the tls option. libfreerdp/tls.c (which so far
only works with openssl) is far more complete but still not completely
finished.
- - Any chance of this working by the end of February?
- - Any plans for this?
- - If you guys haven't got plans, I'll work on a patch. I'm not an
expert at certificate, do I just need to pass the information to the
GUI and let the user ACK/NACK it?
AFAIK there are no specific plans and no chance unless somebody do
something.

I think FreeRDP is quite stable and reliable on local trusted networks,
but I wouldn't recommend using it on untrusted networks or when
connecting to untrusted servers. FreeRDP security in these (and other)
areas is definitely not worse than rdesktop (which I assume is the only
alternative).

It would be great if you could work on improvements in this area.

A brief description of some aspects of a good solution could be:
* options for warning/accepting/failing on "Proprietary Certificate"
* more common handling of certificates for tls and non-tls
* support more crypto backends for tls (and nla) (but focusing on
openssl first is fine)
* checking that the server certificate matches the request hostname
* functionality for checking that the x509 chain can be validated with
the systems CA certificates (probably only useful in very few setups)
* functionality for using other CA certificates (so you can add your
local AD CA and automatically trust all servers on the domain regarding
rdp without adding it to the global configuration)
* ssh-like "known host" functionality, asking "unknown host X shows
certificate Y - trust it and store it to next time?", adding it to some
"known_hosts" file and using it next time and failing/prompting if it
doesn't match next time

It will require changes to both libfreerdp and xfreerdp and will thus
also require a so version bump.

Not a trivial task ... It might make sense to focus on "known host" and
ignore the PKI mess. That might bring you most of the way to what you want.

/Mads
Robert Ancell
2011-02-08 06:01:21 UTC
Permalink
Post by Mads Kiilerich
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi FreeRDPers!
I'm currently trying to get Remmina/FreeRDP as the default on
the Ubuntu 11.04 CD, but our pesky security team wants the
RD_BOOL crypto_cert_verify(CryptoCert server_cert, CryptoCert
cacert) { /* FIXME: do the actual verification */ return True; }
I assume this is from crypto_openssl.c and that you don't care
about other crypto backends. Ok.
This function is only used to verify the individual links in the
x509 certificate chain is correct. That alone is far from enough.
Note however that this part works with the gnutls backend.
Finally (so far) there is the tls option. libfreerdp/tls.c (which
so far only works with openssl) is far more complete but still not
completely finished.
So the question is: - - Any chance of this working by the end of
February? - - Any plans for this? - - If you guys haven't got
plans, I'll work on a patch. I'm not an expert at certificate,
do I just need to pass the information to the GUI and let the
user ACK/NACK it?
AFAIK there are no specific plans and no chance unless somebody do
something.
I think FreeRDP is quite stable and reliable on local trusted
networks, but I wouldn't recommend using it on untrusted networks
or when connecting to untrusted servers. FreeRDP security in these
(and other) areas is definitely not worse than rdesktop (which I
assume is the only alternative).
It would be great if you could work on improvements in this area.
A brief description of some aspects of a good solution could be: *
options for warning/accepting/failing on "Proprietary Certificate"
* more common handling of certificates for tls and non-tls *
support more crypto backends for tls (and nla) (but focusing on
openssl first is fine) * checking that the server certificate
matches the request hostname * functionality for checking that the
x509 chain can be validated with the systems CA certificates
(probably only useful in very few setups) * functionality for using
other CA certificates (so you can add your local AD CA and
automatically trust all servers on the domain regarding rdp without
adding it to the global configuration) * ssh-like "known host"
functionality, asking "unknown host X shows certificate Y - trust
it and store it to next time?", adding it to some "known_hosts"
file and using it next time and failing/prompting if it doesn't
match next time
It will require changes to both libfreerdp and xfreerdp and will
thus also require a so version bump.
Not a trivial task ... It might make sense to focus on "known
host" and ignore the PKI mess. That might bring you most of the way
to what you want.
/Mads
Hi Mads,

Thanks for the information. Yes, we would be switching from rdesktop
(which is a support problem).

I've had a first attempt at getting something working.

Firstly, I'm using the rdp_mitm server to connect to. I couldn't work
out how to get a secure RDP server to work in Linux. Attached patch
fixes the build system for this.

The second patch is to add a callback in the freerdp API so that RDP
clients can prompt the user.

Some questions:

- - I figure the API needs to provide the security state of the
connection (unsecured, secured with unknown/invalid certificate,
secured with valid certificate). Please let me know if this is
heading in the direction you expect.

- - There are two encryption schemes here right? One for the whole
channel (TLS) and one inside the RDP protocol (MCS?). Is TLS the
newer method and MCS? the legacy method?

- - Any thoughts on how to provide certificate contents to the user for
them to decide if a certificate is valid / should be added to the list
of accepted certificates? This seems difficult to provide due to the
number of different crypto backends (i.e. no shared certificate class).

Thanks,
- --Robert
Mads Kiilerich
2011-03-08 15:07:51 UTC
Permalink
Post by Robert Ancell
I've had a first attempt at getting something working.
Thanks for the patches. Unfortunately it seems like everybody has been
too busy to be scalable and efficient and review contributions ...
Post by Robert Ancell
Firstly, I'm using the rdp_mitm server to connect to. I couldn't work
out how to get a secure RDP server to work in Linux. Attached patch
fixes the build system for this.
That tool wasn't really supported and has been removed.
Post by Robert Ancell
The second patch is to add a callback in the freerdp API so that RDP
clients can prompt the user.
Some general comments:

If we extend the API with a ui_check_certificate method it should be
mandatory - there shouldn't be any particular need for checking if it is
NULL. But it should also be implemented in win/wfreerdp/.

I get segmentation fault when l_ui_check_certificate returns False. It
seems like the connection isn't "sufficiently terminated".

The changes in secure.c seems to violate some layering, but I'm not sure
how that should be solved. Others might have an opinion on that.
Post by Robert Ancell
- - I figure the API needs to provide the security state of the
connection (unsecured, secured with unknown/invalid certificate,
secured with valid certificate). Please let me know if this is
heading in the direction you expect.
The way I see it there are two different ways a host can be verified.

One way is that the user somehow (implicitly or explicitly) tells the
crypto library which CAs should be trusted, and FreeRDP then makes sure
the server host certificates are signed by one of these (possibly by
chain of trust).

The other way is that the server presents a certificate that can't be
validated by any CA. FreeRDP can then ask the UI if the certificate is
OK anyway. The UI can ask the user, and the UI may store the decision in
a database so it can answer on the users behalf next time.

( My reference for how that can be done in a slightly different
architecture is http://hg.intevation.org/mercurial/crew/rev/8dc488dfcdb4 .)

The UI shouldn't need to have any crypto awareness, so I think the
check_certificate callback to the UI should have the following parameters:
* flag, one of
** got certificate - what to do
** certificate passed validation by CA
** certificate validation by CA failed
** certificate validation failed - expired or doesn't match server
* servername (as requested by the user or redirected to)
* certificate fingerprint (uint8[20] with sha1 of public certificate DER)
* textual decoding of public certificate (20+ lines as returned by
crypto_cert_print_fp ... or something similar)
* perhaps the raw DER certificate so the user can analyze it further
with crypto tools
The return value could be
* go ahead and accept the connection
* try again with this CA (which also is returned somehow) and call back
* rejected - terminate the connection ASAP

I think such an API would give reasonable flexibility and functionality.
What do GUI writers such as Vic say?

Obviously the connection must either be verified as the user specified
or rejected. I don't think it matters after the fact how it was verified
and I don't see the point in storing sec->verified.
Post by Robert Ancell
- - There are two encryption schemes here right? One for the whole
channel (TLS) and one inside the RDP protocol (MCS?). Is TLS the
newer method and MCS? the legacy method?
Correct. TLS works with some servers and the old way must be used when
connecting to other servers, so both must be implemented.

We don't have a good name for "the old way" that uses "Server
Proprietary" or X.509 certificates.
Post by Robert Ancell
- - Any thoughts on how to provide certificate contents to the user for
them to decide if a certificate is valid / should be added to the list
of accepted certificates? This seems difficult to provide due to the
number of different crypto backends (i.e. no shared certificate class).
Correct. So far the TLS/NLA only works with OpenSSL and doesn't use the
plugable crypto modules secure.c uses. I think it would be OK if we
focus on OpenSSL here too, but keep in mind that it also should be
possible to make it work with other crypto backends in the future.

/Mads
Marc-André Moreau
2011-03-08 15:30:21 UTC
Permalink
I have a suggestion regarding certificate validation:

Looking at mstsc.exe, it appears to me that the certificate validation is
delegated to a module dedicated just to that. If we let the UI handle it
with a callback, maybe we could provide the UI with a library that can
handle it? This way, for instance, a system with both xfreerdp and
dfbfreerdp wouldn't need to have separate certificate validation.
Information could be stored in ~/.freerdp
Post by Mads Kiilerich
Post by Robert Ancell
I've had a first attempt at getting something working.
Thanks for the patches. Unfortunately it seems like everybody has been
too busy to be scalable and efficient and review contributions ...
Post by Robert Ancell
Firstly, I'm using the rdp_mitm server to connect to. I couldn't work
out how to get a secure RDP server to work in Linux. Attached patch
fixes the build system for this.
That tool wasn't really supported and has been removed.
Post by Robert Ancell
The second patch is to add a callback in the freerdp API so that RDP
clients can prompt the user.
If we extend the API with a ui_check_certificate method it should be
mandatory - there shouldn't be any particular need for checking if it is
NULL. But it should also be implemented in win/wfreerdp/.
I get segmentation fault when l_ui_check_certificate returns False. It
seems like the connection isn't "sufficiently terminated".
The changes in secure.c seems to violate some layering, but I'm not sure
how that should be solved. Others might have an opinion on that.
Post by Robert Ancell
- - I figure the API needs to provide the security state of the
connection (unsecured, secured with unknown/invalid certificate,
secured with valid certificate). Please let me know if this is
heading in the direction you expect.
The way I see it there are two different ways a host can be verified.
One way is that the user somehow (implicitly or explicitly) tells the
crypto library which CAs should be trusted, and FreeRDP then makes sure
the server host certificates are signed by one of these (possibly by
chain of trust).
The other way is that the server presents a certificate that can't be
validated by any CA. FreeRDP can then ask the UI if the certificate is
OK anyway. The UI can ask the user, and the UI may store the decision in
a database so it can answer on the users behalf next time.
( My reference for how that can be done in a slightly different
architecture is http://hg.intevation.org/mercurial/crew/rev/8dc488dfcdb4.)
The UI shouldn't need to have any crypto awareness, so I think the
* flag, one of
** got certificate - what to do
** certificate passed validation by CA
** certificate validation by CA failed
** certificate validation failed - expired or doesn't match server
* servername (as requested by the user or redirected to)
* certificate fingerprint (uint8[20] with sha1 of public certificate DER)
* textual decoding of public certificate (20+ lines as returned by
crypto_cert_print_fp ... or something similar)
* perhaps the raw DER certificate so the user can analyze it further
with crypto tools
The return value could be
* go ahead and accept the connection
* try again with this CA (which also is returned somehow) and call back
* rejected - terminate the connection ASAP
I think such an API would give reasonable flexibility and functionality.
What do GUI writers such as Vic say?
Obviously the connection must either be verified as the user specified
or rejected. I don't think it matters after the fact how it was verified
and I don't see the point in storing sec->verified.
Post by Robert Ancell
- - There are two encryption schemes here right? One for the whole
channel (TLS) and one inside the RDP protocol (MCS?). Is TLS the
newer method and MCS? the legacy method?
Correct. TLS works with some servers and the old way must be used when
connecting to other servers, so both must be implemented.
We don't have a good name for "the old way" that uses "Server
Proprietary" or X.509 certificates.
Post by Robert Ancell
- - Any thoughts on how to provide certificate contents to the user for
them to decide if a certificate is valid / should be added to the list
of accepted certificates? This seems difficult to provide due to the
number of different crypto backends (i.e. no shared certificate class).
Correct. So far the TLS/NLA only works with OpenSSL and doesn't use the
plugable crypto modules secure.c uses. I think it would be OK if we
focus on OpenSSL here too, but keep in mind that it also should be
possible to make it work with other crypto backends in the future.
/Mads
------------------------------------------------------------------------------
What You Don't Know About Data Connectivity CAN Hurt You
This paper provides an overview of data connectivity, details
its effect on application quality, and explores various alternative
solutions. http://p.sf.net/sfu/progress-d2d
_______________________________________________
Freerdp-devel mailing list
https://lists.sourceforge.net/lists/listinfo/freerdp-devel
Mads Kiilerich
2011-03-08 15:48:33 UTC
Permalink
Post by Marc-André Moreau
Looking at mstsc.exe, it appears to me that the certificate validation
is delegated to a module dedicated just to that. If we let the UI handle
it with a callback, maybe we could provide the UI with a library that
can handle it? This way, for instance, a system with both xfreerdp and
dfbfreerdp wouldn't need to have separate certificate validation.
Information could be stored in ~/.freerdp
We have to be wire-compatible with MS, but I'm not sure how much we
should learn from MS when it comes to architecture.

However, except for "is the certificate valid with regard to these CAs"
question (which should be answered by the crypto library that already is
encapsulated in libfreerdp) there isn't much code that could be reused.
It is mostly policy and user interfacing, and that is closely related to
how the GUI choose to do it.

I also don't think it would make much sense if for example remmina
looked in .freerdp. It should use its own configuration and UI.

When it comes to FreeRDPs own simple UIs I think they should be built
from the same source with a sufficient number of compile options, and
branded as freerdp on all platforms. Exactly just like for example
firefox is firefox on all platforms even though it differs and is
platform specific in some points. That way they will all share the same
command line options and configuration file parsers and so on - and they
would all use ~/.freerdp.

/Mads
Marc-André Moreau
2011-03-08 15:59:38 UTC
Permalink
Post by Marc-André Moreau
Looking at mstsc.exe, it appears to me that the certificate validation
is delegated to a module dedicated just to that. If we let the UI handle
it with a callback, maybe we could provide the UI with a library that
can handle it? This way, for instance, a system with both xfreerdp and
dfbfreerdp wouldn't need to have separate certificate validation.
Information could be stored in ~/.freerdp
We have to be wire-compatible with MS, but I'm not sure how much we should
learn from MS when it comes to architecture.
Agreed, the MS architecture only gives ideas, it's not something we need to
stick to
However, except for "is the certificate valid with regard to these CAs"
question (which should be answered by the crypto library that already is
encapsulated in libfreerdp) there isn't much code that could be reused. It
is mostly policy and user interfacing, and that is closely related to how
the GUI choose to do it.
How do you plan on handling "is the certificate valid with regard to these
CAs", if we delegate the call to the UI? Will the UI use another function
call in libfreerdp to check if a certificate is valid? The user will only
get a question if the certificate cannot be validated automatically, such as
it is the case with a self-signed certificate.
I also don't think it would make much sense if for example remmina looked
in .freerdp. It should use its own configuration and UI.
Remmina has its own stuff to deal with, that wouln't need to be put there.
However, we could handle FreeRDP-specific information there, stuff that is
common to all UIs.
When it comes to FreeRDPs own simple UIs I think they should be built from
the same source with a sufficient number of compile options, and branded as
freerdp on all platforms. Exactly just like for example firefox is firefox
on all platforms even though it differs and is platform specific in some
points. That way they will all share the same command line options and
configuration file parsers and so on - and they would all use ~/.freerdp.
The main difference is that Firefox will normally be available under one
port per platform, not multiple "ports" per platform like what we have. Both
X11 and DirectFB UIs run on Linux, so how do we make the distinction?
/Mads
Mads Kiilerich
2011-03-08 16:28:35 UTC
Permalink
Post by Mads Kiilerich
However, except for "is the certificate valid with regard to these
CAs" question (which should be answered by the crypto library that
already is encapsulated in libfreerdp) there isn't much code that
could be reused. It is mostly policy and user interfacing, and that
is closely related to how the GUI choose to do it.
How do you plan on handling "is the certificate valid with regard to
these CAs", if we delegate the call to the UI? Will the UI use another
function call in libfreerdp to check if a certificate is valid? The user
will only get a question if the certificate cannot be validated
automatically, such as it is the case with a self-signed certificate.
Yes, something like that, as proposed in my draft.

I am not sure we can assume in libfreerdp that the user only should be
asked if automatic validation fails.

It do make a lot of sense that a UI designer would like to give the user
the option of not silently accepting anything that the CA chain
validates. Checking fingerprints (similar to sshs "known hosts") is in
many ways more secure than CA-based validation where several governments
will be able to impersonate any server. The problem with fingerprints is
how to figure out which fingerprint to trust.

Users might also want to use different CAs for their RDP connections
than they use for their web browsing, and perhaps even different CAs for
different servers.
Post by Mads Kiilerich
The main difference is that Firefox will normally be available under one
port per platform, not multiple "ports" per platform like what we have.
Both X11 and DirectFB UIs run on Linux, so how do we make the distinction?
I think it would be fine to make the choice with a configuration option.
For each platform the packager (or whoever compiles the code) would
choose which of the UI libraries the freerdp binary should use. There is
no reason an ordinary user should want to use X11 when connecting to one
server and DirectFB when connecting to another.

I don't know how far firefox is with directfb and qt support and other
non-gtk gui libraries, but also there I would expect it to be a compile
time option.

/Mads
Vic Lee
2011-03-09 02:03:24 UTC
Permalink
I think we should pass those arguments to ui_check_certificate:
1. Fingerprint of the certificate
2. A human-readable description of the certificate
3. Boolean value on whether the certificate was valid.

This means libfreerdp should always try to verify the certificate before
invoking the callback. I think this should be easier for UI development,
which can simply prompt the passed information and ask the user what to do.
Post by Mads Kiilerich
I am not sure we can assume in libfreerdp that the user only should be
asked if automatic validation fails.
This should be decided by UI. As I proposed, a boolean should be passed
to the UI indicating whether it's valid.

Vic

Loading...