// handleAuth checks authentication against etcd using CanConnect and sets the needed // environment variables for later parts of the builder to use. It takes in the SSH // connection metadata, the public key of the user, and returns the SSH // permissions of the connection and an error if they are not authorized. func handleAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if conn.User() != "git" { return nil, ErrUnauthorized } keydata := string(bytes.TrimSpace(ssh.MarshalAuthorizedKey(key))) etcd := etcd.NewClient([]string{*etcduplink}) fp := utils.GetFingerprint(keydata) user, allowed := utils.CanConnect(etcd, keydata) if allowed { log.Printf("User %s (%s) accepted with fingerprint %s", user, conn.RemoteAddr().String(), fp) return &ssh.Permissions{ Extensions: map[string]string{ "environ": fmt.Sprintf("USER=%s\nKEY='%s'\nFINGERPRINT=%s\n", user, keydata, fp), "user": user, "fingerprint": fp, }, }, nil } else { log.Printf("Connection from %s rejected (bad key)", conn.RemoteAddr().String()) } return nil, ErrUnauthorized }
func (a *Auth) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { authkey := r.Header.Get(a.HeaderName) if authkey == "" { http.Error(rw, `{"code": 401, "message": "Not authorized", "data": ["Try setting `+a.HeaderName+`."]}`, http.StatusUnauthorized) } if user, allowed := utils.CanConnect(a.e, authkey); allowed { r.Header.Set("X-Lagann-User", user) next(rw, r) } else { http.Error(rw, `{"code": 401, "message": "No account found", "data": ["No registration found or user was deleted."]}`, http.StatusUnauthorized) } }