diff --git a/Client.md b/Client.md index 9b6507c..9ff1e2c 100644 --- a/Client.md +++ b/Client.md @@ -1,18 +1,97 @@ # GoSmartKeyboard Client +When GoSmartKeyboard is started in client mode, it does the following: -This is the base client, it only connects and authenticates. +1. Load the connection URL from the second CLI argument. +2. Load the auth token from the environment variable `KEYBOARD_AUTH` or stdin. +3. Connect to the server. +4 Send the auth token to the server. +5. If the server responds with "authenticated", we start reading keys from stdin and sending them to the server until EOF. -The authentication token is loaded from the environment variable `KEYBOARD_AUTH`, if it does not exist we read it from stdin in base64 form, ended with a newline. +## Connecting + +The base64 authentication token is loaded from the environment variable `KEYBOARD_AUTH`, if it does not exist we read it from stdin (base64 encoded), ended with a newline. ``` go --- start client +@{load connection URL from second CLI argument} +@{get authTokenInput from environment} + +if !authTokenInputExists { + fmt.Print("Enter authentication token: ") + _, err := fmt.Scanln(&authTokenInput) + if err != nil { + log.Fatal(err) + } +} + +client, _, err := websocket.DefaultDialer.Dial(connectionURL, nil) +if err != nil { + log.Fatal("dial:", err) +} +defer client.Close() + +err = client.WriteMessage(websocket.TextMessage, []byte(authTokenInput)) + +if err != nil { + log.Fatal("write:", err) +} + +_, authResponse, err := client.ReadMessage() +if err != nil { + log.Fatal("read:", err) +} +if string(authResponse) != "authenticated" { + log.Fatal("authentication failed") +} --- +--- load connection URL from second CLI argument --- noWeave + +if len(os.Args) < 3 { + log.Fatal("missing connection URL") +} + +connectionURL := os.Args[2] + +if !strings.HasPrefix(connectionURL, "ws://") && !strings.HasPrefix(connectionURL, "wss://") { + log.Fatal("connection URL must start with ws:// or wss://") +} + +--- + +``` + +## Sending keys + + +We read keys from stdin and send them to the server until we get EOF + +``` go + +--- start client += + + +for { + var key string + _, err := fmt.Scanln(&key) + if err != nil { + if err == io.EOF { + break + } + log.Fatal(err) + } + err = client.WriteMessage(websocket.TextMessage, []byte(key)) + if err != nil { + log.Fatal("write:", err) + } +} + +--- ``` \ No newline at end of file diff --git a/EnvironmentVariables.md b/EnvironmentVariables.md index 7a512f1..cbc90fc 100644 --- a/EnvironmentVariables.md +++ b/EnvironmentVariables.md @@ -15,6 +15,14 @@ authTokenFile, authTokenFileIsSet := os.LookupEnv("KEYBOARD_AUTH_TOKEN_FILE") --- ``` +## Authentication token input (for client) + +--- get authTokenInput from environment + + authTokenInput, authTokenInputExists := os.LookupEnv("KEYBOARD_AUTH") + +--- + ## HTTP Bind Settings diff --git a/Makefile b/Makefile index 5eed023..d13d0fe 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ weave: - srcweave --formatter srcweave-format --weave docs/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md Server.md Streaming.md ThreatModel.md + srcweave --formatter srcweave-format --weave docs/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md Server.md Streaming.md ThreatModel.md Client.md util/removefencedcode.py tangle: - srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md Server.md Streaming.md ThreatModel.md + srcweave --formatter srcweave-format --tangle smartkeyboard/ ReadMe.md security/Authentication.md EnvironmentVariables.md Dependencies.md Server.md Streaming.md ThreatModel.md Client.md clean: rm -rf docs find smartkeyboard/ -type f -not -name "*_test.go" -delete diff --git a/ReadMe.md b/ReadMe.md index c022635..a1d0460 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -82,6 +82,10 @@ Then we can start the web server and listen for websocket connections. import( "os" "fmt" + "io" + "strings" + "log" + @{gorilla/websocket import string} "keyboard.voidnet.tech/server" "keyboard.voidnet.tech/auth" ) diff --git a/Streaming.md b/Streaming.md index f15f81b..cdc98d0 100644 --- a/Streaming.md +++ b/Streaming.md @@ -26,6 +26,7 @@ func clientConnected(w http.ResponseWriter, r *http.Request) { if auth.CheckAuthToken(string(message)) != nil { log.Println("invalid token") + c.WriteMessage(websocket.TextMessage, []byte("invalid token")) return } c.WriteMessage(websocket.TextMessage, []byte("authenticated"))