Skip to content
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

[Feature] Different user permissions #72

Closed
bannmann opened this issue Jan 27, 2024 · 9 comments · Fixed by #104
Closed

[Feature] Different user permissions #72

bannmann opened this issue Jan 27, 2024 · 9 comments · Fixed by #104

Comments

@bannmann
Copy link

Similar to online conferencing software like Zoom, Google Meet or MS Teams, sshx should distinguish user permission levels. This would greatly increase its usefulness in teaching settings (particularly with larger audiences of 10+ people), or in video conferences with attendees of mixed seniority levels.

Here is how I imagine this could work:

  • The first user to connect to the session becomes the host.
  • A session starts in "default" mode where every user has "full access" level. When the host activates "limited" mode, sshx moves every other user to "guest access", but still shows their mouse cursors and lets them enter chat messages. Users joining afterwards will also be on "guest access".
    • This way, the host can present stuff and others can point at things or ask questions, but nobody can goof around and disturb the presentation. Also, in case it's a production system, the host does not have to watch out for people doing dangerous stuff.
  • While in "limited" mode, the host may change each user from "guest access" to "full access" and back at any time.
    • This is useful if someone from the audience is supposed to take over for a while.
  • The host can leave "limited" mode at any time.
  • Additionally, there could be a feature allowing hosts to designate other users as co-hosts.
@jankatins
Copy link

Another ideas would be a --read-only share and the server on my host printing (and asking) if a command should be run

@webnerdnick

This comment was marked as duplicate.

@luochen1990
Copy link

Another related feature is: the host can confirm it before the command output shared to everyone.

The scenario is if the host check logs via journalctl and there is a pwd or token there, you will not hope it displayed to guests

@lukehsiao
Copy link

lukehsiao commented Nov 6, 2024

sshx is the best terminal sharing solution I've tried so far. However, I really just need a read-only mode. That is, my common use case is just sharing my terminal to many people, and I do not want them to be able to click/input or open other terminals (I often start a session, then open a tmux/zellij session and work in my own terminal directly, not in the web interface, so I do not want to have to check that people are not doing other things in other terminals in the web UI).

If this type of read-only broadcast is something fairly straightforward to implement (vs the more complex user permissions) I would be happy to help contribute.

@ekzhang
Copy link
Owner

ekzhang commented Nov 6, 2024

Okay makes sense! The tricky thing is that in sshx, only web clients may exist -- so read-only mode would require an additional secret / different URLs for the reader and writer.

It would probably require an API change as well as a frontend change. We could enable this when --read-only flag is passed in perhaps, or --read-only-mode or --enable-readers idk what the right flag name is right now

I'll take contributions for it!

@lukehsiao
Copy link

Okay makes sense! The tricky thing is that in sshx, only web clients may exist -- so read-only mode would require an additional secret / different URLs for the reader and writer.

It would probably require an API change as well as a frontend change. We could enable this when --read-only flag is passed in perhaps, or --read-only-mode or --enable-readers idk what the right flag name is right now

I'll take contributions for it!

I see, a little more involved then. Could you provide any pointers on grokking where those changes might need to happen?

@ekzhang
Copy link
Owner

ekzhang commented Nov 6, 2024

service SshxService {
// Create a new SSH session for a given computer.
rpc Open(OpenRequest) returns (OpenResponse);
// Stream real-time commands and terminal outputs to the session.
rpc Channel(stream ClientUpdate) returns (stream ServerUpdate);
// Gracefully shut down an existing SSH session.
rpc Close(CloseRequest) returns (CloseResponse);
}

This is the gRPC service definition used by the client. OpenRequest should take a new bool field for enabling readonly mode. Protobuf will default this to false for older clients that don't have the field. OpenResponse should return some kind of additional password needed to get write access to the terminal, which can be stored on the Metadata of the session (this needs to be persisted in snapshots also).

/// Static metadata for this session.
#[derive(Debug, Clone)]
pub struct Metadata {
/// Used to validate that clients have the correct encryption key.
pub encrypted_zeros: Bytes,
/// Name of the session (human-readable).
pub name: String,
}

On the web client, the WebSocket connection needs a way to authenticate with the write-access password. It's possible you just add that to Authenticate as an optional bytes field, since the web protocol doesn't need to be backwards-compatible like gRPC does.

/// A real-time message sent from the client over WebSocket.
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum WsClient {
/// Authenticate the user's encryption key by zeros block.
Authenticate(Bytes),
/// Set the name of the current user.
SetName(String),

Then the handler here can enable write-only mode based on whether that's set on the terminal and on checking the write-mode password via constant time comparison here

match recv(socket).await? {
Some(WsClient::Authenticate(bytes)) if bytes == metadata.encrypted_zeros => {}
_ => {
send(socket, WsServer::InvalidAuth()).await?;
return Ok(());
}
}

And on the frontend, in read-only mode we can perhaps show a little read-only indicator badge here, while also disabling edits on the XTerm terminals.

image

Additionally the CLI should print out URLs for both the read-only and writable modes.

@ChetanXpro
Copy link
Contributor

I'd like to contribute to implementing the read-only mode feature. I'll take a look at the codebase and come back with any questions if I need guidance.

@ChetanXpro
Copy link
Contributor

@ekzhang Do we need something like this?

For a writable link, we append the writer secret just after the encryption key and separate it with a comma. I think we can pass the password in a better and more secure way, let me know if you have any suggestions.

read-mode.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants