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
}
// 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