summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkali kaneko (leap communications) <kali@leap.se>2020-01-24 23:09:50 -0600
committerkali kaneko (leap communications) <kali@leap.se>2020-01-24 23:59:42 -0600
commit307582d9d193f282fc20182468a02ed0c55b4f99 (patch)
treea1624dcf626cb6b984033c331e33b6b418b0eadc
parent1c9220e04016d035c3c688c315ceabe274f45dfc (diff)
sip authenticator
-rw-r--r--Makefile4
-rw-r--r--cmd/vpnweb/vpnweb.go2
-rw-r--r--pkg/auth/middleware.go30
-rw-r--r--pkg/auth/sip2/auth.go77
-rw-r--r--pkg/auth/sip2/client.go2
-rw-r--r--pkg/auth/sip2/spec.go2
-rw-r--r--pkg/config/main.go2
7 files changed, 107 insertions, 12 deletions
diff --git a/Makefile b/Makefile
index b000de0..1481a5a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,9 @@
build:
go build cmd/vpnweb/vpnweb.go
-demo:
+demo-sip:
. config/CONFIG && ./vpnweb -notls -auth=sip
+demo-anon:
+ . config/CONFIG && ./vpnweb -notls -auth=anon
clean:
rm -f public/1/*
rm public/ca.crt
diff --git a/cmd/vpnweb/vpnweb.go b/cmd/vpnweb/vpnweb.go
index ff25e09..f59cc7d 100644
--- a/cmd/vpnweb/vpnweb.go
+++ b/cmd/vpnweb/vpnweb.go
@@ -25,7 +25,7 @@ func main() {
*/
http.Handle("/3/cert", auth.RestrictedMiddleware(opts.Auth, ch))
- http.Handle("/3/auth", auth.Authenticator(opts.Auth))
+ http.HandleFunc("/3/auth", auth.Authenticator(opts))
/* static files */
diff --git a/pkg/auth/middleware.go b/pkg/auth/middleware.go
index a183c1b..9b42fa9 100644
--- a/pkg/auth/middleware.go
+++ b/pkg/auth/middleware.go
@@ -1,6 +1,8 @@
package auth
import (
+ "0xacab.org/leap/vpnweb/pkg/auth/sip2"
+ "0xacab.org/leap/vpnweb/pkg/config"
"0xacab.org/leap/vpnweb/pkg/web"
"github.com/auth0/go-jwt-middleware"
jwt "github.com/dgrijalva/jwt-go"
@@ -12,20 +14,33 @@ const anonAuth string = "anon"
const sipAuth string = "sip"
/* FIXME -- get this from configuration variables */
-var jwtSecret = []byte("somethingverysecret")
-func Authenticator(auth string) {
+var jwtSigningSecret = []byte("thesingingkey")
+
+func bailOnBadAuthModule(module string) {
+ log.Fatal("Unknown auth module: '", module, "'. Should be one of: ", anonAuth, ", ", sipAuth, ".")
+}
+
+func Authenticator(opts *config.Opts) http.HandlerFunc {
+ switch opts.Auth {
+ case anonAuth:
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ http.Error(w, "no authentication in anon mode", http.StatusBadRequest)
+ })
+ case sipAuth:
+ return sip2.SipAuthenticator(opts)
+ default:
+ bailOnBadAuthModule(opts.Auth)
+ }
+ return nil
}
func RestrictedMiddleware(auth string, ch web.CertHandler) http.Handler {
jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
- return jwtSecret, nil
+ return jwtSigningSecret, nil
},
- // When set, the middleware verifies that tokens are signed with the specific signing algorithm
- // If the signing method is not constant the ValidationKeyGetter callback can be used to implement additional checks
- // Important to avoid security issues described here: https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
SigningMethod: jwt.SigningMethodHS256,
})
@@ -35,8 +50,7 @@ func RestrictedMiddleware(auth string, ch web.CertHandler) http.Handler {
case sipAuth:
return jwtMiddleware.Handler(http.HandlerFunc(ch.CertResponder))
default:
- log.Fatal("Unknown auth module: '", auth, "'. Should be one of: ", anonAuth, ", ", sipAuth, ".")
+ bailOnBadAuthModule(auth)
}
- // should not get here
return nil
}
diff --git a/pkg/auth/sip2/auth.go b/pkg/auth/sip2/auth.go
new file mode 100644
index 0000000..1d3f309
--- /dev/null
+++ b/pkg/auth/sip2/auth.go
@@ -0,0 +1,77 @@
+package sip2
+
+import (
+ "encoding/json"
+ jwt "github.com/dgrijalva/jwt-go"
+ "log"
+ "net/http"
+ "time"
+
+ "0xacab.org/leap/vpnweb/pkg/config"
+)
+
+const LibraryLocation string = "testlibrary"
+const SipUser string = "leap"
+const SipPasswd string = "Kohapassword1!"
+
+// XXX duplicated, pass in opts
+var jwtSigningSecret = []byte("thesingingkey")
+
+type Credentials struct {
+ User string
+ Password string
+}
+
+func SipAuthenticator(opts *config.Opts) http.HandlerFunc {
+ log.Println("Initializing sip2 authenticator...")
+
+ /* TODO -- should pass specific SIP options as a secondary struct */
+ /* TODO -- catch connection errors */
+
+ sip := NewClient("localhost", "6001", LibraryLocation)
+
+ ok, err := sip.Connect()
+ if err != nil {
+ log.Fatal("cannot connect sip client")
+ }
+ ok = sip.Login(SipUser, SipPasswd)
+ if !ok {
+ log.Println("Error on SIP login")
+ } else {
+ log.Println("SIP login ok")
+ }
+
+ var authTokenHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ var c Credentials
+
+ err := json.NewDecoder(r.Body).Decode(&c)
+ if err != nil {
+ log.Println("Auth request did not send valid json")
+ http.Error(w, err.Error(), http.StatusBadRequest)
+ return
+ }
+
+ if c.User == "" || c.Password == "" {
+ log.Println("Auth request did not include user or password")
+ http.Error(w, "missing user and/or password", http.StatusBadRequest)
+ return
+ }
+
+ valid := sip.CheckCredentials(c.User, c.Password)
+ if !valid {
+ log.Println("Wrong auth for user", c.User)
+ http.Error(w, "wrong user and/or password", http.StatusUnauthorized)
+ return
+ }
+
+ log.Println("Valid auth for user", c.User)
+ token := jwt.New(jwt.SigningMethodHS256)
+ claims := token.Claims.(jwt.MapClaims)
+ /* maybe no uid at all */
+ claims["uid"] = "user"
+ claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
+ tokenString, _ := token.SignedString(jwtSigningSecret)
+ w.Write([]byte(tokenString))
+ })
+ return authTokenHandler
+}
diff --git a/pkg/auth/sip2/client.go b/pkg/auth/sip2/client.go
index fbdeded..7116a84 100644
--- a/pkg/auth/sip2/client.go
+++ b/pkg/auth/sip2/client.go
@@ -27,7 +27,7 @@ func NewClient(host, port, location string) Client {
func (c *Client) Connect() (bool, error) {
conn, err := telnet.DialTo(c.Host + ":" + c.Port)
if nil != err {
- log.Println(log.Printf("error: %v", err))
+ log.Println("error", err)
return false, err
}
c.conn = conn
diff --git a/pkg/auth/sip2/spec.go b/pkg/auth/sip2/spec.go
index 9c4ac48..60a14d9 100644
--- a/pkg/auth/sip2/spec.go
+++ b/pkg/auth/sip2/spec.go
@@ -114,7 +114,7 @@ func getParser() *Parser {
txt := msg[:len(msg)-len(terminator)]
code, err := strconv.Atoi(txt[:2])
if nil != err {
- log.Println("Error parsing integer: %s", txt[:2])
+ log.Printf("Error parsing integer: %s\n", txt[:2])
}
spec := parser.getMessageSpecByCode(code)
txt = txt[2:]
diff --git a/pkg/config/main.go b/pkg/config/main.go
index 142738d..cfa97ed 100644
--- a/pkg/config/main.go
+++ b/pkg/config/main.go
@@ -19,6 +19,8 @@ type Opts struct {
Auth string
}
+// TODO -- remove use of reflect
+
func (o *Opts) fallbackToEnv(field string, envVar string, defaultVal string) {
r := reflect.ValueOf(o)
f := reflect.Indirect(r).FieldByName(field)