|
@@ -1,4 +1,8 @@
|
|
|
package auth
|
|
package auth
|
|
|
|
|
+// package for authenticating websockets
|
|
|
|
|
+// we use a homespun jwt knock-off because no tls on lan
|
|
|
|
|
+// authentication adds you to the AuthenticatedClients map
|
|
|
|
|
+// broadcasts get sent to members of this map
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"crypto/rand"
|
|
"crypto/rand"
|
|
@@ -44,24 +48,64 @@ func WsIsAuthenticated(conn *websocket.Conn) bool {
|
|
|
return exists
|
|
return exists
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// // CheckToken checks the validity of the token.
|
|
|
|
|
-// func CheckToken(token string, conn *websocket.Conn, setup bool) (bool, string, error) {
|
|
|
|
|
-// if token == "" {
|
|
|
|
|
-// authStatus := false
|
|
|
|
|
-// if setup {
|
|
|
|
|
-// authStatus = true
|
|
|
|
|
-// }
|
|
|
|
|
-// newToken, err := CreateToken(conn, setup)
|
|
|
|
|
-// if err != nil {
|
|
|
|
|
-// return false, "", err
|
|
|
|
|
-// }
|
|
|
|
|
-// return authStatus, newToken["token"], nil
|
|
|
|
|
-// }
|
|
|
|
|
|
|
+// check if a hash is in the auth map
|
|
|
|
|
+func hashAuthenticated(hash string) bool {
|
|
|
|
|
+ AuthenticatedClients.RLock() // Acquire read lock
|
|
|
|
|
+ defer AuthenticatedClients.RUnlock() // Release read lock
|
|
|
|
|
+ for _, v := range AuthenticatedClients.Conns {
|
|
|
|
|
+ if v == hash {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-// return false, "", nil
|
|
|
|
|
-// }
|
|
|
|
|
|
|
+// check the validity of the token
|
|
|
|
|
+func CheckToken(token string, conn *websocket.Conn, r *http.Request, setup bool) (bool, string, error) {
|
|
|
|
|
+ if token == "" {
|
|
|
|
|
+ authStatus := false
|
|
|
|
|
+ if setup {
|
|
|
|
|
+ authStatus = true
|
|
|
|
|
+ }
|
|
|
|
|
+ newToken, err := CreateToken(conn, r, setup)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return false, "", err
|
|
|
|
|
+ }
|
|
|
|
|
+ return authStatus, newToken["token"], nil
|
|
|
|
|
+ } else {
|
|
|
|
|
+ conf := config.Conf()
|
|
|
|
|
+ key := conf.KeyFile
|
|
|
|
|
+ res, err := KeyfileDecrypt(token, key)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ config.Logger.Warn("Invalid token provided")
|
|
|
|
|
+ return false, "", err
|
|
|
|
|
+ } else {
|
|
|
|
|
+ var ip string
|
|
|
|
|
+ if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
|
|
|
|
|
+ ip = strings.Split(forwarded, ",")[0]
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ip, _, _ = net.SplitHostPort(r.RemoteAddr)
|
|
|
|
|
+ }
|
|
|
|
|
+ userAgent := r.Header.Get("User-Agent")
|
|
|
|
|
+ hashed := sha256.Sum256([]byte(token))
|
|
|
|
|
+ hash := hex.EncodeToString(hashed[:])
|
|
|
|
|
+ if hashAuthenticated(hash) {
|
|
|
|
|
+ if ip == res["ip"] && userAgent == res["user_agent"] {
|
|
|
|
|
+ return true, res["id"], nil
|
|
|
|
|
+ } else {
|
|
|
|
|
+ config.Logger.Warn("Token doesn't match session!")
|
|
|
|
|
+ return false, res["id"], err
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ config.Logger.Warn("Token isn't an authenticated session")
|
|
|
|
|
+ return false, res["id"], err
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return false, "", nil
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-// CreateToken creates a new session token.
|
|
|
|
|
|
|
+// create a new session token
|
|
|
func CreateToken(conn *websocket.Conn, r *http.Request, setup bool) (map[string]string, error) {
|
|
func CreateToken(conn *websocket.Conn, r *http.Request, setup bool) (map[string]string, error) {
|
|
|
// extract conn info
|
|
// extract conn info
|
|
|
var ip string
|
|
var ip string
|