Skip to content

Commit

Permalink
incusd/images: Perform access control after fingerprint expansion
Browse files Browse the repository at this point in the history
Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
  • Loading branch information
stgraber committed Dec 5, 2023
1 parent 2a29732 commit 358d442
Showing 1 changed file with 22 additions and 21 deletions.
43 changes: 22 additions & 21 deletions cmd/incusd/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -2795,17 +2795,7 @@ func imageGet(d *Daemon, r *http.Request) response.Response {
return response.SmartError(err)
}

var userCanViewImage bool
err = s.Authorizer.CheckPermission(r.Context(), r, auth.ObjectImage(projectName, fingerprint), auth.EntitlementCanView)
if err == nil {
userCanViewImage = true
} else if !api.StatusErrorCheck(err, http.StatusForbidden) {
return response.SmartError(err)
}

public := d.checkTrustedClient(r) != nil || !userCanViewImage
secret := r.FormValue("secret")

// Get the image (expand partial fingerprints).
var info *api.Image
err = s.DB.Cluster.Transaction(r.Context(), func(ctx context.Context, tx *db.ClusterTx) error {
info, err = doImageGet(ctx, tx, projectName, fingerprint, false)
Expand All @@ -2819,6 +2809,17 @@ func imageGet(d *Daemon, r *http.Request) response.Response {
return response.SmartError(err)
}

var userCanViewImage bool
err = s.Authorizer.CheckPermission(r.Context(), r, auth.ObjectImage(projectName, info.Fingerprint), auth.EntitlementCanView)
if err == nil {
userCanViewImage = true
} else if !api.StatusErrorCheck(err, http.StatusForbidden) {
return response.SmartError(err)
}

public := d.checkTrustedClient(r) != nil || !userCanViewImage
secret := r.FormValue("secret")

op, err := imageValidSecret(s, r, projectName, info.Fingerprint, secret)
if err != nil {
return response.SmartError(err)
Expand Down Expand Up @@ -3794,8 +3795,15 @@ func imageExport(d *Daemon, r *http.Request) response.Response {
return response.SmartError(err)
}

// Get the image (expand the fingerprint).
_, imgInfo, err := s.DB.Cluster.GetImage(fingerprint, dbCluster.ImageFilter{Project: &projectName})
if err != nil {
return response.SmartError(err)
}

// Access control.
var userCanViewImage bool
err = s.Authorizer.CheckPermission(r.Context(), r, auth.ObjectImage(projectName, fingerprint), auth.EntitlementCanView)
err = s.Authorizer.CheckPermission(r.Context(), r, auth.ObjectImage(projectName, imgInfo.Fingerprint), auth.EntitlementCanView)
if err == nil {
userCanViewImage = true
} else if !api.StatusErrorCheck(err, http.StatusForbidden) {
Expand All @@ -3805,23 +3813,16 @@ func imageExport(d *Daemon, r *http.Request) response.Response {
public := d.checkTrustedClient(r) != nil || !userCanViewImage
secret := r.FormValue("secret")

var imgInfo *api.Image
if r.RemoteAddr == "@dev_incus" {
// /dev/incus API requires exact match
_, imgInfo, err = s.DB.Cluster.GetImage(fingerprint, dbCluster.ImageFilter{Project: &projectName})
if err != nil {
return response.SmartError(err)
if imgInfo.Fingerprint != fingerprint {
return response.NotFound(fmt.Errorf("Image %q not found", fingerprint))
}

if !imgInfo.Public && !imgInfo.Cached {
return response.NotFound(fmt.Errorf("Image %q not found", fingerprint))
}
} else {
_, imgInfo, err = s.DB.Cluster.GetImage(fingerprint, dbCluster.ImageFilter{Project: &projectName})
if err != nil {
return response.SmartError(err)
}

op, err := imageValidSecret(s, r, projectName, imgInfo.Fingerprint, secret)
if err != nil {
return response.SmartError(err)
Expand Down

0 comments on commit 358d442

Please sign in to comment.