2023-10-17 06:31:13 +02:00
|
|
|
// Copyright 2023, Command Line Inc.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
2022-07-13 23:16:08 +02:00
|
|
|
package sstore
|
|
|
|
|
2022-09-01 21:47:10 +02:00
|
|
|
import (
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
"context"
|
2024-02-10 02:19:44 +01:00
|
|
|
"encoding/json"
|
2022-09-01 21:47:10 +02:00
|
|
|
"fmt"
|
2022-10-31 20:40:45 +01:00
|
|
|
"log"
|
2022-09-01 21:47:10 +02:00
|
|
|
"sync"
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
"time"
|
2023-12-26 21:59:25 +01:00
|
|
|
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/wavetermdev/waveterm/wavesrv/pkg/scpacket"
|
2022-09-01 21:47:10 +02:00
|
|
|
)
|
2022-07-13 23:16:08 +02:00
|
|
|
|
|
|
|
var MainBus *UpdateBus = MakeUpdateBus()
|
|
|
|
|
2022-07-16 02:37:32 +02:00
|
|
|
const PtyDataUpdateStr = "pty"
|
2022-08-24 11:14:16 +02:00
|
|
|
const ModelUpdateStr = "model"
|
2022-09-15 09:17:23 +02:00
|
|
|
const UpdateChSize = 100
|
2022-07-16 02:37:32 +02:00
|
|
|
|
|
|
|
type UpdatePacket interface {
|
2024-02-10 02:19:44 +01:00
|
|
|
// The key to use when marshalling to JSON and interpreting in the client
|
2022-07-16 02:37:32 +02:00
|
|
|
UpdateType() string
|
2023-05-09 01:06:51 +02:00
|
|
|
Clean()
|
2022-07-16 02:37:32 +02:00
|
|
|
}
|
|
|
|
|
2022-07-13 23:16:08 +02:00
|
|
|
type PtyDataUpdate struct {
|
2023-03-16 02:12:55 +01:00
|
|
|
ScreenId string `json:"screenid,omitempty"`
|
2023-07-31 02:16:43 +02:00
|
|
|
LineId string `json:"lineid,omitempty"`
|
2022-09-15 08:10:35 +02:00
|
|
|
RemoteId string `json:"remoteid,omitempty"`
|
2022-07-13 23:16:08 +02:00
|
|
|
PtyPos int64 `json:"ptypos"`
|
|
|
|
PtyData64 string `json:"ptydata64"`
|
|
|
|
PtyDataLen int64 `json:"ptydatalen"`
|
|
|
|
}
|
|
|
|
|
2023-05-09 01:06:51 +02:00
|
|
|
func (*PtyDataUpdate) UpdateType() string {
|
2022-07-16 02:37:32 +02:00
|
|
|
return PtyDataUpdateStr
|
|
|
|
}
|
|
|
|
|
2023-05-09 01:06:51 +02:00
|
|
|
func (pdu *PtyDataUpdate) Clean() {}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
// A collection of independent model updates to be sent to the client. Will be evaluated in order on the client.
|
|
|
|
type ModelUpdate []*ModelUpdateItem
|
2022-07-15 10:57:45 +02:00
|
|
|
|
2023-05-09 01:06:51 +02:00
|
|
|
func (*ModelUpdate) UpdateType() string {
|
2022-08-24 11:14:16 +02:00
|
|
|
return ModelUpdateStr
|
2022-07-16 02:37:32 +02:00
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
func (mu *ModelUpdate) MarshalJSON() ([]byte, error) {
|
|
|
|
rtn := make([]map[string]any, 0)
|
|
|
|
for _, u := range *mu {
|
|
|
|
m := make(map[string]any)
|
|
|
|
m[(*u).UpdateType()] = u
|
|
|
|
rtn = append(rtn, m)
|
2023-05-09 01:06:51 +02:00
|
|
|
}
|
2024-02-10 02:19:44 +01:00
|
|
|
return json.Marshal(rtn)
|
2023-05-09 01:06:51 +02:00
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
// An interface for all model updates
|
|
|
|
type ModelUpdateItem interface {
|
|
|
|
// The key to use when marshalling to JSON and interpreting in the client
|
|
|
|
UpdateType() string
|
Implement a Sidebar for Tabs (#157)
* work on basic sidebar layout
* fix more golang warnings
* sidebar open/close
* add ability to set width of split
* sidebar add and remove, set width, etc.
* almost working sidebar implementation -- still needs height/width, input control, and bug with initial add, but getting there
* add isSidebarOpen() method
* fix resize jump -- must set width in error handler as well (before window is loaded)
* sidebar UI touchups and help
* more sidebar progress, render more like regular lines, just in the right column
* merge
* move migration to 26
* simplify sidebar types
* checkpoint
* proxy things through parent screen object for sidebar
* checkpoint, add/remove from sidebar
* work on add/remove icons for sidebar
* fix height calculation, remove close button
* bring back close button when no line is selected
* add sidebar flag to run command to run new command output in sidebar
* implement 'sidebar' kwarg in eval. this lets sidebar work for slashcommands as well that produce lines (codeedit, mdview, etc.)
* prettier
* minor fixes
* working on resizing. must exclude sidebar entries and send separate resize events based on size of sidebar (implement exclude / include for resize)
* fix sidebar terminal command resizing
* add sidebar header (toggles for half/partial width and close). add hotkey to open/close sidebar (Cmd-Ctrl-S). more robust calculation for sidebar width. add width validation. minimum sidebar width is 200px. other fixes, etc.
2023-12-18 08:46:53 +01:00
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
// Clean the ClientData in an update, if present
|
|
|
|
func (update *ModelUpdate) Clean() {
|
|
|
|
if update == nil {
|
|
|
|
return
|
Implement a Sidebar for Tabs (#157)
* work on basic sidebar layout
* fix more golang warnings
* sidebar open/close
* add ability to set width of split
* sidebar add and remove, set width, etc.
* almost working sidebar implementation -- still needs height/width, input control, and bug with initial add, but getting there
* add isSidebarOpen() method
* fix resize jump -- must set width in error handler as well (before window is loaded)
* sidebar UI touchups and help
* more sidebar progress, render more like regular lines, just in the right column
* merge
* move migration to 26
* simplify sidebar types
* checkpoint
* proxy things through parent screen object for sidebar
* checkpoint, add/remove from sidebar
* work on add/remove icons for sidebar
* fix height calculation, remove close button
* bring back close button when no line is selected
* add sidebar flag to run command to run new command output in sidebar
* implement 'sidebar' kwarg in eval. this lets sidebar work for slashcommands as well that produce lines (codeedit, mdview, etc.)
* prettier
* minor fixes
* working on resizing. must exclude sidebar entries and send separate resize events based on size of sidebar (implement exclude / include for resize)
* fix sidebar terminal command resizing
* add sidebar header (toggles for half/partial width and close). add hotkey to open/close sidebar (Cmd-Ctrl-S). more robust calculation for sidebar width. add width validation. minimum sidebar width is 200px. other fixes, etc.
2023-12-18 08:46:53 +01:00
|
|
|
}
|
2024-02-10 02:19:44 +01:00
|
|
|
clientDataUpdates := GetUpdateItems[ClientData](update)
|
|
|
|
if len(clientDataUpdates) > 0 {
|
|
|
|
lastUpdate := clientDataUpdates[len(clientDataUpdates)-1]
|
|
|
|
lastUpdate.Clean()
|
Implement a Sidebar for Tabs (#157)
* work on basic sidebar layout
* fix more golang warnings
* sidebar open/close
* add ability to set width of split
* sidebar add and remove, set width, etc.
* almost working sidebar implementation -- still needs height/width, input control, and bug with initial add, but getting there
* add isSidebarOpen() method
* fix resize jump -- must set width in error handler as well (before window is loaded)
* sidebar UI touchups and help
* more sidebar progress, render more like regular lines, just in the right column
* merge
* move migration to 26
* simplify sidebar types
* checkpoint
* proxy things through parent screen object for sidebar
* checkpoint, add/remove from sidebar
* work on add/remove icons for sidebar
* fix height calculation, remove close button
* bring back close button when no line is selected
* add sidebar flag to run command to run new command output in sidebar
* implement 'sidebar' kwarg in eval. this lets sidebar work for slashcommands as well that produce lines (codeedit, mdview, etc.)
* prettier
* minor fixes
* working on resizing. must exclude sidebar entries and send separate resize events based on size of sidebar (implement exclude / include for resize)
* fix sidebar terminal command resizing
* add sidebar header (toggles for half/partial width and close). add hotkey to open/close sidebar (Cmd-Ctrl-S). more robust calculation for sidebar width. add width validation. minimum sidebar width is 200px. other fixes, etc.
2023-12-18 08:46:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
func (update *ModelUpdate) append(item *ModelUpdateItem) {
|
|
|
|
*update = append(*update, item)
|
2023-04-04 00:55:36 +02:00
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
// Add a collection of model updates to the update
|
|
|
|
func AddUpdate(update *ModelUpdate, item ...ModelUpdateItem) {
|
|
|
|
for _, i := range item {
|
|
|
|
update.append(&i)
|
2022-09-01 21:47:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-10 02:19:44 +01:00
|
|
|
// Returns the items in the update that are of type I
|
|
|
|
func GetUpdateItems[I ModelUpdateItem](update *ModelUpdate) []*I {
|
|
|
|
ret := make([]*I, 0)
|
|
|
|
for _, item := range *update {
|
|
|
|
if i, ok := (*item).(I); ok {
|
|
|
|
ret = append(ret, &i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
}
|
|
|
|
|
2022-07-13 23:16:08 +02:00
|
|
|
type UpdateChannel struct {
|
2023-03-21 03:20:57 +01:00
|
|
|
ScreenId string
|
|
|
|
ClientId string
|
|
|
|
Ch chan interface{}
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
|
2023-03-21 03:20:57 +01:00
|
|
|
func (uch UpdateChannel) Match(screenId string) bool {
|
|
|
|
if screenId == "" {
|
2022-07-13 23:16:08 +02:00
|
|
|
return true
|
|
|
|
}
|
2023-03-21 03:20:57 +01:00
|
|
|
return screenId == uch.ScreenId
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type UpdateBus struct {
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
Lock *sync.Mutex
|
|
|
|
Channels map[string]UpdateChannel
|
|
|
|
UserInputCh map[string](chan *scpacket.UserInputResponsePacketType)
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func MakeUpdateBus() *UpdateBus {
|
|
|
|
return &UpdateBus{
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
Lock: &sync.Mutex{},
|
|
|
|
Channels: make(map[string]UpdateChannel),
|
|
|
|
UserInputCh: make(map[string](chan *scpacket.UserInputResponsePacketType)),
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 21:42:09 +02:00
|
|
|
// always returns a new channel
|
2023-03-21 03:20:57 +01:00
|
|
|
func (bus *UpdateBus) RegisterChannel(clientId string, screenId string) chan interface{} {
|
2022-07-13 23:16:08 +02:00
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
uch, found := bus.Channels[clientId]
|
|
|
|
if found {
|
|
|
|
close(uch.Ch)
|
2023-03-21 03:20:57 +01:00
|
|
|
uch.ScreenId = screenId
|
2022-09-15 09:17:23 +02:00
|
|
|
uch.Ch = make(chan interface{}, UpdateChSize)
|
2022-07-13 23:16:08 +02:00
|
|
|
} else {
|
|
|
|
uch = UpdateChannel{
|
2023-03-21 03:20:57 +01:00
|
|
|
ClientId: clientId,
|
|
|
|
ScreenId: screenId,
|
|
|
|
Ch: make(chan interface{}, UpdateChSize),
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
bus.Channels[clientId] = uch
|
|
|
|
return uch.Ch
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bus *UpdateBus) UnregisterChannel(clientId string) {
|
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
uch, found := bus.Channels[clientId]
|
|
|
|
if found {
|
|
|
|
close(uch.Ch)
|
|
|
|
delete(bus.Channels, clientId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-09 01:06:51 +02:00
|
|
|
func (bus *UpdateBus) SendUpdate(update UpdatePacket) {
|
|
|
|
if update == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
update.Clean()
|
2023-03-21 03:20:57 +01:00
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
for _, uch := range bus.Channels {
|
|
|
|
select {
|
|
|
|
case uch.Ch <- update:
|
|
|
|
|
|
|
|
default:
|
|
|
|
log.Printf("[error] dropped update on updatebus uch clientid=%s\n", uch.ClientId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-09 01:06:51 +02:00
|
|
|
func (bus *UpdateBus) SendScreenUpdate(screenId string, update UpdatePacket) {
|
|
|
|
if update == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
update.Clean()
|
2022-07-13 23:16:08 +02:00
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
for _, uch := range bus.Channels {
|
2023-03-21 03:20:57 +01:00
|
|
|
if uch.Match(screenId) {
|
2022-09-15 09:17:23 +02:00
|
|
|
select {
|
|
|
|
case uch.Ch <- update:
|
|
|
|
|
|
|
|
default:
|
2022-10-31 20:40:45 +01:00
|
|
|
log.Printf("[error] dropped update on updatebus uch clientid=%s\n", uch.ClientId)
|
2022-09-15 09:17:23 +02:00
|
|
|
}
|
2022-07-13 23:16:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-08-24 11:14:16 +02:00
|
|
|
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
func (bus *UpdateBus) registerUserInputChannel() (string, chan *scpacket.UserInputResponsePacketType) {
|
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
|
|
|
|
id := uuid.New().String()
|
|
|
|
uich := make(chan *scpacket.UserInputResponsePacketType, 1)
|
|
|
|
|
|
|
|
bus.UserInputCh[id] = uich
|
|
|
|
return id, uich
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bus *UpdateBus) unregisterUserInputChannel(id string) {
|
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
|
|
|
|
delete(bus.UserInputCh, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bus *UpdateBus) GetUserInputChannel(id string) (chan *scpacket.UserInputResponsePacketType, bool) {
|
|
|
|
bus.Lock.Lock()
|
|
|
|
defer bus.Lock.Unlock()
|
|
|
|
|
|
|
|
uich, ok := bus.UserInputCh[id]
|
|
|
|
return uich, ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (bus *UpdateBus) GetUserInput(ctx context.Context, userInputRequest *UserInputRequestType) (*scpacket.UserInputResponsePacketType, error) {
|
|
|
|
id, uich := bus.registerUserInputChannel()
|
|
|
|
defer bus.unregisterUserInputChannel(id)
|
|
|
|
|
|
|
|
userInputRequest.RequestId = id
|
|
|
|
deadline, _ := ctx.Deadline()
|
|
|
|
userInputRequest.TimeoutMs = int(time.Until(deadline).Milliseconds()) - 500
|
2024-02-10 02:19:44 +01:00
|
|
|
update := &ModelUpdate{}
|
|
|
|
AddUpdate(update, *userInputRequest)
|
Use ssh library: add user input (#281)
* feat: create backend for user input requests
This is the first part of a change that allows the backend to request
user input from the frontend. Essentially, the backend will send a
request for the user to answer some query, and the frontend will send
that answer back. It is blocking, so it needs to be used within a
goroutine.
There is some placeholder code in the frontend that will be updated in
future commits. Similarly, there is some debug code in the backend
remote.go file.
* feat: create frontend for user input requests
This is part of a change to allow the backend to request user input from
the frontend. This adds a component specifically for handling this
logic. It is only a starting point, and does not work perfectly yet.
* refactor: update user input backend/interface
This updates the user input backend to fix a few potential bugs. It also
refactors the user input request and response types to better handle
markdown and errors while making it more convenient to work with.
A couple frontend changes were made to keep everything compatible.
* fix: add props to user input request modal
There was a second place that the modals were created that I previously
missed. This fixes that second casel
* feat: complete user input modal
This rounds out the most immediate concerns for the new user input
modal. The frontend now includes a timer to show how much time is left
and will close itself once it reaches zero. Css
formatting has been cleaned up to be more reasonable.
There is still some test code present on the back end. This will be
removed once actuall examples of the new modal are in place.
* feat: create first pass known_hosts detection
Manually integrating with golang's ssh library means that the code must
authenticate known_hosts on its own. This is a first pass at creating a
system that parses the known hosts files and denys a connection if there
is a mismatch. This needs to be updated with a means to add keys to the
known-hosts file if the user requests it.
* feat: allow writing to known_hosts first pass
As a follow-up to the previous change, we now allow the user to respond
to interactive queries in order to determine if an unknown known hosts
key can be added to a known_hosts file if it is missing. This needs to
be refined further, but it gets the basic functionality there.
* feat: add user input for kbd-interactive auth
This adds a modal so the user can respond to prompts provided using the
keyboard interactive authentication method.
* feat: add interactive password authentication
This makes the ssh password authentication interactive with its own user
input modal. Unfortunately, this method does not allow trying a default
first. This will need to be expanded in the future to accomodate that.
* fix: allow automatic and interactive auth together
Previously, it was impossible to use to separate methods of the same
type to try ssh authentication. This made it impossible to make an auto
attempt before a manual one. This change restricts that by combining
them into one method where the auto attempt is tried once first and
cannot be tried again. Following that, interactive authentication can be
tried separately.
It also lowers the time limit on kbd interactive authentication to 15
seconds due to limitations on the library we are using.
* fix: set number of retries to one in ssh
Number of retries means number of attempts after the fact, not number of
total attempts. It has been adjusted from 2 to 1 to reflect this.
* refactor: change argument order in GetUserInput
This is a simple change to move the context to the first argument of
GetUserInput to match the convention used elsewhere in the code.
* fix: set number of retries to two again
I was wrong in my previous analysis. The number given is the total
number of tries. This is confusing when keyboard authentication and
password authentication are both available which usually doesn't happen.
* feat: create naive ui for ssh key passphrases
This isn't quite as reactive as the other methods, but it does attempt
to use publickey without a passphrase, then attempt to use the password
as the passphrase, and finally prompting the user for a passphrase. The
problem with this approach is that if multiple keys are used and they
all have passphrases, they need to all be checked up front. In practice,
this will not happen often, but it is something to be aware of.
* fix: add the userinput.tsx changes
These were missed in the previous commit. Adding them now.
2024-02-09 04:16:56 +01:00
|
|
|
bus.SendUpdate(update)
|
|
|
|
log.Printf("test: %+v", userInputRequest)
|
|
|
|
|
|
|
|
var response *scpacket.UserInputResponsePacketType
|
|
|
|
var err error
|
|
|
|
// prepare to receive response
|
|
|
|
select {
|
|
|
|
case resp := <-uich:
|
|
|
|
response = resp
|
|
|
|
case <-ctx.Done():
|
|
|
|
return nil, fmt.Errorf("Timed out waiting for user input")
|
|
|
|
}
|
|
|
|
|
|
|
|
if response.ErrorMsg != "" {
|
|
|
|
err = fmt.Errorf(response.ErrorMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
return response, err
|
|
|
|
}
|