Replies: 28 comments 9 replies
-
To support autocompletion, you'll want to take a look at: You can pass in '\t' for the key and a handler which accepts the current input line and cursor position and which returns an updated input line and cursor position as a tuple. This assume you want line editing capability on the user's input and just want to add tab completion to the exiting editing support. As for supporting keyboard-interactive authentication, you'll need to implement a few different methods in your SSHServer subclass. First, have kbdint_auth_supported() return |
Beta Was this translation helpful? Give feedback.
-
Hello, Thanks for your answer. Same question for auth do you have any example ? (in my app i just need to replace char in password with *** then the password is send to a another custom client and finally sent to a device over serial connection) My design is Serial Device <=> Phone <=> AsyncSSH Server <=> MultipleClient working on serial device. |
Beta Was this translation helpful? Give feedback.
-
Hey the Tab handler work fine |
Beta Was this translation helpful? Give feedback.
-
Glad to hear you got the tab handler working! That confirms that you are already using the line editor, which makes sense. It is enabled by default on all server connections where the client requests a PTY. You don't need to subclass SSHLineEditorChannel or set any other configuration options for this. Regarding the authentication, are you trying to use keyboard-interactive authentication on the your SSHServer, on your outbound SSH clients, or both? If you are trying to use it on both, passing through the challenges and responses, whatever the server does to not echo the password when it prompt for it should carry through to the clients. You won't be able to print "*" when entering the password in that case, but it should disable echo entirely while prompting for the password. In addition to the prompt string, there's a boolean that gets passed for each prompt saying whether to enable echo or not. If you are prompting for the auth yourself, you should be able to call a set_echo() method on the SSH channel (which is really an SSHLineEditorChannel in this case) before you prompt for the password yourself to achieve a similar result. See https://asyncssh.readthedocs.io/en/latest/#line-editing for an example. |
Beta Was this translation helpful? Give feedback.
-
Thanks for your answer i will try echo off for password i think it will be enough. Regarding my tab handler can you tell me if what i m trying to do is even possible ? Do you think it's possible to do this with asynssh ? (Stop the readline process while my handler is waiting an answer then put it back to run ?) My quick & dirty code:
|
Beta Was this translation helpful? Give feedback.
-
Hello, I will go deeper in asyncssh function because for now after function is call Thanks for your help i was like a blind guy in a forest >< asyncio.Event() global_tabbed = asyncio.Event()
|
Beta Was this translation helpful? Give feedback.
-
Any solution to have a global variable protected with RLock in async function ? I try to declare a top file global variable but it seem's instantiated, when i use a variable in a ChatClient instance it work (but each time i want to access this variable i have to look for the good ChatClient first ><) |
Beta Was this translation helpful? Give feedback.
-
Hello, As example on a Normal Serial communication when i start 'conf sys' and press tab i got a simple response 'conf system'. And i got the same kind of ESC [ XX sequence on linux tab autocompletion so i assume there's a standard but i m not able to point out the name of this standard and finally got any documentation ... So if you have any knowledge on this standard name it will be a hudge unblock for me ;) |
Beta Was this translation helpful? Give feedback.
-
This looks like standard ANSI escape sequences, as documented at https://en.wikipedia.org/wiki/ANSI_escape_code. For "ESC [" sequences, see the "CSI" section of that doc. More specifically, ESC [ n D is actually a "move cursor left n cells" and then ESC [ K is "clear to end of line". I don't recognize the sequence with "@" there. There are other "cursor move" sequence for going up (A instead of D), down (B), and right ©, but you probably wouldn't run into those with tab completion redrawing. As you can see from the URL above, there are a LOT of these, but you probably only need to know about a few of them for this use case. |
Beta Was this translation helpful? Give feedback.
-
That a great start thanks for the link. SERIAL DEVICE <==> PC with asyncssh client <==== > Asyncssh server <====> putty So when i press TAB (from putty) it send the Tab to the serial device got the reponse and process it back to putty. At the moment i catch Tab response not in tab_handler because im unable on asynchssh server to wait for the asynchssh client reponse. Is there a way to wait on a handler for another process response before answering to Putty ? |
Beta Was this translation helpful? Give feedback.
-
The purpose is to have also the possibility to see with multiple putty client the same session for support needs. Putty guy 1<------+ At the moment i have a correct authent with group mapping and role then after a putty guy choose a group i run This code handle only line with \n Is there a way to get a function execution when a simple char is received ? based on https://asyncssh.readthedocs.io/en/latest/#serving-multiple-clients Thanks for your help it's really apreciated |
Beta Was this translation helpful? Give feedback.
-
If you are accessing a physical serial port by opening it as a "tty", you'll need to set something like raw mode on the TTY if you want it to return output immediately rather than waiting for a newline to output. You can use the "tty" module to do this, and more specifically call tty.setraw(fd), where fd is the file descriptor of the serial device. You'll probably also want to set line_editor=False in the AsyncSSH server, if you expect the AsyncSSH client to pass terminal type. If i understand right, you'll have both "PuTTY" client connections and AsyncSSH client connections (on devices with serial ports) connecting into a shared AsyncSSH server. That means you'll probably need some way to distinguish between the two so that the AsyncSSH server handles them differently. You can probably do this by specify different commands or subsystems to run when the AsyncSSH server receives a new session request. Also, you'll probably need some way for the PuTTY clients to specify which serial device that particular session should be attached to. |
Beta Was this translation helpful? Give feedback.
-
I add a property of ChatClient => user in the example of 'ChatClient' https://asyncssh.readthedocs.io/en/latest/#serving-multiple-clients To start server i use async def start_server(): class MySSHServer(asyncssh.SSHServer): The user property contain a role (That retrieved on authentication time on a remote BDD) then Putty user have to chose a group (An AsyncSSHClient & Serial) to be group with. AsyncSSH Client & Serial got an Echo Off and Putty user an Echo On based on user role Then after all of this choise they go in the main loop When this loop received a message it broacast it to group member. All of this is working fine. So if i user set line_editor=False i will have char input on the loop ? |
Beta Was this translation helpful? Give feedback.
-
Hello, it's a success at the moment Putty Stdin is in line mode (It help to capture CMD for server or Asyncssh client) and AsyncSSH client is in channel.set_line_mode(False) and it work really fine i have a native autocompletion from Serial to putty without any code need ;) Thanks a lot |
Beta Was this translation helpful? Give feedback.
-
In addition to turning off the line editor, I imagine you probably had to switch from the "async for" reading lines to calls to read() which could get whatever data was outstanding without waiting for a line boundary. If you also set the serial port connection into raw mode and did the same there with read() calls, it should be possible to copy bytes back and forth between the two as soon as the data came in, allowing the TTY on the serial port to send arbitrary escape sequences that would be rendered on all the SSH clients attached to reflect things like auto-completion. This is actually one case where using the "callback" API might be cleaner and simpler than the higher-level "stream" or "process" APIs, as you wouldn't need to create separate tasks which sat in async read() loops. The data_received() callback would just get called automatically whenever new data came in, and that could call write() on the associated sessions to perform the "broadcast". |
Beta Was this translation helpful? Give feedback.
-
Yes that it. I still did the choice to stay on line basis from putty to Asynchssh Server to AsynchSsh client for Command purpose (like change serial parameters from putty)
|
Beta Was this translation helpful? Give feedback.
-
Nice look for the '?' i add a handler to manage it and send only cmd ? and not cmd ?\n and it work fine. Thanks for the stdin.read(1024) it work really better than stdin.read(1) I will try the line mode off on putty side because as you mension it will be better to have a closer experience as connecting a serial device directly. Thanks for your help it was really helpful |
Beta Was this translation helpful? Give feedback.
-
I don't think Ctrl+$ is a valid key sequence, but I was thinking something similar where you'd go into "command mode" by hitting Ctrl-], similar to "telnet". AsyncSSH lets you enable/disable line editing at any time, so on the PuTTY connections you could turn on line editing right after seeing that keypress, and then turn it off again when the user went back to talking to the serial device, switching between readline() (or iterating on stdin with "async for" when in command mode but then going back to read() with a length the rest of the time. |
Beta Was this translation helpful? Give feedback.
-
Yes it work fine i was able to swap line_editing without any problem. |
Beta Was this translation helpful? Give feedback.
-
Yeah - Ctrl-@ seems pretty safe for this. If there's anything else you need or you have other questions, let me know! |
Beta Was this translation helpful? Give feedback.
-
I have one more question on the possibility to 'transfert' an ssh connection from a server to another. Do you know a 'simple' way to do this without any second authentication need ? |
Beta Was this translation helpful? Give feedback.
-
I'd need a little more detail about what kind of connections you had in mind, and whether you were using a custom client to make the connections or you were expecting to be able to forward a connection initiated from a standard client like OpenSSH or PuTTY. Here are some possible cases: Client -> Server1 -> Server2, where Server1 stays in the loop for the lifetime of the connection from the Client to Server2 and the SSH authentication is done first between the Client & Server1 and then between Server1 & Server2. In this case, the clients don't need to know how to authenticate to Server2 and don't even need to know traffic is being forwarded. However, both Server1 and Server2 end up seeing all the data. Because the client is unaware of any of this, it works with standard clients. A variation of this is Client -> Server1 -> Server2 where the client performs the authentication to both Server1 and Server2, and may even tell Server1 where to connect when forwarding the traffic. This is your standard "jump host" or "bastion host" use case. It can work with standard clients, but only if they actively participate in the authentication and forwarding. Also, you're effectively running SSH inside of SSH in this case, with data being encrypted twice. As above, Server1 has to stay in the loop the whole time and will end up having to forward all the data, but what it forwards is opaque since it will be an encrypted data stream between the Client and Server2. If you want to "transfer" a connection so that something starting off as Client -> Server1 ends up becoming Client -> Server2 with Server1 no longer involved, you need a custom client. After the client authenticates with Server1, it can be sent a message telling it to connect to Server2 instead, causing it to initiate a direct connection to Server2 and then close the connection to Server1. The client is responsible for doing auth on both of these connections, and it's as if the connections were entirely unrelated to one another. Unfortunately, there's no standard way in SSH to do the above kind of "transfer" in a way where authentication to Server2 is done by Server1 instead of the Client but data then flows directly from the Client to Server2 with Server1 no longer involved. If Server1 does the auth, it must remain in the loop after that shuffling the data back and forth between the Client and Server2. You can't do the key exchange on one connection but then use the agreed-upon key on a different connection. |
Beta Was this translation helpful? Give feedback.
-
I think you got my point, the purpose was to have server1 no longer involved without the second authentication need. The exact need is to have a first server (or set of server) to authenticate and dispatch all group member on the same second server in a second set of server. In this image Group 2 can be transfert to server 2. Is there a possibility to ask a putty client to connect to another server without the need of copy / past url on putty and restart a new putty windows? |
Beta Was this translation helpful? Give feedback.
-
Unfortunately, I don't know any way for an SSH server to send a "redirect" back to the client. Other protocols such as HTTP/HTTPS have this, but SSH doesn't. So, you'd need to have a custom client in order to be able to interpret such a message, which probably isn't an option in your application, at least not for the end-user SSH client connections. You could do something like that for connections from the serial port clients, but I'm not sure how useful that is. If you want to do this as a way for the end users to know have to know in advance which server a given serial connection is associated with, perhaps you could have Server 1 stay in the path forwarding traffic the whole time, though. To get better redundancy and scalability, you could have a pool of servers take on this role, with all of them having the ability to forward end-user connections to ANY of the SSH servers which are accepting requests from the serial port clients. When a serial port client connects to a server, that could be registered somewhere that the end-user servers have access to, so they know where to forward requests to depending on which serial port is requested by an end user. If you had a single DNS name which resolved to the IP addresses of all of the end-user servers, the load could automatically be spread across all of those servers, giving you redundancy and scalability while also eliminating the need for end users to know which serial port clients were connected where. |
Beta Was this translation helpful? Give feedback.
-
Hello, I try to set some environnement from the AsyncSSH client, i rewrite a simple ssh client class MySSHClientSession(asyncssh.SSHClientSession):
async def run_client() -> None: try: I don't pass the (the environnement is received on server) Any clue ? Also when i try i got error on asyncssh.DataType
|
Beta Was this translation helpful? Give feedback.
-
The DataType error is |
Beta Was this translation helpful? Give feedback.
-
I m on |
Beta Was this translation helpful? Give feedback.
-
Good point, upgrade clear the problem. I have a warning on \asyncssh\crypto\cipher.py:30: CryptographyDeprecationWarning: SEED has been deprecated I try to fix all algo with this in my connect
I work on this because i just realize that my Serial / SSH client is still using Paramiko in a thread instead of AsyncSSH CLient. At the moment i m unable to start the AsyncSSH Client without blocking my other Thread (because most of my code in the client use Thread) |
Beta Was this translation helpful? Give feedback.
-
Hello,
I customise a ssh server side for some purpose and i m not able to get any clue about how to handle 'tab' for autocompletion.
I m just unable to see any code entry when the client press tab.
I also try to implement keyboard interactive auth for other password in my session but same point at the moment i m not able to see how to raise this method on client side from my server.
I use the base from
https://asyncssh.readthedocs.io/en/latest/#serving-multiple-clients
If one of you have any clues it will be really appreciated
Beta Was this translation helpful? Give feedback.
All reactions