summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile.golang2
-rw-r--r--main.go57
2 files changed, 51 insertions, 8 deletions
diff --git a/Dockerfile.golang b/Dockerfile.golang
index df1bf9d..d77956f 100644
--- a/Dockerfile.golang
+++ b/Dockerfile.golang
@@ -1,6 +1,6 @@
FROM golang:1.10 as build
WORKDIR /go/src/pwman
-RUN go get -d -v gopkg.in/ldap.v2 github.com/gorilla/csrf gopkg.in/jcmturner/gokrb5.v5/client gopkg.in/jcmturner/gokrb5.v5/config
+RUN go get -d -v gopkg.in/ldap.v2 github.com/gorilla/csrf gopkg.in/jcmturner/gokrb5.v5/client gopkg.in/jcmturner/gokrb5.v5/config github.com/namsral/flag
COPY *.go ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o pwman .
diff --git a/main.go b/main.go
index ea6a60c..4970e86 100644
--- a/main.go
+++ b/main.go
@@ -1,9 +1,13 @@
package main
import (
+ "fmt"
"github.com/gorilla/csrf"
+ "github.com/namsral/flag"
"log"
+ "math/rand"
"net/http"
+ "strings"
"time"
)
@@ -17,15 +21,42 @@ type PwmanServer struct {
var pwman *PwmanServer
+const csrf_base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._#%!&:;?+{}[]"
+
func main() {
+ var ldapServer, ldapUser, ldapPassword, pwnedFile, krb5Conf, changePwScript, csrfSecret, serverAddr string
+ var ldapPort int
+ var ldapSkipSSLVerify, csrfInsecure, gennerateCsrfKey bool
+ flag.StringVar(&ldapServer, "ldap-server", "localhost", "the ldap server address")
+ flag.IntVar(&ldapPort, "ldap-port", 636, "the ldap server port")
+ flag.BoolVar(&ldapSkipSSLVerify, "ldap-ssl-skip-verify", false, "Should the ssl certificate of the ldap server be verfied")
+ flag.StringVar(&ldapUser, "ldap-user", "cn=admin,dc=nordu,dc=net", "An ldap user that can change user attributes")
+ flag.StringVar(&ldapPassword, "ldap-password", "", "Ldap user password")
+ flag.StringVar(&pwnedFile, "pwned", "./pwned-passwords-ordered-2.0.txt", "Path to the pwned passwords list")
+ flag.StringVar(&krb5Conf, "krb5", "./krb5.conf", "Path to kerberos config file")
+ flag.StringVar(&changePwScript, "changepw-script", "./create-kdc-principal.pl", "Path to the change password script")
+ flag.StringVar(&csrfSecret, "csrf-secret", "", "Specify csrf 32 char secret")
+ flag.StringVar(&serverAddr, "address", ":3000", "Server address to listen on")
+ flag.BoolVar(&csrfInsecure, "csrf-insecure", false, "Allow csrf cookie to be sent over http")
+ flag.BoolVar(&gennerateCsrfKey, "gennerate-csrf", false, "Gennerate a csrf secret")
+ flag.Parse()
+
+ if gennerateCsrfKey {
+ fmt.Println("CSRF secret:", gennerateCsrfSecret())
+ return
+ }
+ if csrfSecret == "" {
+ csrfSecret = gennerateCsrfSecret()
+ log.Println("WARN", "No CSRF secret specified. Using random:", csrfSecret)
+ }
- ldapInfo := &LdapInfo{Server: "localhost", Port: 6636, SSLSkipVerify: true, User: "cn=admin,dc=nordu,dc=net", Password: "secretpw"}
+ ldapInfo := &LdapInfo{Server: ldapServer, Port: ldapPort, SSLSkipVerify: ldapSkipSSLVerify, User: ldapUser, Password: ldapPassword}
pwman = &PwmanServer{
LdapInfo: ldapInfo,
- PwnedDBFile: "/Users/markus/Downloads/pwned-passwords-ordered-2.0.txt",
- Krb5Conf: "./krb5.conf",
- ChangePwScript: "./create-kdc-principal.pl",
+ PwnedDBFile: pwnedFile,
+ Krb5Conf: krb5Conf,
+ ChangePwScript: changePwScript,
RemoteUserHeader: "X-Remote-User",
}
@@ -41,18 +72,30 @@ func main() {
mux.Handle(base_path+"/static/", http.StripPrefix(base_path+"/static", http.FileServer(http.Dir("static"))))
- CSRF := csrf.Protect([]byte("f3b4ON3nQkmNPNP.hiyp7Z5DBAMsXo7c_"), csrf.Secure(false))
+ CSRF := csrf.Protect([]byte(csrfSecret), csrf.Secure(!csrfInsecure))
server := &http.Server{
- Addr: ":3000",
+ Addr: serverAddr,
Handler: CSRF(mux),
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
}
- log.Println("Listening on: http://0.0.0.0:3000")
+ if strings.HasPrefix(serverAddr, ":") {
+ serverAddr = "0.0.0.0" + serverAddr
+ }
+ log.Println("Listening on: http://" + serverAddr)
log.Fatal(server.ListenAndServe())
}
+func gennerateCsrfSecret() string {
+ b := make([]byte, 32)
+ rand.Seed(time.Now().UnixNano())
+ for i := range b {
+ b[i] = csrf_base[rand.Intn(len(csrf_base))]
+ }
+ return string(b)
+}
+
//type CustomMux struct {
// base_path string
// mux *http.ServeMux