You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@guacamole.apache.org by GitBox <gi...@apache.org> on 2022/06/15 22:48:29 UTC

[GitHub] [guacamole-client] jmuehlner opened a new pull request, #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

jmuehlner opened a new pull request, #736:
URL: https://github.com/apache/guacamole-client/pull/736

   As discussed in https://issues.apache.org/jira/browse/GUACAMOLE-1623, this allows the KSM vault extension to 
   
   * read a domain token out of records in the vault directly, 
   
   * or to split the username field into domain and username tokens if no domain is directly defined, if the username matches the expected formats as seen at https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name, and if the configuration property is enabled.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902954310


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/DomainAndUsername.java:
##########
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class that implements to attempts to split a username from a vault into a
+ * Windows domain and username, and stores the result of this operation.

Review Comment:
   How does this look?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] mike-jumper merged pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
mike-jumper merged PR #736:
URL: https://github.com/apache/guacamole-client/pull/736


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902863241


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/util/FieldParsingUtil.java:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * A set of utility methods for parsing field values for records retrieved
+ * from vaults.
+ */
+public class FieldParsingUtil {
+
+    /**
+     * A pattern for matching a down-level logon name containing a Windows
+     * domain and username - e.g. domain\\user. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#down-level-logon-name
+     */
+    private static final Pattern DOWN_LEVEL_LOGON_NAME_PATTERN = Pattern.compile(
+            "(?<domain>[^@\\\\]+)\\\\(?<username>[^@\\\\]+)");
+
+    /**
+     * A pattern for matching a user principal name containing a Windows
+     * domain and username - e.g. user@domain. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name
+     */
+    private static final  Pattern USER_PRINCIPAL_NAME_PATTERN = Pattern.compile(
+            "(?<username>[^@\\\\]+)@(?<domain>[^@\\\\]+)");
+
+    /**
+     * A class representating the result of attempting to split a username from
+     * a vault into a Windows domain and username. The username field will always
+     * be set, but if no domain was extracted, the domain field will be null.
+     */
+    public static class DomainAndUsername {
+
+        /**
+         * The username associated with the potential Windows domain/username
+         * value. If no domain is found, the username field will contain the
+         * entire value as read from the vault.
+         */
+        private final String username;
+
+        /**
+         * The dinaun associated with the potential Windows domain/username
+         * value. If no domain is found, this will be null.
+         */
+        private final String domain;
+
+        /**
+         * Create a DomainAndUsername record with no associated domain.
+         *
+         * @param username
+         *     The username, which should be the entire value as extracted
+         *     from the vault.
+         */
+        private DomainAndUsername(@NonNull String username) {
+            this.username = username;
+            this.domain = null;
+        }
+
+        /**
+         * Create a DomainAndUsername record with a username and a domain.
+         *
+         * @param username
+         *     The username portion of the field value from the vault.
+         *
+         * @param domain
+         *     The domain portion of the field value from the vault.
+         */
+        private DomainAndUsername(
+                @NonNull String username, @NonNull String domain) {
+            this.username = username;
+            this.domain = domain;
+        }
+
+        /**
+         * Return the value of the username as extracted from the vault field.
+         * If the domain is null, this will be the entire field value.
+         *
+         * @return
+         *     The username value as extracted from the vault field.
+         */
+        public String getUsername() {
+            return username;
+        }
+
+        /**
+         * Return the value of the domain as extracted from the vault field.
+         * If this is null, it means that no domain was found in the vault field.
+         *
+         * @return
+         *     The domain value as extracted from the vault field.
+         */
+        public String getDomain() {
+            return domain;
+        }
+
+        /**
+         * Return true if a domain was found in the vault field, false otherwise.
+         *
+         * @return
+         */
+        public boolean hasDomain() {
+            return this.domain != null;
+        }
+
+    }
+
+    /**
+     * Strip off a Windows domain from the provided username, if one is
+     * present. For example: "DOMAIN\\user" or "user@DOMAIN" will both
+     * be stripped to just "user". Note: neither the '@' or '\\' characters
+     * are valid in Windows usernames.
+     *
+     * @param vaultField
+     *     The raw field value as retrieved from the vault. This might contain
+     *     a Windows domain.
+     *
+     * @return
+     *     The provided username with the Windows domain stripped off, if one
+     *     is present.
+     */
+    public static DomainAndUsername splitWindowsUsernameFromDomain(String vaultField) {
+
+        // If it's the down-level logon format, return the extracted username and domain
+        Matcher downLevelLogonMatcher = DOWN_LEVEL_LOGON_NAME_PATTERN.matcher(vaultField);
+        if (downLevelLogonMatcher.matches())
+            return new DomainAndUsername(
+                    downLevelLogonMatcher.group("username"),
+                    downLevelLogonMatcher.group("domain"));
+
+        // If it's the user principal format, return the extracted username and domain
+        Matcher userPrincipalMatcher = USER_PRINCIPAL_NAME_PATTERN.matcher(vaultField);
+        if (userPrincipalMatcher.matches())
+            return new DomainAndUsername(
+                    userPrincipalMatcher.group("username"),
+                    userPrincipalMatcher.group("domain"));
+
+        // If none of the expected formats matched, return the username with do domain
+        return new DomainAndUsername(vaultField);
+
+    }

Review Comment:
   Sure



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] mike-jumper commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
mike-jumper commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r904252506


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/WindowsUsername.java:
##########
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class representing a Windows username, which may optionally also include
+ * a domain. This class can be used to parse the username and domain out of a
+ * username from a vault.
+ */
+public class WindowsUsername {
+
+    /**
+     * A pattern for matching a down-level logon name containing a Windows
+     * domain and username - e.g. domain\\user. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#down-level-logon-name
+     */
+    private static final Pattern DOWN_LEVEL_LOGON_NAME_PATTERN = Pattern.compile(
+            "(?<domain>[^@\\\\]+)\\\\(?<username>[^@\\\\]+)");
+
+    /**
+     * A pattern for matching a user principal name containing a Windows
+     * domain and username - e.g. user@domain. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name
+     */
+    private static final  Pattern USER_PRINCIPAL_NAME_PATTERN = Pattern.compile(
+            "(?<username>[^@\\\\]+)@(?<domain>[^@\\\\]+)");
+
+    /**
+     * The username associated with the potential Windows domain/username
+     * value. If no domain is found, the username field will contain the
+     * entire value as read from the vault.
+     */
+    private final String username;
+
+    /**
+     * The dinaun associated with the potential Windows domain/username
+     * value. If no domain is found, this will be null.
+     */
+    private final String domain;
+
+    /**
+     * Create a WindowsUsername record with no associated domain.
+     *
+     * @param username
+     *     The username, which should be the entire value as extracted
+     *     from the vault.
+     */
+    private WindowsUsername(@Nonnull String username) {
+        this.username = username;
+        this.domain = null;
+    }
+
+    /**
+     * Create a WindowsUsername record with a username and a domain.
+     *
+     * @param username
+     *     The username portion of the field value from the vault.
+     *
+     * @param domain
+     *     The domain portion of the field value from the vault.
+     */
+    private WindowsUsername(
+            @Nonnull String username, @Nonnull String domain) {
+        this.username = username;
+        this.domain = domain;
+    }
+
+    /**
+     * Return the value of the username as extracted from the vault field.
+     * If the domain is null, this will be the entire field value.
+     *
+     * @return
+     *     The username value as extracted from the vault field.
+     */
+    public String getUsername() {
+        return username;
+    }
+
+    /**
+     * Return the value of the domain as extracted from the vault field.
+     * If this is null, it means that no domain was found in the vault field.
+     *
+     * @return
+     *     The domain value as extracted from the vault field.
+     */
+    public String getDomain() {
+        return domain;
+    }
+
+    /**
+     * Return true if a domain was found in the vault field, false otherwise.
+     *
+     * @return
+     */

Review Comment:
   Oops - missing the description here.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] mike-jumper commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
mike-jumper commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902931556


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/DomainAndUsername.java:
##########
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class that implements to attempts to split a username from a vault into a
+ * Windows domain and username, and stores the result of this operation.

Review Comment:
   > A class that implements to attempts to split a username ...
   
   "Implements to attempts" sounds odd to me, but either way - this class is a representation of a Windows username, no? It does have a convenience method for splitting a username, but the class itself is the representation of a username and optional domain, not specifically a domain+username parser.



##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/util/FieldParsingUtil.java:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * A set of utility methods for parsing field values for records retrieved
+ * from vaults.
+ */
+public class FieldParsingUtil {

Review Comment:
   With `DomainAndUsername` now existing on its own, this class should be deleted.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] mike-jumper commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
mike-jumper commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r904241188


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/DomainAndUsername.java:
##########
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class that implements to attempts to split a username from a vault into a
+ * Windows domain and username, and stores the result of this operation.

Review Comment:
   Looks much better.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r904349590


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/WindowsUsername.java:
##########
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class representing a Windows username, which may optionally also include
+ * a domain. This class can be used to parse the username and domain out of a
+ * username from a vault.
+ */
+public class WindowsUsername {
+
+    /**
+     * A pattern for matching a down-level logon name containing a Windows
+     * domain and username - e.g. domain\\user. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#down-level-logon-name
+     */
+    private static final Pattern DOWN_LEVEL_LOGON_NAME_PATTERN = Pattern.compile(
+            "(?<domain>[^@\\\\]+)\\\\(?<username>[^@\\\\]+)");
+
+    /**
+     * A pattern for matching a user principal name containing a Windows
+     * domain and username - e.g. user@domain. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name
+     */
+    private static final  Pattern USER_PRINCIPAL_NAME_PATTERN = Pattern.compile(
+            "(?<username>[^@\\\\]+)@(?<domain>[^@\\\\]+)");
+
+    /**
+     * The username associated with the potential Windows domain/username
+     * value. If no domain is found, the username field will contain the
+     * entire value as read from the vault.
+     */
+    private final String username;
+
+    /**
+     * The dinaun associated with the potential Windows domain/username
+     * value. If no domain is found, this will be null.
+     */
+    private final String domain;
+
+    /**
+     * Create a WindowsUsername record with no associated domain.
+     *
+     * @param username
+     *     The username, which should be the entire value as extracted
+     *     from the vault.
+     */
+    private WindowsUsername(@Nonnull String username) {
+        this.username = username;
+        this.domain = null;
+    }
+
+    /**
+     * Create a WindowsUsername record with a username and a domain.
+     *
+     * @param username
+     *     The username portion of the field value from the vault.
+     *
+     * @param domain
+     *     The domain portion of the field value from the vault.
+     */
+    private WindowsUsername(
+            @Nonnull String username, @Nonnull String domain) {
+        this.username = username;
+        this.domain = domain;
+    }
+
+    /**
+     * Return the value of the username as extracted from the vault field.
+     * If the domain is null, this will be the entire field value.
+     *
+     * @return
+     *     The username value as extracted from the vault field.
+     */
+    public String getUsername() {
+        return username;
+    }
+
+    /**
+     * Return the value of the domain as extracted from the vault field.
+     * If this is null, it means that no domain was found in the vault field.
+     *
+     * @return
+     *     The domain value as extracted from the vault field.
+     */
+    public String getDomain() {
+        return domain;
+    }
+
+    /**
+     * Return true if a domain was found in the vault field, false otherwise.
+     *
+     * @return
+     */

Review Comment:
   Fixed!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902936912


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/util/FieldParsingUtil.java:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * A set of utility methods for parsing field values for records retrieved
+ * from vaults.
+ */
+public class FieldParsingUtil {

Review Comment:
   Ack, sorry. I thought I had done that.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] mike-jumper commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
mike-jumper commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902780723


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/test/java/org/apache/guacamole/vault/util/FieldParsingUtilTest.java:
##########
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import org.apache.guacamole.vault.util.FieldParsingUtil.DomainAndUsername;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+/**
+ * Class to test methods in the QCParser utility class.
+ */
+public class FieldParsingUtilTest {
+
+    /**
+     * Verify that the splitWindowsUsernameFromDomain() method correctly strips Windows
+     * domains from provided usernames that include them, and does not modify
+     * usernames that do not have Windows domains.
+     */
+    @Test
+    public void testSplitWindowsUsernameFromDomain() {
+
+        DomainAndUsername usernameAndDomain;
+
+        // If no Windows domain is present in the provided field, the username should
+        // contain the entire field, and no domain should be returned
+        usernameAndDomain = FieldParsingUtil.splitWindowsUsernameFromDomain("bob");
+        assertEquals(usernameAndDomain.getUsername(), "bob");
+        assertFalse(usernameAndDomain.hasDomain());
+
+        // It should parse down-level logon name style domains
+        usernameAndDomain = FieldParsingUtil.splitWindowsUsernameFromDomain("localhost\\bob");
+        assertEquals("bob", usernameAndDomain.getUsername(), "bob");
+        assertTrue(usernameAndDomain.hasDomain());
+        assertEquals("localhost", usernameAndDomain.getDomain());
+
+        // It should parse user principal name style domains
+        usernameAndDomain = FieldParsingUtil.splitWindowsUsernameFromDomain("bob@localhost");
+        assertEquals("bob", usernameAndDomain.getUsername(), "bob");
+        assertTrue(usernameAndDomain.hasDomain());
+        assertEquals("localhost", usernameAndDomain.getDomain());
+
+        // It should not match if there are an invalid number of seperators
+        List<String> invalidSeperators = List.of(

Review Comment:
   separator*



##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/util/FieldParsingUtil.java:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * A set of utility methods for parsing field values for records retrieved
+ * from vaults.
+ */
+public class FieldParsingUtil {
+
+    /**
+     * A pattern for matching a down-level logon name containing a Windows
+     * domain and username - e.g. domain\\user. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#down-level-logon-name
+     */
+    private static final Pattern DOWN_LEVEL_LOGON_NAME_PATTERN = Pattern.compile(
+            "(?<domain>[^@\\\\]+)\\\\(?<username>[^@\\\\]+)");
+
+    /**
+     * A pattern for matching a user principal name containing a Windows
+     * domain and username - e.g. user@domain. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name
+     */
+    private static final  Pattern USER_PRINCIPAL_NAME_PATTERN = Pattern.compile(
+            "(?<username>[^@\\\\]+)@(?<domain>[^@\\\\]+)");
+
+    /**
+     * A class representating the result of attempting to split a username from
+     * a vault into a Windows domain and username. The username field will always
+     * be set, but if no domain was extracted, the domain field will be null.
+     */
+    public static class DomainAndUsername {
+
+        /**
+         * The username associated with the potential Windows domain/username
+         * value. If no domain is found, the username field will contain the
+         * entire value as read from the vault.
+         */
+        private final String username;
+
+        /**
+         * The dinaun associated with the potential Windows domain/username
+         * value. If no domain is found, this will be null.
+         */
+        private final String domain;
+
+        /**
+         * Create a DomainAndUsername record with no associated domain.
+         *
+         * @param username
+         *     The username, which should be the entire value as extracted
+         *     from the vault.
+         */
+        private DomainAndUsername(@NonNull String username) {
+            this.username = username;
+            this.domain = null;
+        }
+
+        /**
+         * Create a DomainAndUsername record with a username and a domain.
+         *
+         * @param username
+         *     The username portion of the field value from the vault.
+         *
+         * @param domain
+         *     The domain portion of the field value from the vault.
+         */
+        private DomainAndUsername(
+                @NonNull String username, @NonNull String domain) {
+            this.username = username;
+            this.domain = domain;
+        }
+
+        /**
+         * Return the value of the username as extracted from the vault field.
+         * If the domain is null, this will be the entire field value.
+         *
+         * @return
+         *     The username value as extracted from the vault field.
+         */
+        public String getUsername() {
+            return username;
+        }
+
+        /**
+         * Return the value of the domain as extracted from the vault field.
+         * If this is null, it means that no domain was found in the vault field.
+         *
+         * @return
+         *     The domain value as extracted from the vault field.
+         */
+        public String getDomain() {
+            return domain;
+        }
+
+        /**
+         * Return true if a domain was found in the vault field, false otherwise.
+         *
+         * @return
+         */
+        public boolean hasDomain() {
+            return this.domain != null;
+        }
+
+    }
+
+    /**
+     * Strip off a Windows domain from the provided username, if one is
+     * present. For example: "DOMAIN\\user" or "user@DOMAIN" will both
+     * be stripped to just "user". Note: neither the '@' or '\\' characters
+     * are valid in Windows usernames.
+     *
+     * @param vaultField
+     *     The raw field value as retrieved from the vault. This might contain
+     *     a Windows domain.
+     *
+     * @return
+     *     The provided username with the Windows domain stripped off, if one
+     *     is present.
+     */
+    public static DomainAndUsername splitWindowsUsernameFromDomain(String vaultField) {
+
+        // If it's the down-level logon format, return the extracted username and domain
+        Matcher downLevelLogonMatcher = DOWN_LEVEL_LOGON_NAME_PATTERN.matcher(vaultField);
+        if (downLevelLogonMatcher.matches())
+            return new DomainAndUsername(
+                    downLevelLogonMatcher.group("username"),
+                    downLevelLogonMatcher.group("domain"));
+
+        // If it's the user principal format, return the extracted username and domain
+        Matcher userPrincipalMatcher = USER_PRINCIPAL_NAME_PATTERN.matcher(vaultField);
+        if (userPrincipalMatcher.matches())
+            return new DomainAndUsername(
+                    userPrincipalMatcher.group("username"),
+                    userPrincipalMatcher.group("domain"));
+
+        // If none of the expected formats matched, return the username with do domain
+        return new DomainAndUsername(vaultField);
+
+    }

Review Comment:
   Rather than establish a general parsing utility class for all future parsing needs, I suggest instead just defining `DomainAndUsername` and let it do-one-thing-and-do-it-well. ie:
   
   `DomainAndUsername.split(someFieldValue)`
   
   rather than:
   
   `FieldParsingUtil.DomainAndUsername` and `FieldParsingUtil.splitWindowsUsernameFromDomain(someFieldValue)`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902938467


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/secret/DomainAndUsername.java:
##########
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.secret;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+/**
+ * A class that implements to attempts to split a username from a vault into a
+ * Windows domain and username, and stores the result of this operation.

Review Comment:
   Lemme reword the comment (and rename the class) to make things a bit clearer.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [guacamole-client] jmuehlner commented on a diff in pull request #736: GUACAMOLE-1623: Extract domain field directly from the vault, or split out of username.

Posted by GitBox <gi...@apache.org>.
jmuehlner commented on code in PR #736:
URL: https://github.com/apache/guacamole-client/pull/736#discussion_r902903287


##########
extensions/guacamole-vault/modules/guacamole-vault-base/src/main/java/org/apache/guacamole/vault/util/FieldParsingUtil.java:
##########
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.guacamole.vault.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+/**
+ * A set of utility methods for parsing field values for records retrieved
+ * from vaults.
+ */
+public class FieldParsingUtil {
+
+    /**
+     * A pattern for matching a down-level logon name containing a Windows
+     * domain and username - e.g. domain\\user. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#down-level-logon-name
+     */
+    private static final Pattern DOWN_LEVEL_LOGON_NAME_PATTERN = Pattern.compile(
+            "(?<domain>[^@\\\\]+)\\\\(?<username>[^@\\\\]+)");
+
+    /**
+     * A pattern for matching a user principal name containing a Windows
+     * domain and username - e.g. user@domain. For more information, see
+     * https://docs.microsoft.com/en-us/windows/win32/secauthn/user-name-formats#user-principal-name
+     */
+    private static final  Pattern USER_PRINCIPAL_NAME_PATTERN = Pattern.compile(
+            "(?<username>[^@\\\\]+)@(?<domain>[^@\\\\]+)");
+
+    /**
+     * A class representating the result of attempting to split a username from
+     * a vault into a Windows domain and username. The username field will always
+     * be set, but if no domain was extracted, the domain field will be null.
+     */
+    public static class DomainAndUsername {
+
+        /**
+         * The username associated with the potential Windows domain/username
+         * value. If no domain is found, the username field will contain the
+         * entire value as read from the vault.
+         */
+        private final String username;
+
+        /**
+         * The dinaun associated with the potential Windows domain/username
+         * value. If no domain is found, this will be null.
+         */
+        private final String domain;
+
+        /**
+         * Create a DomainAndUsername record with no associated domain.
+         *
+         * @param username
+         *     The username, which should be the entire value as extracted
+         *     from the vault.
+         */
+        private DomainAndUsername(@NonNull String username) {
+            this.username = username;
+            this.domain = null;
+        }
+
+        /**
+         * Create a DomainAndUsername record with a username and a domain.
+         *
+         * @param username
+         *     The username portion of the field value from the vault.
+         *
+         * @param domain
+         *     The domain portion of the field value from the vault.
+         */
+        private DomainAndUsername(
+                @NonNull String username, @NonNull String domain) {
+            this.username = username;
+            this.domain = domain;
+        }
+
+        /**
+         * Return the value of the username as extracted from the vault field.
+         * If the domain is null, this will be the entire field value.
+         *
+         * @return
+         *     The username value as extracted from the vault field.
+         */
+        public String getUsername() {
+            return username;
+        }
+
+        /**
+         * Return the value of the domain as extracted from the vault field.
+         * If this is null, it means that no domain was found in the vault field.
+         *
+         * @return
+         *     The domain value as extracted from the vault field.
+         */
+        public String getDomain() {
+            return domain;
+        }
+
+        /**
+         * Return true if a domain was found in the vault field, false otherwise.
+         *
+         * @return
+         */
+        public boolean hasDomain() {
+            return this.domain != null;
+        }
+
+    }
+
+    /**
+     * Strip off a Windows domain from the provided username, if one is
+     * present. For example: "DOMAIN\\user" or "user@DOMAIN" will both
+     * be stripped to just "user". Note: neither the '@' or '\\' characters
+     * are valid in Windows usernames.
+     *
+     * @param vaultField
+     *     The raw field value as retrieved from the vault. This might contain
+     *     a Windows domain.
+     *
+     * @return
+     *     The provided username with the Windows domain stripped off, if one
+     *     is present.
+     */
+    public static DomainAndUsername splitWindowsUsernameFromDomain(String vaultField) {
+
+        // If it's the down-level logon format, return the extracted username and domain
+        Matcher downLevelLogonMatcher = DOWN_LEVEL_LOGON_NAME_PATTERN.matcher(vaultField);
+        if (downLevelLogonMatcher.matches())
+            return new DomainAndUsername(
+                    downLevelLogonMatcher.group("username"),
+                    downLevelLogonMatcher.group("domain"));
+
+        // If it's the user principal format, return the extracted username and domain
+        Matcher userPrincipalMatcher = USER_PRINCIPAL_NAME_PATTERN.matcher(vaultField);
+        if (userPrincipalMatcher.matches())
+            return new DomainAndUsername(
+                    userPrincipalMatcher.group("username"),
+                    userPrincipalMatcher.group("domain"));
+
+        // If none of the expected formats matched, return the username with do domain
+        return new DomainAndUsername(vaultField);
+
+    }

Review Comment:
   It's done.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org