chldapasswd/login.go

102 lines
2.6 KiB
Go

package main
import (
"fmt"
"html/template"
"log"
"net/http"
"strings"
"github.com/go-ldap/ldap/v3"
)
func login(login string, password string) ([]*ldap.EntryAttribute, error) {
conn, err := myLDAP.Connect()
if err != nil || conn == nil {
return nil, err
}
if err = conn.ServiceBind(); err != nil {
return nil, err
}
var dn string
dn, err = conn.SearchDN(login, true)
if err != nil {
dn, err = conn.SearchDN(login, false)
if err != nil {
return nil, err
}
}
if err := conn.Bind(dn, password); err != nil {
return nil, err
}
if entries, err := conn.GetEntry(dn); err != nil {
return nil, err
} else {
return entries, nil
}
}
func tryLogin(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
displayTmpl(w, "login.html", map[string]interface{}{})
return
}
if entries, err := login(r.PostFormValue("login"), r.PostFormValue("password")); err != nil {
log.Println(err)
displayTmplError(w, http.StatusInternalServerError, "login.html", map[string]interface{}{"error": err.Error()})
} else {
cnt := "<ul>"
for _, e := range entries {
for _, v := range e.Values {
if e.Name == "userPassword" {
cnt += "<li><strong>" + e.Name + ":</strong> <em>[...]</em></li>"
} else {
cnt += "<li><strong>" + e.Name + ":</strong> " + v + "</li>"
}
}
}
displayTmpl(w, "message.html", map[string]interface{}{"details": template.HTML(`Login ok<br><br>Here are the information we have about you:` + cnt + "</ul>")})
}
}
func httpBasicAuth(w http.ResponseWriter, r *http.Request) {
if user, pass, ok := r.BasicAuth(); ok {
if entries, err := login(user, pass); err != nil {
w.Header().Set("WWW-Authenticate", `Basic realm="nemunai.re restricted"`)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
return
} else {
w.Header().Set("X-Remote-User", user)
w.WriteHeader(http.StatusOK)
for _, e := range entries {
for _, v := range e.Values {
if e.Name != "userPassword" {
w.Write([]byte(fmt.Sprintf("%s: %s", e.Name, v)))
}
}
}
return
}
} else if v := r.Header.Get("X-Special-Auth"); v == "docker-registry" {
method := r.Header.Get("X-Original-Method")
uri := r.Header.Get("X-Original-URI")
if (method == "GET" || method == "HEAD") && uri != "" && uri != "/" && uri != "/v2/" && !strings.HasPrefix(uri, "/v2/_") {
log.Printf("docker-registry: Permit anonymous login for URL %s", uri)
w.Header().Set("X-Remote-User", "anonymous")
w.WriteHeader(http.StatusOK)
return
}
}
w.Header().Set("WWW-Authenticate", `Basic realm="nemunai.re restricted"`)
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Please login"))
}