-
Notifications
You must be signed in to change notification settings - Fork 62
feat: username and password support for SSH connection type #1126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Pushed a super rough draft of auth handler logic this morning. Very rough around the edges but wanted to get thoughts down in some (semi) organized manner. Will further test and refine as time allows. |
|
First up, thank you for working on this. It'll be a big improvement for us. A few random thoughts:
From your top message: "Users should still be able to specify an identify file for keys that have a passphrase." ; do you mean "for keys that don't have a passphrase"? For keys that do, you would need to develop the ability to de-shield them after loading them from disk, to pass to the private key method. Probably safer to just expect users to set up ssh-agent, if that's where they're at. [although it's true that that is unfortunate on windows] |
client/src/connection/ssh/index.ts
Outdated
| this._config = c; | ||
| this.conn = new Client(); | ||
| this._conn = new Client(); | ||
| this._authMethods = ["publickey", "password", "keyboard-interactive"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attempt non-interactive methods first, falling back to interactive ones.
@chunky in a few test scenarios in house, I'm seeing the auth method for agent and public key coming back from the server simply as "publickey". I'm wondering if the library is adding in agent based on set config options?
Essentially, these strings are well known auth methods that are supported by ssh itself. I think it would be great to get these from the server by initially sending "none" up to prompt for a response. We need to then roll through the list of methods that we can support in the extension (which should be most of them except for the kerberos methods) and then make sure that before we try it, that it's in the "server supported list".
client/src/connection/ssh/index.ts
Outdated
| parsedKeyResult instanceof Error && | ||
| parsedKeyResult.message === | ||
| "Encrypted OpenSSH private key detected, but no passphrase given" | ||
| ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ssh2 library has a function that can assist with detecting that the key file specified on the config property is encrypted, which is a nice help to allow users to specify shielded and unshielded key paths on the connection profile (if they dont want to / cant use use agent). Right now with the code below if we detect a passphrase we'd prompt for it before sending it on. Generally I'm against storing these kinds of passphrases in a secret for reasons mentioned above. If a user wants passphrase persistence then perhaps agent is the ideal solution.
client/src/connection/ssh/index.ts
Outdated
| }); | ||
| } | ||
| } | ||
| } else if (process.env.SSH_AUTH_SOCK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty straightforward, this is the agent method that we supported in the before state. Users can still elect not to specify a key file on the connection profile and have the agent do all of the work (if they have set it up).
client/src/connection/ssh/index.ts
Outdated
| }); | ||
| } | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Support both password and keyboard-interactive. Prompt user "just in time".
All good feedback. I generally agree with thoughts above. I've put comments around changes that I think support these items. On the issue of whether or not to store the passwords in secrets, we have some precedent for doing this in other connection types. I do agree though that generally for ssh interaction with other solutions, anytime passwordless or passphraseless interactions are intended, that I've seen docs push users towards agent or public key. |
|
I would like to see the authentication method gssapi-with-mic added. This will be beneficial to those in corporate environments where Kerberos Tickets enable you to access other resources such as file systems, databases, APIs, etc ... while eliminating the need for the person to enter their credentials. |
|
If you can figure it out, yes, the kerberos SSO stuff is great where available. That was another thing I couldn't figure out. It works on some of our servers. Another of those "if it works it's magical and absolutely preferred". I think the distinction between "agent" and "public key" is a manifestation from the ssh2 library, not the server. In practice it might mean taking two bites at the key-based apple, which is explicitly afforded by the Auth handler mechanism |
Yea that's what the current changeset has, inside of "publickey" we'd look for whether or not the user has set their keyfile on the connection profile, if so we'd use that file, otherwise we'd defer to agent.
One challenge is that the ssh2 library doesnt support GSSAPI methods yet: |
|
@smorrisj I missed this comment from earlier: "I'm seeing the auth method for agent and public key coming back from the server simply as "publickey". I'm wondering if the library is adding in agent based on set config options?" From the server's perspective, these are the same thing; it just wants to do a key-based handshake. But on the client, they're different beasts. With ssh2's 'agent' they go get it from a daemon running on a socket, while 'publickey' is just a thing where you hand ssh2 the ready-to-use bytes. |
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| const SECOND = 1000; | ||
| export const KEEPALIVE_INTERVAL = 60 * SECOND; //How often (in milliseconds) to send SSH-level keepalive packets to the server. Set to 0 to disable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chunky any thoughts on going with these values for keepalive and max unanswered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smorrisj 60 seconds is a reasonable figure - I think I usually set it to 30, but I have no strong feelings as long as it's well inside 90.
The unanswered_threshold, I confess to be unsure about appropriate behaviour. If the comment is right, it's measured in "pings" not in "time". So if you're aiming for 12 hours, it should be (12 * HOUR / KEEPALIVE_INTERVAL). Either way, because this is happening at the SSH/networking level, then 12 hours is probably way too long. Maybe 15 minutes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Private key specified in privateKeyFilePath field in connection profile (with a passphrase)
|
|
There are two SSH connection profiles and both do not work properly. One was configured as an invalid private key file path, the other one was not reachable with error like 'getaddrinfo ENOTFOUND...', switch between the two profiles, run some code, it did not use the specified one. |
I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 482f2f2 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: bda97f1 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 86840c7 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 7404025 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 69b6664 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: cc667a4 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 38a575a I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: f0016cb I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 21284e4 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 8aa0c23 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 91a6d0f I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 0607d64 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 6ac98e8 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: a092524 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: debafaf I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: e0e26dd I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 51ce78a I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: ea17b75 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 3e1f267 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 76a271f I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 7a2c0b4 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 430f80b I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 04444a7 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 5f9ec57 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: d3c9cd2 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: 6d28a43 I, Joe Morris <[email protected]>, hereby add my Signed-off-by to this commit: a0b7f88 Signed-off-by: Joe Morris <[email protected]>
Fixed in a0b7f88 |
Refactored error handling to fix issues like this in a0b7f88 |
|
|
Private key specified in privateKeyFilePath field in connection profile (with a passphrase) |
|
The error handling code still wasnt quite right. Made another pass to refactor it to clean it up some: 6e46440 |
There was a lifecycle issue where the ssh socket was dangling open after the run errored out. Fixed in 6e46440 |
Fixed in 6e46440. We now properly close the ssh connection when the user cancels out of the passphrase dialog. Entering blank on password will be treated as an invalid password attempt. Retries allowed are governed by the ssh server settings. So for that it's possible that the user will continue to be prompted until the server responds with "Too many authentication failures", where it will then close the connection. |
|
There is no result output if specify a long workdir and a specific pagesize in sasOptions. |
The work dir code was setting up the value over multiple lines. In this approach, for long directory values we were getting log output intermixed in between the start element, end element, and directory value. Fixed in 2195eb9 |
@smorrisj I checked the issue in the latest PR build. I can still reproduce it if specify the page size as new value '23'. |
|
Thanks @Zhirong2022. The log parsing for detecting work dir still was not robust enough. Refactored the code that sets work dir to use a more structured logging output. See fix in cde43f0. |
|
All raised issues have been fixed. Feature: Public key specified in privateKeyFilePath field in connection profile (with a passphrase) Feature: Traditional username/password |
Summary
Todos:
Store password in Secrets API so that the user is not prompted for a password on each session establishment after initial profile creation.Use masked input field like we do for IOM on the text input prompt.setTimeoutlogic will need to be adjusted so that we dont errantly timeout while a user is typing in a password or passphrase.Testing
Connection Profile Prompts:
Auth Refactor:
Users can successfully authenticate to the server to run sas programs using the following auth methods:
Work Directory Detection
Keepalive Changes: