Add Certificate helper function
This commit is contained in:
parent
8c4c00b31a
commit
1634c2c11c
@ -33,19 +33,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
handler := &gmi.ServeMux{}
|
var mux gmi.ServeMux
|
||||||
handler.HandleFunc("/", welcome)
|
mux.HandleFunc("/", welcome)
|
||||||
handler.HandleFunc("/login", login)
|
mux.HandleFunc("/login", login)
|
||||||
handler.HandleFunc("/login/password", loginPassword)
|
mux.HandleFunc("/login/password", loginPassword)
|
||||||
handler.HandleFunc("/profile", profile)
|
mux.HandleFunc("/profile", profile)
|
||||||
handler.HandleFunc("/admin", admin)
|
mux.HandleFunc("/admin", admin)
|
||||||
handler.HandleFunc("/logout", logout)
|
mux.HandleFunc("/logout", logout)
|
||||||
|
|
||||||
server := &gmi.Server{}
|
var server gmi.Server
|
||||||
if err := server.CertificateStore.Load("/var/lib/gemini/certs"); err != nil {
|
if err := server.CertificateStore.Load("/var/lib/gemini/certs"); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
server.Register("localhost", handler)
|
server.Register("localhost", &mux)
|
||||||
|
|
||||||
if err := server.ListenAndServe(); err != nil {
|
if err := server.ListenAndServe(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -59,11 +59,15 @@ func getSession(crt *x509.Certificate) (*session, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func welcome(w *gmi.ResponseWriter, r *gmi.Request) {
|
func welcome(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
w.Write([]byte("Welcome to this example.\n=> /login Login\n"))
|
fmt.Fprintln(w, "Welcome to this example.")
|
||||||
|
fmt.Fprintln(w, "=> /login Login")
|
||||||
}
|
}
|
||||||
|
|
||||||
func login(w *gmi.ResponseWriter, r *gmi.Request) {
|
func login(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
cert, ok := gmi.Certificate(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
username, ok := gmi.Input(w, r, "Username")
|
username, ok := gmi.Input(w, r, "Username")
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@ -73,11 +77,13 @@ func login(w *gmi.ResponseWriter, r *gmi.Request) {
|
|||||||
username: username,
|
username: username,
|
||||||
}
|
}
|
||||||
gmi.Redirect(w, r, "/login/password")
|
gmi.Redirect(w, r, "/login/password")
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginPassword(w *gmi.ResponseWriter, r *gmi.Request) {
|
func loginPassword(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
cert, ok := gmi.Certificate(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
session, ok := getSession(cert)
|
session, ok := getSession(cert)
|
||||||
if !ok {
|
if !ok {
|
||||||
gmi.CertificateNotAuthorized(w, r)
|
gmi.CertificateNotAuthorized(w, r)
|
||||||
@ -95,32 +101,39 @@ func loginPassword(w *gmi.ResponseWriter, r *gmi.Request) {
|
|||||||
} else {
|
} else {
|
||||||
gmi.SensitiveInput(w, r, "Wrong password. Try again")
|
gmi.SensitiveInput(w, r, "Wrong password. Try again")
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func logout(w *gmi.ResponseWriter, r *gmi.Request) {
|
func logout(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
cert, ok := gmi.Certificate(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
fingerprint := gmi.Fingerprint(cert)
|
fingerprint := gmi.Fingerprint(cert)
|
||||||
delete(sessions, fingerprint)
|
delete(sessions, fingerprint)
|
||||||
})
|
fmt.Fprintln(w, "Successfully logged out.")
|
||||||
w.Write([]byte("Successfully logged out.\n"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func profile(w *gmi.ResponseWriter, r *gmi.Request) {
|
func profile(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
cert, ok := gmi.Certificate(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
session, ok := getSession(cert)
|
session, ok := getSession(cert)
|
||||||
if !ok {
|
if !ok {
|
||||||
gmi.CertificateNotAuthorized(w, r)
|
gmi.CertificateNotAuthorized(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := logins[session.username]
|
user := logins[session.username]
|
||||||
profile := fmt.Sprintf("Username: %s\nAdmin: %t\n=> /logout Logout", session.username, user.admin)
|
fmt.Fprintln(w, "Username:", session.username)
|
||||||
w.Write([]byte(profile))
|
fmt.Fprintln(w, "Admin:", user.admin)
|
||||||
})
|
fmt.Fprintln(w, "=> /logout Logout")
|
||||||
}
|
}
|
||||||
|
|
||||||
func admin(w *gmi.ResponseWriter, r *gmi.Request) {
|
func admin(w *gmi.ResponseWriter, r *gmi.Request) {
|
||||||
gmi.WithCertificate(w, r, func(cert *x509.Certificate) {
|
cert, ok := gmi.Certificate(w, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
session, ok := getSession(cert)
|
session, ok := getSession(cert)
|
||||||
if !ok {
|
if !ok {
|
||||||
gmi.CertificateNotAuthorized(w, r)
|
gmi.CertificateNotAuthorized(w, r)
|
||||||
@ -131,6 +144,5 @@ func admin(w *gmi.ResponseWriter, r *gmi.Request) {
|
|||||||
gmi.CertificateNotAuthorized(w, r)
|
gmi.CertificateNotAuthorized(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Write([]byte("Welcome to the admin portal.\n"))
|
fmt.Fprintln(w, "Welcome to the admin portal.")
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
11
server.go
11
server.go
@ -311,15 +311,14 @@ func CertificateNotAuthorized(w *ResponseWriter, r *Request) {
|
|||||||
w.WriteHeader(StatusCertificateNotAuthorized, "Certificate not authorized")
|
w.WriteHeader(StatusCertificateNotAuthorized, "Certificate not authorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithCertificate either responds with CertificateRequired if the client did
|
// Certificate returns the request certificate. If one is not provided,
|
||||||
// not provide a certificate, or calls f with the first ceritificate provided.
|
// it returns nil and responds with StatusCertificateRequired.
|
||||||
func WithCertificate(w *ResponseWriter, r *Request, f func(*x509.Certificate)) {
|
func Certificate(w *ResponseWriter, r *Request) (*x509.Certificate, bool) {
|
||||||
if len(r.TLS.PeerCertificates) == 0 {
|
if len(r.TLS.PeerCertificates) == 0 {
|
||||||
CertificateRequired(w, r)
|
CertificateRequired(w, r)
|
||||||
return
|
return nil, false
|
||||||
}
|
}
|
||||||
cert := r.TLS.PeerCertificates[0]
|
return r.TLS.PeerCertificates[0], true
|
||||||
f(cert)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResponderFunc is a wrapper around a bare function that implements Handler.
|
// ResponderFunc is a wrapper around a bare function that implements Handler.
|
||||||
|
Loading…
Reference in New Issue
Block a user