Finished authentication

This commit is contained in:
Kevin F 2022-09-16 00:42:29 -05:00
parent 32f3e6fb86
commit c0639dfa0c
4 changed files with 71 additions and 37 deletions

View File

@ -33,14 +33,14 @@ We use sha3 to hash authentication tokens. It is not in the crypto standard libr
--- ---
# keybd_event # sendkeys
In order to avoid coding key press simulation for every major platform, we use [keybd_event](https://github.com/micmonay/keybd_event). This is a cross-platform library that uses the OS's native key press simulation. In order to avoid coding key press simulation for every major platform, we use [sendkeys](https://github.com/yunginnanet/sendkeys). This is a cross-platform library that uses the OS's native key press simulation using [keybd_event](https://github.com/micmonay/keybd_event)
--- keybd_event import string --- sendkeys import string
"github.com/micmonay/keybd_event" "github.com/EgosOwn/sendkeys"
--- ---

View File

@ -50,6 +50,7 @@ First, we call
--- entrypoint --- entrypoint
func main(){ func main(){
auth.ProvisionToken()
server.StartServer() server.StartServer()
} }
@ -61,6 +62,7 @@ First, we call
import( import(
"keyboard.voidnet.tech/server" "keyboard.voidnet.tech/server"
"keyboard.voidnet.tech/auth"
) )

View File

@ -36,7 +36,7 @@ if unixSocketPathExists {
--- start websocket server --- start websocket server
func clientConnected(w http.ResponseWriter, r *http.Request) { func clientConnected(w http.ResponseWriter, r *http.Request) {
kb, err := keybd_event.NewKeyBonding() keyboard, err := sendkeys.NewKBWrapWithOptions(sendkeys.Noisy)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -47,7 +47,22 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
} }
defer c.Close() defer c.Close()
// get auth token
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
if auth.CheckAuthToken(string(message)) != nil {
log.Println("invalid token")
return
}
c.WriteMessage(websocket.TextMessage, []byte("authenticated"))
for { for {
time.Sleep(25 * time.Millisecond)
_, message, err := c.ReadMessage() _, message, err := c.ReadMessage()
if err != nil { if err != nil {
log.Println("read:", err) log.Println("read:", err)
@ -55,16 +70,11 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
} }
log.Printf("recv: %s", message) log.Printf("recv: %s", message)
message_string := string(message) message_string := string(message)
for _, char := range message_string { err = keyboard.Type(message_string)
// make sure that the char is a number if err != nil {
number, err := strconv.Atoi(string(char)) log.Println("type:", err)
if err == nil { break
kb.SetKeys(number)
}
} }
// sendkeys
//kb.SetKeys(30, 32, 33)
go kb.Launching()
} }
} }
@ -80,18 +90,20 @@ func StartServer() {
--- ---
```
--- /server/server.go --- /server/server.go
package server package server
import( import(
"net" "net"
"time"
"os" "os"
"net/http" "net/http"
"log" "log"
"keyboard.voidnet.tech/auth"
@{gorilla/websocket import string} @{gorilla/websocket import string}
@{keybd_event import string} @{sendkeys import string}
) )
var listener net.Listener var listener net.Listener
@ -101,3 +113,4 @@ var upgrader = websocket.Upgrader{} // use default options
@{start websocket server} @{start websocket server}
--- ---
```

View File

@ -14,6 +14,8 @@ KDF.
--- token generation --- token generation
authToken = uuid.New().String() + uuid.New().String() authToken = uuid.New().String() + uuid.New().String()
hashedID := sha3.Sum256([]byte(authToken)) hashedID := sha3.Sum256([]byte(authToken))
fmt.Println("This is your authentication token, it will only be shown once: " + authToken)
--- ---
``` ```
@ -43,9 +45,12 @@ if authTokenFileIsSet == false {
When a client connects, the [websocket server](Server.md) checks the token they send against the stored token. When a client connects, the [websocket server](Server.md) checks the token they send against the stored token.
We use a constant time comparison to avoid timing attacks.
``` go ``` go
--- check token --- check token function
func checkAuthToken(token string) error { func CheckAuthToken(token string) error {
@{define authentication token file} @{define authentication token file}
// compare sha3_256 hash to hash in file // compare sha3_256 hash to hash in file
hashedToken := sha3.Sum256([]byte(token)) hashedToken := sha3.Sum256([]byte(token))
@ -60,12 +65,42 @@ func checkAuthToken(token string) error {
} }
--- ---
--- provision token function
func ProvisionToken() (error){
@{define authentication token file}
if _, err := os.Stat(authTokenFile); err == nil {
return nil
}
@{token generation}
// create directories if they don't exist
os.MkdirAll(filepath.Dir(authTokenFile), 0700)
fo, err := os.Create(authTokenFile)
defer fo.Close()
if err != nil {
panic(err)
}
fo.Write(hashedID[:])
return nil
}
---
## Putting it all together
The following is the structure of the authentication package.
Both CheckAuthToken and ProvisionToken are exported.
The former is used by the server on client connect and the latter is called on startup.
--- /auth/auth.go --- /auth/auth.go
package auth package auth
import( import(
"os" "os"
"path/filepath" "path/filepath"
"fmt"
"errors" "errors"
"crypto/subtle" "crypto/subtle"
@{sha3 import string} @{sha3 import string}
@ -75,25 +110,9 @@ import(
var authToken = "" var authToken = ""
func provisionToken() (error){ @{provision token function}
@{define authentication token file}
if _, err := os.Stat(authTokenFile); err == nil { @{check token function}
return nil
}
@{token generation}
fo, err := os.Create(authTokenFile)
if err != nil {
panic(err)
}
fo.Write(hashedID[:])
fo.Close()
return nil
}
@{check token}
--- ---