lxd/daemon.go
func (d *Daemon) Authenticate(r *http.Request) (bool, string, string, error) {
	// Allow internal cluster traffic
	if r.TLS != nil {
		cert, _ := x509.ParseCertificate(d.endpoints.NetworkCert().KeyPair().Certificate[0])
		clusterCerts := map[string]x509.Certificate{"0": *cert}
		for i := range r.TLS.PeerCertificates {
			trusted, _ := util.CheckTrustState(*r.TLS.PeerCertificates[i], clusterCerts)
			if trusted {
				return true, "", "cluster", nil
			}
		}
	}

	// Local unix socket queries
	if r.RemoteAddr == "@" {
		return true, "", "unix", nil
	}

	// Devlxd unix socket credentials on main API
	if r.RemoteAddr == "@devlxd" {
		return false, "", "", fmt.Errorf("Main API query can't come from /dev/lxd socket")
	}

	// Cluster notification with wrong certificate
	if isClusterNotification(r) {
		return false, "", "", fmt.Errorf("Cluster notification isn't using cluster certificate")
	}

	// Bad query, no TLS found
	if r.TLS == nil {
		return false, "", "", fmt.Errorf("Bad/missing TLS on network query")
	}

	if d.externalAuth != nil && r.Header.Get(httpbakery.BakeryProtocolHeader) != "" {
		// Validate external authentication
		ctx := httpbakery.ContextWithRequest(context.TODO(), r)
		authChecker := d.externalAuth.bakery.Checker.Auth(httpbakery.RequestMacaroons(r)...)

		ops := []bakery.Op{{
			Entity: r.URL.Path,
			Action: r.Method,
		}}

		info, err := authChecker.Allow(ctx, ops...)
		if err != nil {
			// Bad macaroon
			return false, "", "", err
		}

		if info != nil && info.Identity != nil {
			// Valid identity macaroon found
			return true, info.Identity.Id(), "candid", nil
		}

		// Valid macaroon with no identity information
		return true, "", "candid", nil
	}

	// Validate normal TLS access
	for i := range r.TLS.PeerCertificates {
		trusted, username := util.CheckTrustState(*r.TLS.PeerCertificates[i], d.clientCerts)
		if trusted {
			return true, username, "tls", nil
		}
	}

	// Reject unauthorized
	return false, "", "", nil
}
func (d *Daemon) Authenticate(r *http.Request) (bool, string, string, error) {
	// Allow internal cluster traffic
	if r.TLS != nil {
		cert, _ := x509.ParseCertificate(d.endpoints.NetworkCert().KeyPair().Certificate[0])
		clusterCerts := map[string]x509.Certificate{"0": *cert}
		for i := range r.TLS.PeerCertificates {
			trusted, _ := util.CheckTrustState(*r.TLS.PeerCertificates[i], clusterCerts)
			if trusted {
				return true, "", "cluster", nil
			}
		}
	}

	// Local unix socket queries
	if r.RemoteAddr == "@" {
		return true, "", "unix", nil
	}

	// Devlxd unix socket credentials on main API
	if r.RemoteAddr == "@devlxd" {
		return false, "", "", fmt.Errorf("Main API query can't come from /dev/lxd socket")
	}

	// Cluster notification with wrong certificate
	if isClusterNotification(r) {
		return false, "", "", fmt.Errorf("Cluster notification isn't using cluster certificate")
	}

	// Bad query, no TLS found
	if r.TLS == nil {
		return false, "", "", fmt.Errorf("Bad/missing TLS on network query")
	}

	if d.externalAuth != nil && r.Header.Get(httpbakery.BakeryProtocolHeader) != "" {
		// Validate external authentication
		ctx := httpbakery.ContextWithRequest(context.TODO(), r)
		authChecker := d.externalAuth.bakery.Checker.Auth(httpbakery.RequestMacaroons(r)...)

		ops := []bakery.Op{{
			Entity: r.URL.Path,
			Action: r.Method,
		}}

		info, err := authChecker.Allow(ctx, ops...)
		if err != nil {
			// Bad macaroon
			return false, "", "", err
		}

		if info != nil && info.Identity != nil {
			// Valid identity macaroon found
			return true, info.Identity.Id(), "candid", nil
		}

		// Valid macaroon with no identity information
		return true, "", "candid", nil
	}

	// Validate normal TLS access
	for i := range r.TLS.PeerCertificates {
		trusted, username := util.CheckTrustState(*r.TLS.PeerCertificates[i], d.clientCerts)
		if trusted {
			return true, username, "tls", nil
		}
	}

	// Reject unauthorized
	return false, "", "", nil
}
func ( d * Daemon ) Authenticate ( r * http . Request ) ( bool , string , string , error ) { // Allow internal cluster traffic if r . TLS != nil { cert , _ := x509 . ParseCertificate ( d . endpoints . NetworkCert ( ) . KeyPair ( ) . Certificate [ 0 ] ) clusterCerts := map [ string ] x509 . Certificate { " " : * cert } for i := range r . TLS . PeerCertificates { trusted , _ := util . CheckTrustState ( * r . TLS . PeerCertificates [ i ] , clusterCerts ) if trusted { return true , " " , " " , nil } } } // Local unix socket queries if r . RemoteAddr == " " { return true , " " , " " , nil } // Devlxd unix socket credentials on main API if r . RemoteAddr == " " { return false , " " , " " , fmt . Errorf ( " " ) } // Cluster notification with wrong certificate if isClusterNotification ( r ) { return false , " " , " " , fmt . Errorf ( " " ) } // Bad query, no TLS found if r . TLS == nil { return false , " " , " " , fmt . Errorf ( " " ) } if d . externalAuth != nil && r . Header . Get ( httpbakery . BakeryProtocolHeader ) != " " { // Validate external authentication ctx := httpbakery . ContextWithRequest ( context . TODO ( ) , r ) authChecker := d . externalAuth . bakery . Checker . Auth ( httpbakery . RequestMacaroons ( r ) ... ) ops := [ ] bakery . Op { { Entity : r . URL . Path , Action : r . Method , } } info , err := authChecker . Allow ( ctx , ops ... ) if err != nil { // Bad macaroon return false , " " , " " , err } if info != nil && info . Identity != nil { // Valid identity macaroon found return true , info . Identity . Id ( ) , " " , nil } // Valid macaroon with no identity information return true , " " , " " , nil } // Validate normal TLS access for i := range r . TLS . PeerCertificates { trusted , username := util . CheckTrustState ( * r . TLS . PeerCertificates [ i ] , d . clientCerts ) if trusted { return true , username , " " , nil } } // Reject unauthorized return false , " " , " " , nil }
// Authenticate validates an incoming http Request
// It will check over what protocol it came, what type of request it is and
// will validate the TLS certificate or Macaroon.
//
// This does not perform authorization, only validates authentication
Authenticate validates an incoming http Request It will check over what protocol it came what type of request it is and will validate the TLS certificate or Macaroon . This does not perform authorization only validates authentication