|
@@ -1,4 +1,5 @@
|
|
|
package auth
|
|
package auth
|
|
|
|
|
+
|
|
|
// package for authenticating websockets
|
|
// package for authenticating websockets
|
|
|
// we use a homespun jwt knock-off because no tls on lan
|
|
// we use a homespun jwt knock-off because no tls on lan
|
|
|
// authentication adds you to the AuthenticatedClients map
|
|
// authentication adds you to the AuthenticatedClients map
|
|
@@ -27,84 +28,61 @@ var (
|
|
|
// maps a websocket conn to a tokenid
|
|
// maps a websocket conn to a tokenid
|
|
|
// tokenid's can be referenced from the global conf
|
|
// tokenid's can be referenced from the global conf
|
|
|
AuthenticatedClients = struct {
|
|
AuthenticatedClients = struct {
|
|
|
- Conns map[*websocket.Conn]string
|
|
|
|
|
|
|
+ Conns map[string]*websocket.Conn
|
|
|
sync.RWMutex
|
|
sync.RWMutex
|
|
|
}{
|
|
}{
|
|
|
- Conns: make(map[*websocket.Conn]string),
|
|
|
|
|
|
|
+ Conns: make(map[string]*websocket.Conn),
|
|
|
}
|
|
}
|
|
|
UnauthClients = struct {
|
|
UnauthClients = struct {
|
|
|
- Conns map[*websocket.Conn]string
|
|
|
|
|
|
|
+ Conns map[string]*websocket.Conn
|
|
|
sync.RWMutex
|
|
sync.RWMutex
|
|
|
}{
|
|
}{
|
|
|
- Conns: make(map[*websocket.Conn]string),
|
|
|
|
|
|
|
+ Conns: make(map[string]*websocket.Conn),
|
|
|
}
|
|
}
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-// check if websocket session is in the auth map
|
|
|
|
|
-func WsIsAuthenticated(conn *websocket.Conn) bool {
|
|
|
|
|
- AuthenticatedClients.Lock()
|
|
|
|
|
- defer AuthenticatedClients.Unlock()
|
|
|
|
|
- _, exists := AuthenticatedClients.Conns[conn]
|
|
|
|
|
- return exists
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// check if a hash is in the auth map
|
|
|
|
|
-func hashAuthenticated(hash string) bool {
|
|
|
|
|
- AuthenticatedClients.RLock() // Acquire read lock
|
|
|
|
|
|
|
+// check if websocket-token pair is auth'd
|
|
|
|
|
+func WsIsAuthenticated(conn *websocket.Conn, token string) bool {
|
|
|
|
|
+ AuthenticatedClients.RLock() // Acquire read lock
|
|
|
defer AuthenticatedClients.RUnlock() // Release read lock
|
|
defer AuthenticatedClients.RUnlock() // Release read lock
|
|
|
- for _, v := range AuthenticatedClients.Conns {
|
|
|
|
|
- if v == hash {
|
|
|
|
|
- return true
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if AuthenticatedClients.Conns[token] == conn {
|
|
|
|
|
+ return true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false
|
|
|
}
|
|
}
|
|
|
- return false
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// check the validity of the token
|
|
// check the validity of the token
|
|
|
-func CheckToken(token string, conn *websocket.Conn, r *http.Request, setup bool) (bool, string, error) {
|
|
|
|
|
- // no token? we have problem.
|
|
|
|
|
- if token == "" {
|
|
|
|
|
- authStatus := false
|
|
|
|
|
- if setup {
|
|
|
|
|
- authStatus = true
|
|
|
|
|
- }
|
|
|
|
|
- // you take token.
|
|
|
|
|
- newToken, err := CreateToken(conn, r, setup)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- return false, "", err
|
|
|
|
|
- }
|
|
|
|
|
- return authStatus, newToken["token"], nil
|
|
|
|
|
|
|
+func CheckToken(token map[string]string, conn *websocket.Conn, r *http.Request, setup bool) (bool, string, error) {
|
|
|
|
|
+ // great you have token. we see if valid.
|
|
|
|
|
+ conf := config.Conf()
|
|
|
|
|
+ key := conf.KeyFile
|
|
|
|
|
+ res, err := KeyfileDecrypt(token["token"], key)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ config.Logger.Warn("Invalid token provided")
|
|
|
|
|
+ return false, "", err
|
|
|
} else {
|
|
} else {
|
|
|
- // great you have token. we see if valid.
|
|
|
|
|
- conf := config.Conf()
|
|
|
|
|
- key := conf.KeyFile
|
|
|
|
|
- res, err := KeyfileDecrypt(token, key)
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- config.Logger.Warn("Invalid token provided")
|
|
|
|
|
- return false, "", err
|
|
|
|
|
|
|
+ // so you decrypt. now we see the useragent and ip.
|
|
|
|
|
+ var ip string
|
|
|
|
|
+ if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
|
|
|
|
|
+ ip = strings.Split(forwarded, ",")[0]
|
|
|
} else {
|
|
} else {
|
|
|
- // so you decrypt. now we see the useragent and ip.
|
|
|
|
|
- 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[:])
|
|
|
|
|
- // you in auth map?
|
|
|
|
|
- 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
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ip, _, _ = net.SplitHostPort(r.RemoteAddr)
|
|
|
|
|
+ }
|
|
|
|
|
+ userAgent := r.Header.Get("User-Agent")
|
|
|
|
|
+ hashed := sha256.Sum256([]byte(token["token"]))
|
|
|
|
|
+ hash := hex.EncodeToString(hashed[:])
|
|
|
|
|
+ // you in auth map?
|
|
|
|
|
+ if WsIsAuthenticated(conn, hash) {
|
|
|
|
|
+ if ip == res["ip"] && userAgent == res["user_agent"] {
|
|
|
|
|
+ return true, res["id"], nil
|
|
|
} else {
|
|
} else {
|
|
|
- config.Logger.Warn("Token isn't an authenticated session")
|
|
|
|
|
|
|
+ config.Logger.Warn("Token doesn't match session!")
|
|
|
return false, res["id"], err
|
|
return false, res["id"], err
|
|
|
}
|
|
}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ config.Logger.Warn("Token isn't an authenticated session")
|
|
|
|
|
+ return false, res["id"], err
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
return false, "", nil
|
|
return false, "", nil
|
|
@@ -255,7 +233,7 @@ func AuthenticateLogin(password string) bool {
|
|
|
if hash == conf.PwHash {
|
|
if hash == conf.PwHash {
|
|
|
return true
|
|
return true
|
|
|
} else {
|
|
} else {
|
|
|
- config.Logger.Warn(fmt.Sprintf("debug: failed pw hash: %v",hash))
|
|
|
|
|
|
|
+ config.Logger.Warn(fmt.Sprintf("debug: failed pw hash: %v", hash))
|
|
|
return false
|
|
return false
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|