Finished authentication
This commit is contained in:
parent
32f3e6fb86
commit
c0639dfa0c
@ -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"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
39
Server.md
39
Server.md
@ -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
|
||||||
@ -100,4 +112,5 @@ var upgrader = websocket.Upgrader{} // use default options
|
|||||||
|
|
||||||
|
|
||||||
@{start websocket server}
|
@{start websocket server}
|
||||||
---
|
---
|
||||||
|
```
|
@ -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}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user