On 2019-03-21 00:12, brian mullan wrote:
> Maybe I missed it but what linux distro are you using ?
Brian, I think it does not matter so much. I have compiled guacd from sources
for Debian Buster and I have downloaded guacamole.war v1.0.0 from Apache
website.
On 2019-03-21 15:33, Nick Couchman wrote:
> I don't think that the not allowing of a null password is actually the issue
> - I think the problem is that it just implements the
> getAuthorizedConfigurations() method and not the authenticateUser()
> method, which is what the other modules use to "stack" authentication.
Nick, if you check SimpleAuthenticationProvider.authenticateUser():142
<https://github.com/apache/guacamole-client/blob/7e7b6fde4cd63ac8ec21e2ee900ae865d15a4c36/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleAuthenticationProvider.java#L142>
you
will see that if there are configurations available, user is created on-the-fly.
Further look into the source code revealed that things are a bit more
complicated. All modules perform user comparison based on the information from
Credentials instance, see for example
UserService.retrieveAuthenticatedUser():361
<https://github.com/apache/guacamole-client/blob/658ce7884695cbe0c04b29f0b6fa365312dbe2fd/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/user/UserService.java#L361>
and the only place where this object is created at is
TokenRESTService.getCredentials()
<https://github.com/apache/guacamole-client/blob/c890919d5bbb9ccc8243f04caae07c78a032ef07/guacamole/src/main/java/org/apache/guacamole/rest/auth/TokenRESTService.java#L84>.
That in its turn means that
Guacamole cannot create Credentials instance other than from Authorization:
Basic HTTP header, which means that front webserver/proxy authorization (which
is not necessarily HTTP basic authentication)
is not possible.
I have identified the following workarounds, namely, if one of below patches is
applied then everything starts working:
* FileAuthenticationProvider.java.patch – this one overrides getUserContext()
to enable configuration for authenticatedUser.getIdentifier().
* AuthenticatedUser_Authorization.patch – this one injects username from
header to Credentials and allows null passwords.
>
>
> How Guacamole decides in which order to call providers? I order is
> undefined, then I don't see any reasonable way to make chaining possible. The
> only way out then is for
> HTTPHeaderAuthenticationProvider to extend FileAuthenticationProvider...
>
>
> In general extensions are loaded and processed in alphabetical order, but
> FileAuthenticationProvider is always loaded and processed last. However, the
> overall order only matters in certain corner
> cases for stacking, and, in this case, the order does not matter so much as
> the fact that FileAuthenticationProvider does not implement
> authenticateUser(). I could be wrong about that, but I'm
> reasonably certain that's the issue.
Thanks. I confirm that is exactly as you say.
>
>
> As for HTTPHeaderAuthenticationProvider implementation, I am a bit
> concerned. It uses such powerful tool as Guice / IoC just to perform static
> bindings? Then it's an overkill.
>
>
> HTTPHeaderAuthenticationProvider only uses Guice to process configuration
> information. It is quite possible it is slightly overkill for this
> implementation, and you're certainly welcome to propose
> changes and submit pull requests if you have an idea of how it can be done
> more efficiently.
>
>
>> You say that you don't get automatically connected to the VNC server -
>> do you see the connection at all on the home screen? Or is it a blank
>> screen, with no connections?
> I don't see any connections on home screen. In other words, I see only
> blank white panes.
>
>
> Yeah, this further indicates that the File provider does not stack with the
> other modules.
>
>
>> My suggestion would be to use the JDBC module to store connections. It
>> requires a little bit of extra work and a few extra resources to configure,
>> but definitey works with the other modules
>> and also gives you some flexibility in permission management among users.
> I would like not to go that way. Maybe it's not so complicated to setup,
> but I would like to keep everything simple.
>
>
> That's understandable; however, this means you really have two options:
> - Write a custom module, similar to the FileAuthenticationProvider, that
> reads input from a file and stacks correctly with other modules. This should
> be pretty straight-forward, especially if you
> just want to write a module that contains configurations and not actual
> authentication information, and just map users or groups to those
> configurations.
With my respect to GUACAMOLE-493
<https://issues.apache.org/jira/browse/GUACAMOLE-493> and GUACAMOLE-256
<https://issues.apache.org/jira/browse/GUACAMOLE-256> after removing
guacamole-auth-noauth
Guacamole provided no means to replace it. It actually did what you say, and
only was missing a header check.
> - Propose changes to the FileAuthenticationProvider that allows it to "stack"
> with the other modules, and (possibly, if you're up to it) submit a pull
> request for those changes and have that
> functionality added to a future version (1.1.0 scope is fixed, so it would be
> 1.2.0 or later).
As I shown above, "stacking" of FileAuthenticationProvider is possible, but
requires opening other doors, which I am not sure is correct.
>
>
>> The File provider handles both cases - either the single connection
>> specified within the <authorize></authorize> context, or multiple
>> connections specified within their own
>> <connection></connection> contexts.
> Could you please put that phrase into documentation? As an option I can
> create a pull request.
>
>
> http://guacamole.apache.org/doc/gug/configuring-guacamole.html#basic-auth
>
> We can be more explicit about it if you think it necessary, but I'm
> reasonably certain the examples in the documentation cover both scenarios.
>
Thanks for comments & explanations!
--
With best regards,
Dmitry
---
guacamole/src/main/java/org/apache/guacamole/auth/file/FileAuthenticationProvider.java.orig
2018-12-05 23:32:37.000000000 +0100
+++
guacamole/src/main/java/org/apache/guacamole/auth/file/FileAuthenticationProvider.java
2019-03-22 00:48:56.393284100 +0100
@@ -28,8 +28,11 @@
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.environment.Environment;
import org.apache.guacamole.environment.LocalEnvironment;
+import org.apache.guacamole.net.auth.AuthenticatedUser;
import org.apache.guacamole.net.auth.Credentials;
+import org.apache.guacamole.net.auth.UserContext;
import org.apache.guacamole.net.auth.simple.SimpleAuthenticationProvider;
+import org.apache.guacamole.net.auth.simple.SimpleUserContext;
import org.apache.guacamole.xml.DocumentHandler;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
import org.slf4j.Logger;
@@ -169,6 +172,34 @@
}
+ @Override
+ public UserContext getUserContext(AuthenticatedUser authenticatedUser)
+ throws GuacamoleException {
+
+ Map<String, GuacamoleConfiguration> configs =
+
getAuthorizedConfigurations(authenticatedUser.getCredentials());
+
+ if (configs == null) {
+ // Abort authorization if no user mapping exists
+ UserMapping userMapping = getUserMapping();
+ if (userMapping == null)
+ return null;
+
+ // Validate and return info for given user and pass
+ Authorization auth =
userMapping.getAuthorization(authenticatedUser.getIdentifier());
+
+ if (auth != null)
+ configs = auth.getConfigurations();
+
+ if (configs == null)
+ return null;
+ }
+
+ // Return user context restricted to authorized configs
+ return new SimpleUserContext(this, authenticatedUser.getIdentifier(),
configs);
+
+ }
+
@Override
public Map<String, GuacamoleConfiguration>
getAuthorizedConfigurations(Credentials credentials)
---
extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/user/AuthenticatedUser.java.orig
2018-12-05 23:32:37.000000000 +0100
+++
extensions/guacamole-auth-header/src/main/java/org/apache/guacamole/auth/header/user/AuthenticatedUser.java
2019-03-22 00:54:57.597802800 +0100
@@ -54,8 +54,9 @@
* The credentials provided when this user was authenticated.
*/
public void init(String username, Credentials credentials) {
- this.credentials = credentials;
setIdentifier(username.toLowerCase());
+ this.credentials = credentials;
+ this.credentials.setUsername(getIdentifier());
}
@Override
---
guacamole/src/main/java/org/apache/guacamole/auth/file/Authorization.java.orig
2018-12-05 23:32:37.000000000 +0100
+++ guacamole/src/main/java/org/apache/guacamole/auth/file/Authorization.java
2019-03-22 01:16:34.969670500 +0100
@@ -23,6 +23,7 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
+import java.util.Objects;
import java.util.TreeMap;
import org.apache.guacamole.protocol.GuacamoleConfiguration;
@@ -178,8 +179,7 @@
public boolean validate(String username, String password) {
// If username matches
- if (username != null && password != null
- && username.equals(this.username)) {
+ if (username != null && username.equals(this.username)) {
switch (encoding) {
@@ -187,7 +187,7 @@
case PLAIN_TEXT:
// Compare plaintext
- return password.equals(this.password);
+ return Objects.equals(password, this.password);
// If hased with MD5, hash password and compare
case MD5: