diff --git a/go.mod b/go.mod index 009615a8638..e79d5efd1aa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/containers/podman/v6 // Warning: if there is a "toolchain" directive anywhere in this file (and most of the // time there shouldn't be), its version must be an exact match to the "go" directive. -go 1.24.2 +go 1.24.6 require ( github.com/Microsoft/go-winio v0.6.2 @@ -58,7 +58,7 @@ require ( github.com/openshift/imagebuilder v1.2.19 github.com/rootless-containers/rootlesskit/v2 v2.3.5 github.com/shirou/gopsutil/v4 v4.25.10 - github.com/sirupsen/logrus v1.9.3 + github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af github.com/spf13/cobra v1.10.1 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 @@ -102,7 +102,7 @@ require ( github.com/containers/common v0.62.2 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/luksy v0.0.0-20250910190358-2cf5bc928957 // indirect - github.com/coreos/go-oidc/v3 v3.14.1 // indirect + github.com/coreos/go-oidc/v3 v3.16.0 // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -132,7 +132,6 @@ require ( github.com/jinzhu/copier v0.4.0 // indirect github.com/klauspost/compress v1.18.1 // indirect github.com/kr/fs v0.1.0 // indirect - github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-runewidth v0.0.19 // indirect @@ -148,28 +147,26 @@ require ( github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/runc v1.3.3 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/sftp v1.13.10 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/proglottis/gpgme v0.1.5 // indirect + github.com/proglottis/gpgme v0.1.6 // indirect github.com/seccomp/libseccomp-golang v0.11.1 // indirect github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect - github.com/segmentio/ksuid v1.0.4 // indirect - github.com/sigstore/fulcio v1.7.1 // indirect - github.com/sigstore/protobuf-specs v0.4.1 // indirect - github.com/sigstore/sigstore v1.9.5 // indirect + github.com/sigstore/fulcio v1.8.1 // indirect + github.com/sigstore/protobuf-specs v0.5.0 // indirect + github.com/sigstore/sigstore v1.9.6-0.20251111174640-d8ab8afb1326 // indirect github.com/skeema/knownhosts v1.3.2 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/smallstep/pkcs7 v0.1.1 // indirect github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect github.com/sylabs/sif/v2 v2.22.0 // indirect github.com/tchap/go-patricia/v2 v2.3.3 // indirect - github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect @@ -183,15 +180,17 @@ require ( go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/oauth2 v0.33.0 // indirect golang.org/x/text v0.31.0 // indirect - golang.org/x/time v0.11.0 // indirect + golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.38.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect tags.cncf.io/container-device-interface/specs-go v1.0.1-0.20251120202831-139ffec09210 // indirect ) + +replace go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251125184859-3ed278e8d0ca diff --git a/go.sum b/go.sum index e3c7a2fa249..69229a266d8 100644 --- a/go.sum +++ b/go.sum @@ -20,14 +20,10 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6 h1:5L8Mj9Co9sJVgW3TpYk2gxGJnDjsYuboNTcRmbtGKGs= github.com/aead/serpent v0.0.0-20160714141033-fba169763ea6/go.mod h1:3HgLJ9d18kXMLQlJvIY3+FszZYMxCz8WfE2MQ7hDY0w= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/checkpointctl v1.4.0 h1:3kRns56TArwiyHOMakaumUgSZZlB1hZBkjVgR6IeZ3E= github.com/checkpoint-restore/checkpointctl v1.4.0/go.mod h1:ynQ52zQBazgcTZuxpwTFzRinIcAf0haDTC1X1LA/FKA= github.com/checkpoint-restore/go-criu/v7 v7.2.0 h1:qGiWA4App1gGlEfIJ68WR9jbezV9J7yZdjzglezcqKo= @@ -81,8 +77,8 @@ github.com/containers/psgo v1.10.0 h1:r9cEzAMVRtC0sw4ayIPjbd9EgF9pPaTCqKgDHhS0D/ github.com/containers/psgo v1.10.0/go.mod h1:e44fw+1A7eJH1y0eWAo3P7sjfftXDlfF4AY498h+svQ= github.com/containers/winquit v1.1.0 h1:jArun04BNDQvt2W0Y78kh9TazN2EIEMG5Im6/JY7+pE= github.com/containers/winquit v1.1.0/go.mod h1:PsPeZlnbkmGGIToMPHF1zhWjBUkd8aHjMOr/vFcPxw8= -github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk= -github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU= +github.com/coreos/go-oidc/v3 v3.16.0 h1:qRQUCFstKpXwmEjDQTIbyY/5jF00+asXzSkmkoa/mow= +github.com/coreos/go-oidc/v3 v3.16.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= @@ -108,8 +104,8 @@ github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWh github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v29.0.2+incompatible h1:iLuKy2GWOSLXGp8feLYBJQVDv7m/8xoofz6lPq41x6A= -github.com/docker/cli v29.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.0.4+incompatible h1:mffN/hPqaI39vx/4QiSkdldHeM0rP1ZZBIXRUOPI5+I= +github.com/docker/cli v29.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= @@ -155,8 +151,6 @@ github.com/go-rod/rod v0.116.2 h1:A5t2Ky2A+5eD/ZJQr1EfsQSe5rms5Xof/qj296e+ZqA= github.com/go-rod/rod v0.116.2/go.mod h1:H+CMO9SCNc2TJ2WfrG+pKhITz57uGNYU43qYHh438Mg= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= -github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.2.0 h1:3WexO+U+yg9T70v9FdHr9kCxYlazaAXUhx2VMkbfax8= @@ -188,8 +182,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -213,8 +207,6 @@ github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 h1:q3OEI9RaN/wwc github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905/go.mod h1:VvGYjkZoJyKqlmT1yzakUs4mfKMNB0XdODP0+rdml6k= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= -github.com/jmhodges/clock v1.2.0 h1:eq4kys+NI0PLngzaHEe7AmPT90XMGIEySD1JfV1PDIs= -github.com/jmhodges/clock v1.2.0/go.mod h1:qKjhA7x7u/lQpPB1XAqX1b1lCI/w3/fNuYpI/ZjLynI= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= @@ -235,10 +227,10 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ= -github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422 h1:XvRuyDDRvi+UDxHN/M4MW4HxjmNVMmUKQj/+AbgsYgk= github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422/go.mod h1:JLgfq4XMVbvfNlAXla/41lZnp21O72a/wWHGJefAvgQ= +github.com/lsm5/container-libs/common v0.0.0-20251125184859-3ed278e8d0ca h1:X9MKMFBADGn+H7TdzyU/i5U4Y6wJtBBYYkQXA0FKJqs= +github.com/lsm5/container-libs/common v0.0.0-20251125184859-3ed278e8d0ca/go.mod h1:Hkrtv0G+eJBvJxXlDBB5O10fIhHuq7Jq4MGJYDkHApw= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -296,12 +288,11 @@ github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFL github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= @@ -326,6 +317,8 @@ github.com/openshift/imagebuilder v1.2.19 h1:Xqq36KMJgsRU2MPaLRML23Myvk+AaY8pE8V github.com/openshift/imagebuilder v1.2.19/go.mod h1:fdbnfQWjxMBoB/jrvEzUk+UT1zqvtZZj7oQ7GU6RD9I= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU= @@ -337,16 +330,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/proglottis/gpgme v0.1.5 h1:KCGyOw8sQ+SI96j6G8D8YkOGn+1TwbQTT9/zQXoVlz0= -github.com/proglottis/gpgme v0.1.5/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= -github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= -github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= -github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/proglottis/gpgme v0.1.6 h1:8WpQ8VWggLdxkuTnW+sZ1r1t92XBNd8GZNDhQ4Rz+98= +github.com/proglottis/gpgme v0.1.6/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rootless-containers/rootlesskit/v2 v2.3.5 h1:WGY05oHE7xQpSkCGfYP9lMY5z19tCxA8PhWlvP1cKx8= @@ -360,24 +345,20 @@ github.com/seccomp/libseccomp-golang v0.11.1 h1:wuk4ZjSx6kyQII4rj6G6fvVzRHQaSiPv github.com/seccomp/libseccomp-golang v0.11.1/go.mod h1:5m1Lk8E9OwgZTTVz4bBOer7JuazaBa+xTkM895tDiWc= github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL5qTdn9lR8XKHf4RUyG1Sx3g= github.com/secure-systems-lab/go-securesystemslib v0.9.1/go.mod h1:np53YzT0zXGMv6x4iEWc9Z59uR+x+ndLwCLqPYpLXVU= -github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= -github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shirou/gopsutil/v4 v4.25.10 h1:at8lk/5T1OgtuCp+AwrDofFRjnvosn0nkN2OLQ6g8tA= github.com/shirou/gopsutil/v4 v4.25.10/go.mod h1:+kSwyC8DRUD9XXEHCAFjK+0nuArFJM0lva+StQAcskM= -github.com/sigstore/fulcio v1.7.1 h1:RcoW20Nz49IGeZyu3y9QYhyyV3ZKQ85T+FXPKkvE+aQ= -github.com/sigstore/fulcio v1.7.1/go.mod h1:7lYY+hsd8Dt+IvKQRC+KEhWpCZ/GlmNvwIa5JhypMS8= -github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc= -github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= -github.com/sigstore/sigstore v1.9.5 h1:Wm1LT9yF4LhQdEMy5A2JeGRHTrAWGjT3ubE5JUSrGVU= -github.com/sigstore/sigstore v1.9.5/go.mod h1:VtxgvGqCmEZN9X2zhFSOkfXxvKUjpy8RpUW39oCtoII= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sigstore/fulcio v1.8.1 h1:PmoQv3XmhjR2BWFWw5LcMUXJPmhyizOIL7HeYnpio58= +github.com/sigstore/fulcio v1.8.1/go.mod h1:7tP3KW9eCGlPYRj5N4MSuUOat7CkeIHuXZ2jAUQ+Rwc= +github.com/sigstore/protobuf-specs v0.5.0 h1:F8YTI65xOHw70NrvPwJ5PhAzsvTnuJMGLkA4FIkofAY= +github.com/sigstore/protobuf-specs v0.5.0/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= +github.com/sigstore/sigstore v1.9.6-0.20251111174640-d8ab8afb1326 h1:s39MsSDVn8LhePV5adidcOjjKHaplLxpHM1mvbC24l4= +github.com/sigstore/sigstore v1.9.6-0.20251111174640-d8ab8afb1326/go.mod h1:xSCb7eki7lCdi+mNh4I4MVpKPP2cWGtDYmSPPmX/K70= +github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af h1:Sp5TG9f7K39yfB+If0vjp97vuT74F72r8hfRpP8jLU0= +github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg= github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= @@ -405,8 +386,6 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0= -github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso= @@ -457,8 +436,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= @@ -469,16 +448,14 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.podman.io/common v0.66.1-0.20251122023359-22d50c57903c h1:BVbMOd8iQudCWi7ZovrurXCF3OBrVjWHtRws4knbKgE= -go.podman.io/common v0.66.1-0.20251122023359-22d50c57903c/go.mod h1:8qbjUhjwp4i5u1O19vzwYW2qwIuPdFXIuv4nl3Z8px8= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.podman.io/image/v5 v5.38.1-0.20251122023359-22d50c57903c h1:5RHfIQ06rcaVMCRM8TxTK8/tU550tQsVrDC8LQGm9LM= go.podman.io/image/v5 v5.38.1-0.20251122023359-22d50c57903c/go.mod h1:9DniP9NaGH03kzwNKYEtOXgRJwO+cQHENH+G4sOwLNc= go.podman.io/storage v1.61.1-0.20251122023359-22d50c57903c h1:KXfC7Sd8oNDasi/2LkNxD0O9Yz67FkTVBE6e0h9AqZ4= go.podman.io/storage v1.61.1-0.20251122023359-22d50c57903c/go.mod h1:4p18A5ymiiJTllTu2Eo7CX88SO+V110TMzi31pXsb1s= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -580,8 +557,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/libpod/info_linux.go b/libpod/info_linux.go index 67f1000d36e..108d5cf4576 100644 --- a/libpod/info_linux.go +++ b/libpod/info_linux.go @@ -30,10 +30,7 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error { return fmt.Errorf("getting Seccomp profile path: %w", err) } - // Get Map of all available controllers - // FIXME: AvailableControllers should be further simplified once CGv1 removal - // in container-libs is complete. - availableControllers, err := cgroups.AvailableControllers(nil, true) + availableControllers, err := cgroups.AvailableControllers() if err != nil { return fmt.Errorf("getting available cgroup controllers: %w", err) } diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go index 6a846ece95b..c5e4d787c8f 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/jwks.go @@ -11,7 +11,6 @@ import ( "io" "net/http" "sync" - "time" jose "github.com/go-jose/go-jose/v4" ) @@ -57,16 +56,12 @@ func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, // The returned KeySet is a long lived verifier that caches keys based on any // keys change. Reuse a common remote key set instead of creating new ones as needed. func NewRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { - return newRemoteKeySet(ctx, jwksURL, time.Now) + return newRemoteKeySet(ctx, jwksURL) } -func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time) *RemoteKeySet { - if now == nil { - now = time.Now - } +func newRemoteKeySet(ctx context.Context, jwksURL string) *RemoteKeySet { return &RemoteKeySet{ jwksURL: jwksURL, - now: now, // For historical reasons, this package uses contexts for configuration, not just // cancellation. In hindsight, this was a bad idea. // @@ -81,7 +76,6 @@ func newRemoteKeySet(ctx context.Context, jwksURL string, now func() time.Time) // a jwks_uri endpoint. type RemoteKeySet struct { jwksURL string - now func() time.Time // Used for configuration. Cancelation is ignored. ctx context.Context diff --git a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go index 52b27b746a2..a8bf107d4a6 100644 --- a/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go +++ b/vendor/github.com/coreos/go-oidc/v3/oidc/verify.go @@ -1,15 +1,11 @@ package oidc import ( - "bytes" "context" - "encoding/base64" "encoding/json" - "errors" "fmt" "io" "net/http" - "strings" "time" jose "github.com/go-jose/go-jose/v4" @@ -145,18 +141,6 @@ func (p *Provider) newVerifier(keySet KeySet, config *Config) *IDTokenVerifier { return NewVerifier(p.issuer, keySet, config) } -func parseJWT(p string) ([]byte, error) { - parts := strings.Split(p, ".") - if len(parts) < 2 { - return nil, fmt.Errorf("oidc: malformed jwt, expected 3 parts got %d", len(parts)) - } - payload, err := base64.RawURLEncoding.DecodeString(parts[1]) - if err != nil { - return nil, fmt.Errorf("oidc: malformed jwt payload: %v", err) - } - return payload, nil -} - func contains(sli []string, ele string) bool { for _, s := range sli { if s == ele { @@ -219,12 +203,49 @@ func resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src // // token, err := verifier.Verify(ctx, rawIDToken) func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDToken, error) { - // Throw out tokens with invalid claims before trying to verify the token. This lets - // us do cheap checks before possibly re-syncing keys. - payload, err := parseJWT(rawIDToken) + var supportedSigAlgs []jose.SignatureAlgorithm + for _, alg := range v.config.SupportedSigningAlgs { + supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg)) + } + if len(supportedSigAlgs) == 0 { + // If no algorithms were specified by both the config and discovery, default + // to the one mandatory algorithm "RS256". + supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256} + } + if v.config.InsecureSkipSignatureCheck { + // "none" is a required value to even parse a JWT with the "none" algorithm + // using go-jose. + supportedSigAlgs = append(supportedSigAlgs, "none") + } + + // Parse and verify the signature first. This at least forces the user to have + // a valid, signed ID token before we do any other processing. + jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs) if err != nil { return nil, fmt.Errorf("oidc: malformed jwt: %v", err) } + switch len(jws.Signatures) { + case 0: + return nil, fmt.Errorf("oidc: id token not signed") + case 1: + default: + return nil, fmt.Errorf("oidc: multiple signatures on id token not supported") + } + sig := jws.Signatures[0] + + var payload []byte + if v.config.InsecureSkipSignatureCheck { + // Yolo mode. + payload = jws.UnsafePayloadWithoutVerification() + } else { + // The JWT is attached here for the happy path to avoid the verifier from + // having to parse the JWT twice. + ctx = context.WithValue(ctx, parsedJWTKey, jws) + payload, err = v.keySet.VerifySignature(ctx, rawIDToken) + if err != nil { + return nil, fmt.Errorf("failed to verify signature: %v", err) + } + } var token idToken if err := json.Unmarshal(payload, &token); err != nil { return nil, fmt.Errorf("oidc: failed to unmarshal claims: %v", err) @@ -254,6 +275,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok AccessTokenHash: token.AtHash, claims: payload, distributedClaims: distributedClaims, + sigAlgorithm: sig.Header.Algorithm, } // Check issuer. @@ -306,45 +328,6 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok } } - if v.config.InsecureSkipSignatureCheck { - return t, nil - } - - var supportedSigAlgs []jose.SignatureAlgorithm - for _, alg := range v.config.SupportedSigningAlgs { - supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg)) - } - if len(supportedSigAlgs) == 0 { - // If no algorithms were specified by both the config and discovery, default - // to the one mandatory algorithm "RS256". - supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256} - } - jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs) - if err != nil { - return nil, fmt.Errorf("oidc: malformed jwt: %v", err) - } - - switch len(jws.Signatures) { - case 0: - return nil, fmt.Errorf("oidc: id token not signed") - case 1: - default: - return nil, fmt.Errorf("oidc: multiple signatures on id token not supported") - } - sig := jws.Signatures[0] - t.sigAlgorithm = sig.Header.Algorithm - - ctx = context.WithValue(ctx, parsedJWTKey, jws) - gotPayload, err := v.keySet.VerifySignature(ctx, rawIDToken) - if err != nil { - return nil, fmt.Errorf("failed to verify signature: %v", err) - } - - // Ensure that the payload returned by the square actually matches the payload parsed earlier. - if !bytes.Equal(gotPayload, payload) { - return nil, errors.New("oidc: internal error, payload parsed did not match previous payload") - } - return t, nil } diff --git a/vendor/github.com/letsencrypt/boulder/LICENSE.txt b/vendor/github.com/letsencrypt/boulder/LICENSE.txt deleted file mode 100644 index fa274d92d74..00000000000 --- a/vendor/github.com/letsencrypt/boulder/LICENSE.txt +++ /dev/null @@ -1,375 +0,0 @@ -Copyright 2016 ISRG. All rights reserved. - -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/letsencrypt/boulder/core/challenges.go b/vendor/github.com/letsencrypt/boulder/core/challenges.go deleted file mode 100644 index d5e7a87295e..00000000000 --- a/vendor/github.com/letsencrypt/boulder/core/challenges.go +++ /dev/null @@ -1,41 +0,0 @@ -package core - -import "fmt" - -func newChallenge(challengeType AcmeChallenge, token string) Challenge { - return Challenge{ - Type: challengeType, - Status: StatusPending, - Token: token, - } -} - -// HTTPChallenge01 constructs a http-01 challenge. -func HTTPChallenge01(token string) Challenge { - return newChallenge(ChallengeTypeHTTP01, token) -} - -// DNSChallenge01 constructs a dns-01 challenge. -func DNSChallenge01(token string) Challenge { - return newChallenge(ChallengeTypeDNS01, token) -} - -// TLSALPNChallenge01 constructs a tls-alpn-01 challenge. -func TLSALPNChallenge01(token string) Challenge { - return newChallenge(ChallengeTypeTLSALPN01, token) -} - -// NewChallenge constructs a challenge of the given kind. It returns an -// error if the challenge type is unrecognized. -func NewChallenge(kind AcmeChallenge, token string) (Challenge, error) { - switch kind { - case ChallengeTypeHTTP01: - return HTTPChallenge01(token), nil - case ChallengeTypeDNS01: - return DNSChallenge01(token), nil - case ChallengeTypeTLSALPN01: - return TLSALPNChallenge01(token), nil - default: - return Challenge{}, fmt.Errorf("unrecognized challenge type %q", kind) - } -} diff --git a/vendor/github.com/letsencrypt/boulder/core/interfaces.go b/vendor/github.com/letsencrypt/boulder/core/interfaces.go deleted file mode 100644 index 59b55a3f4b8..00000000000 --- a/vendor/github.com/letsencrypt/boulder/core/interfaces.go +++ /dev/null @@ -1,14 +0,0 @@ -package core - -import ( - "github.com/letsencrypt/boulder/identifier" -) - -// PolicyAuthority defines the public interface for the Boulder PA -// TODO(#5891): Move this interface to a more appropriate location. -type PolicyAuthority interface { - WillingToIssue([]string) error - ChallengesFor(identifier.ACMEIdentifier) ([]Challenge, error) - ChallengeTypeEnabled(AcmeChallenge) bool - CheckAuthz(*Authorization) error -} diff --git a/vendor/github.com/letsencrypt/boulder/core/objects.go b/vendor/github.com/letsencrypt/boulder/core/objects.go deleted file mode 100644 index c01f551abd8..00000000000 --- a/vendor/github.com/letsencrypt/boulder/core/objects.go +++ /dev/null @@ -1,505 +0,0 @@ -package core - -import ( - "crypto" - "encoding/base64" - "encoding/json" - "fmt" - "hash/fnv" - "net" - "strings" - "time" - - "github.com/go-jose/go-jose/v4" - "golang.org/x/crypto/ocsp" - - "github.com/letsencrypt/boulder/identifier" - "github.com/letsencrypt/boulder/probs" - "github.com/letsencrypt/boulder/revocation" -) - -// AcmeStatus defines the state of a given authorization -type AcmeStatus string - -// These statuses are the states of authorizations, challenges, and registrations -const ( - StatusUnknown = AcmeStatus("unknown") // Unknown status; the default - StatusPending = AcmeStatus("pending") // In process; client has next action - StatusProcessing = AcmeStatus("processing") // In process; server has next action - StatusReady = AcmeStatus("ready") // Order is ready for finalization - StatusValid = AcmeStatus("valid") // Object is valid - StatusInvalid = AcmeStatus("invalid") // Validation failed - StatusRevoked = AcmeStatus("revoked") // Object no longer valid - StatusDeactivated = AcmeStatus("deactivated") // Object has been deactivated -) - -// AcmeResource values identify different types of ACME resources -type AcmeResource string - -// The types of ACME resources -const ( - ResourceNewReg = AcmeResource("new-reg") - ResourceNewAuthz = AcmeResource("new-authz") - ResourceNewCert = AcmeResource("new-cert") - ResourceRevokeCert = AcmeResource("revoke-cert") - ResourceRegistration = AcmeResource("reg") - ResourceChallenge = AcmeResource("challenge") - ResourceAuthz = AcmeResource("authz") - ResourceKeyChange = AcmeResource("key-change") -) - -// AcmeChallenge values identify different types of ACME challenges -type AcmeChallenge string - -// These types are the available challenges -const ( - ChallengeTypeHTTP01 = AcmeChallenge("http-01") - ChallengeTypeDNS01 = AcmeChallenge("dns-01") - ChallengeTypeTLSALPN01 = AcmeChallenge("tls-alpn-01") -) - -// IsValid tests whether the challenge is a known challenge -func (c AcmeChallenge) IsValid() bool { - switch c { - case ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01: - return true - default: - return false - } -} - -// OCSPStatus defines the state of OCSP for a domain -type OCSPStatus string - -// These status are the states of OCSP -const ( - OCSPStatusGood = OCSPStatus("good") - OCSPStatusRevoked = OCSPStatus("revoked") - // Not a real OCSP status. This is a placeholder we write before the - // actual precertificate is issued, to ensure we never return "good" before - // issuance succeeds, for BR compliance reasons. - OCSPStatusNotReady = OCSPStatus("wait") -) - -var OCSPStatusToInt = map[OCSPStatus]int{ - OCSPStatusGood: ocsp.Good, - OCSPStatusRevoked: ocsp.Revoked, - OCSPStatusNotReady: -1, -} - -// DNSPrefix is attached to DNS names in DNS challenges -const DNSPrefix = "_acme-challenge" - -type RawCertificateRequest struct { - CSR JSONBuffer `json:"csr"` // The encoded CSR -} - -// Registration objects represent non-public metadata attached -// to account keys. -type Registration struct { - // Unique identifier - ID int64 `json:"id,omitempty" db:"id"` - - // Account key to which the details are attached - Key *jose.JSONWebKey `json:"key"` - - // Contact URIs - Contact *[]string `json:"contact,omitempty"` - - // Agreement with terms of service - Agreement string `json:"agreement,omitempty"` - - // InitialIP is the IP address from which the registration was created - InitialIP net.IP `json:"initialIp"` - - // CreatedAt is the time the registration was created. - CreatedAt *time.Time `json:"createdAt,omitempty"` - - Status AcmeStatus `json:"status"` -} - -// ValidationRecord represents a validation attempt against a specific URL/hostname -// and the IP addresses that were resolved and used. -type ValidationRecord struct { - // SimpleHTTP only - URL string `json:"url,omitempty"` - - // Shared - Hostname string `json:"hostname,omitempty"` - Port string `json:"port,omitempty"` - AddressesResolved []net.IP `json:"addressesResolved,omitempty"` - AddressUsed net.IP `json:"addressUsed,omitempty"` - // AddressesTried contains a list of addresses tried before the `AddressUsed`. - // Presently this will only ever be one IP from `AddressesResolved` since the - // only retry is in the case of a v6 failure with one v4 fallback. E.g. if - // a record with `AddressesResolved: { 127.0.0.1, ::1 }` were processed for - // a challenge validation with the IPv6 first flag on and the ::1 address - // failed but the 127.0.0.1 retry succeeded then the record would end up - // being: - // { - // ... - // AddressesResolved: [ 127.0.0.1, ::1 ], - // AddressUsed: 127.0.0.1 - // AddressesTried: [ ::1 ], - // ... - // } - AddressesTried []net.IP `json:"addressesTried,omitempty"` - // ResolverAddrs is the host:port of the DNS resolver(s) that fulfilled the - // lookup for AddressUsed. During recursive A and AAAA lookups, a record may - // instead look like A:host:port or AAAA:host:port - ResolverAddrs []string `json:"resolverAddrs,omitempty"` - // UsedRSAKEX is a *temporary* addition to the validation record, so we can - // see how many servers that we reach out to during HTTP-01 and TLS-ALPN-01 - // validation are only willing to negotiate RSA key exchange mechanisms. The - // field is not included in the serialized json to avoid cluttering the - // database and log lines. - // TODO(#7321): Remove this when we have collected sufficient data. - UsedRSAKEX bool `json:"-"` -} - -// Challenge is an aggregate of all data needed for any challenges. -// -// Rather than define individual types for different types of -// challenge, we just throw all the elements into one bucket, -// together with the common metadata elements. -type Challenge struct { - // Type is the type of challenge encoded in this object. - Type AcmeChallenge `json:"type"` - - // URL is the URL to which a response can be posted. Required for all types. - URL string `json:"url,omitempty"` - - // Status is the status of this challenge. Required for all types. - Status AcmeStatus `json:"status,omitempty"` - - // Validated is the time at which the server validated the challenge. Required - // if status is valid. - Validated *time.Time `json:"validated,omitempty"` - - // Error contains the error that occurred during challenge validation, if any. - // If set, the Status must be "invalid". - Error *probs.ProblemDetails `json:"error,omitempty"` - - // Token is a random value that uniquely identifies the challenge. It is used - // by all current challenges (http-01, tls-alpn-01, and dns-01). - Token string `json:"token,omitempty"` - - // ProvidedKeyAuthorization used to carry the expected key authorization from - // the RA to the VA. However, since this field is never presented to the user - // via the ACME API, it should not be on this type. - // - // Deprecated: use vapb.PerformValidationRequest.ExpectedKeyAuthorization instead. - // TODO(#7514): Remove this. - ProvidedKeyAuthorization string `json:"keyAuthorization,omitempty"` - - // Contains information about URLs used or redirected to and IPs resolved and - // used - ValidationRecord []ValidationRecord `json:"validationRecord,omitempty"` -} - -// ExpectedKeyAuthorization computes the expected KeyAuthorization value for -// the challenge. -func (ch Challenge) ExpectedKeyAuthorization(key *jose.JSONWebKey) (string, error) { - if key == nil { - return "", fmt.Errorf("Cannot authorize a nil key") - } - - thumbprint, err := key.Thumbprint(crypto.SHA256) - if err != nil { - return "", err - } - - return ch.Token + "." + base64.RawURLEncoding.EncodeToString(thumbprint), nil -} - -// RecordsSane checks the sanity of a ValidationRecord object before sending it -// back to the RA to be stored. -func (ch Challenge) RecordsSane() bool { - if ch.ValidationRecord == nil || len(ch.ValidationRecord) == 0 { - return false - } - - switch ch.Type { - case ChallengeTypeHTTP01: - for _, rec := range ch.ValidationRecord { - // TODO(#7140): Add a check for ResolverAddress == "" only after the - // core.proto change has been deployed. - if rec.URL == "" || rec.Hostname == "" || rec.Port == "" || rec.AddressUsed == nil || - len(rec.AddressesResolved) == 0 { - return false - } - } - case ChallengeTypeTLSALPN01: - if len(ch.ValidationRecord) > 1 { - return false - } - if ch.ValidationRecord[0].URL != "" { - return false - } - // TODO(#7140): Add a check for ResolverAddress == "" only after the - // core.proto change has been deployed. - if ch.ValidationRecord[0].Hostname == "" || ch.ValidationRecord[0].Port == "" || - ch.ValidationRecord[0].AddressUsed == nil || len(ch.ValidationRecord[0].AddressesResolved) == 0 { - return false - } - case ChallengeTypeDNS01: - if len(ch.ValidationRecord) > 1 { - return false - } - // TODO(#7140): Add a check for ResolverAddress == "" only after the - // core.proto change has been deployed. - if ch.ValidationRecord[0].Hostname == "" { - return false - } - return true - default: // Unsupported challenge type - return false - } - - return true -} - -// CheckPending ensures that a challenge object is pending and has a token. -// This is used before offering the challenge to the client, and before actually -// validating a challenge. -func (ch Challenge) CheckPending() error { - if ch.Status != StatusPending { - return fmt.Errorf("challenge is not pending") - } - - if !looksLikeAToken(ch.Token) { - return fmt.Errorf("token is missing or malformed") - } - - return nil -} - -// StringID is used to generate a ID for challenges associated with new style authorizations. -// This is necessary as these challenges no longer have a unique non-sequential identifier -// in the new storage scheme. This identifier is generated by constructing a fnv hash over the -// challenge token and type and encoding the first 4 bytes of it using the base64 URL encoding. -func (ch Challenge) StringID() string { - h := fnv.New128a() - h.Write([]byte(ch.Token)) - h.Write([]byte(ch.Type)) - return base64.RawURLEncoding.EncodeToString(h.Sum(nil)[0:4]) -} - -// Authorization represents the authorization of an account key holder -// to act on behalf of a domain. This struct is intended to be used both -// internally and for JSON marshaling on the wire. Any fields that should be -// suppressed on the wire (e.g., ID, regID) must be made empty before marshaling. -type Authorization struct { - // An identifier for this authorization, unique across - // authorizations and certificates within this instance. - ID string `json:"id,omitempty" db:"id"` - - // The identifier for which authorization is being given - Identifier identifier.ACMEIdentifier `json:"identifier,omitempty" db:"identifier"` - - // The registration ID associated with the authorization - RegistrationID int64 `json:"regId,omitempty" db:"registrationID"` - - // The status of the validation of this authorization - Status AcmeStatus `json:"status,omitempty" db:"status"` - - // The date after which this authorization will be no - // longer be considered valid. Note: a certificate may be issued even on the - // last day of an authorization's lifetime. The last day for which someone can - // hold a valid certificate based on an authorization is authorization - // lifetime + certificate lifetime. - Expires *time.Time `json:"expires,omitempty" db:"expires"` - - // An array of challenges objects used to validate the - // applicant's control of the identifier. For authorizations - // in process, these are challenges to be fulfilled; for - // final authorizations, they describe the evidence that - // the server used in support of granting the authorization. - // - // There should only ever be one challenge of each type in this - // slice and the order of these challenges may not be predictable. - Challenges []Challenge `json:"challenges,omitempty" db:"-"` - - // https://datatracker.ietf.org/doc/html/rfc8555#page-29 - // - // wildcard (optional, boolean): This field MUST be present and true - // for authorizations created as a result of a newOrder request - // containing a DNS identifier with a value that was a wildcard - // domain name. For other authorizations, it MUST be absent. - // Wildcard domain names are described in Section 7.1.3. - // - // This is not represented in the database because we calculate it from - // the identifier stored in the database. Unlike the identifier returned - // as part of the authorization, the identifier we store in the database - // can contain an asterisk. - Wildcard bool `json:"wildcard,omitempty" db:"-"` -} - -// FindChallengeByStringID will look for a challenge matching the given ID inside -// this authorization. If found, it will return the index of that challenge within -// the Authorization's Challenges array. Otherwise it will return -1. -func (authz *Authorization) FindChallengeByStringID(id string) int { - for i, c := range authz.Challenges { - if c.StringID() == id { - return i - } - } - return -1 -} - -// SolvedBy will look through the Authorizations challenges, returning the type -// of the *first* challenge it finds with Status: valid, or an error if no -// challenge is valid. -func (authz *Authorization) SolvedBy() (AcmeChallenge, error) { - if len(authz.Challenges) == 0 { - return "", fmt.Errorf("Authorization has no challenges") - } - for _, chal := range authz.Challenges { - if chal.Status == StatusValid { - return chal.Type, nil - } - } - return "", fmt.Errorf("Authorization not solved by any challenge") -} - -// JSONBuffer fields get encoded and decoded JOSE-style, in base64url encoding -// with stripped padding. -type JSONBuffer []byte - -// MarshalJSON encodes a JSONBuffer for transmission. -func (jb JSONBuffer) MarshalJSON() (result []byte, err error) { - return json.Marshal(base64.RawURLEncoding.EncodeToString(jb)) -} - -// UnmarshalJSON decodes a JSONBuffer to an object. -func (jb *JSONBuffer) UnmarshalJSON(data []byte) (err error) { - var str string - err = json.Unmarshal(data, &str) - if err != nil { - return err - } - *jb, err = base64.RawURLEncoding.DecodeString(strings.TrimRight(str, "=")) - return -} - -// Certificate objects are entirely internal to the server. The only -// thing exposed on the wire is the certificate itself. -type Certificate struct { - ID int64 `db:"id"` - RegistrationID int64 `db:"registrationID"` - - Serial string `db:"serial"` - Digest string `db:"digest"` - DER []byte `db:"der"` - Issued time.Time `db:"issued"` - Expires time.Time `db:"expires"` -} - -// CertificateStatus structs are internal to the server. They represent the -// latest data about the status of the certificate, required for generating new -// OCSP responses and determining if a certificate has been revoked. -type CertificateStatus struct { - ID int64 `db:"id"` - - Serial string `db:"serial"` - - // status: 'good' or 'revoked'. Note that good, expired certificates remain - // with status 'good' but don't necessarily get fresh OCSP responses. - Status OCSPStatus `db:"status"` - - // ocspLastUpdated: The date and time of the last time we generated an OCSP - // response. If we have never generated one, this has the zero value of - // time.Time, i.e. Jan 1 1970. - OCSPLastUpdated time.Time `db:"ocspLastUpdated"` - - // revokedDate: If status is 'revoked', this is the date and time it was - // revoked. Otherwise it has the zero value of time.Time, i.e. Jan 1 1970. - RevokedDate time.Time `db:"revokedDate"` - - // revokedReason: If status is 'revoked', this is the reason code for the - // revocation. Otherwise it is zero (which happens to be the reason - // code for 'unspecified'). - RevokedReason revocation.Reason `db:"revokedReason"` - - LastExpirationNagSent time.Time `db:"lastExpirationNagSent"` - - // NotAfter and IsExpired are convenience columns which allow expensive - // queries to quickly filter out certificates that we don't need to care about - // anymore. These are particularly useful for the expiration mailer and CRL - // updater. See https://github.com/letsencrypt/boulder/issues/1864. - NotAfter time.Time `db:"notAfter"` - IsExpired bool `db:"isExpired"` - - // Note: this is not an issuance.IssuerNameID because that would create an - // import cycle between core and issuance. - // Note2: This field used to be called `issuerID`. We keep the old name in - // the DB, but update the Go field name to be clear which type of ID this - // is. - IssuerNameID int64 `db:"issuerID"` -} - -// FQDNSet contains the SHA256 hash of the lowercased, comma joined dNSNames -// contained in a certificate. -type FQDNSet struct { - ID int64 - SetHash []byte - Serial string - Issued time.Time - Expires time.Time -} - -// SCTDERs is a convenience type -type SCTDERs [][]byte - -// CertDER is a convenience type that helps differentiate what the -// underlying byte slice contains -type CertDER []byte - -// SuggestedWindow is a type exposed inside the RenewalInfo resource. -type SuggestedWindow struct { - Start time.Time `json:"start"` - End time.Time `json:"end"` -} - -// IsWithin returns true if the given time is within the suggested window, -// inclusive of the start time and exclusive of the end time. -func (window SuggestedWindow) IsWithin(now time.Time) bool { - return !now.Before(window.Start) && now.Before(window.End) -} - -// RenewalInfo is a type which is exposed to clients which query the renewalInfo -// endpoint specified in draft-aaron-ari. -type RenewalInfo struct { - SuggestedWindow SuggestedWindow `json:"suggestedWindow"` -} - -// RenewalInfoSimple constructs a `RenewalInfo` object and suggested window -// using a very simple renewal calculation: calculate a point 2/3rds of the way -// through the validity period, then give a 2-day window around that. Both the -// `issued` and `expires` timestamps are expected to be UTC. -func RenewalInfoSimple(issued time.Time, expires time.Time) RenewalInfo { - validity := expires.Add(time.Second).Sub(issued) - renewalOffset := validity / time.Duration(3) - idealRenewal := expires.Add(-renewalOffset) - return RenewalInfo{ - SuggestedWindow: SuggestedWindow{ - Start: idealRenewal.Add(-24 * time.Hour), - End: idealRenewal.Add(24 * time.Hour), - }, - } -} - -// RenewalInfoImmediate constructs a `RenewalInfo` object with a suggested -// window in the past. Per the draft-ietf-acme-ari-01 spec, clients should -// attempt to renew immediately if the suggested window is in the past. The -// passed `now` is assumed to be a timestamp representing the current moment in -// time. -func RenewalInfoImmediate(now time.Time) RenewalInfo { - oneHourAgo := now.Add(-1 * time.Hour) - return RenewalInfo{ - SuggestedWindow: SuggestedWindow{ - Start: oneHourAgo, - End: oneHourAgo.Add(time.Minute * 30), - }, - } -} diff --git a/vendor/github.com/letsencrypt/boulder/core/util.go b/vendor/github.com/letsencrypt/boulder/core/util.go deleted file mode 100644 index 641521f1699..00000000000 --- a/vendor/github.com/letsencrypt/boulder/core/util.go +++ /dev/null @@ -1,383 +0,0 @@ -package core - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/hex" - "encoding/pem" - "errors" - "expvar" - "fmt" - "io" - "math/big" - mrand "math/rand" - "os" - "path" - "reflect" - "regexp" - "sort" - "strings" - "time" - "unicode" - - "github.com/go-jose/go-jose/v4" - "google.golang.org/protobuf/types/known/durationpb" - "google.golang.org/protobuf/types/known/timestamppb" -) - -const Unspecified = "Unspecified" - -// Package Variables Variables - -// BuildID is set by the compiler (using -ldflags "-X core.BuildID $(git rev-parse --short HEAD)") -// and is used by GetBuildID -var BuildID string - -// BuildHost is set by the compiler and is used by GetBuildHost -var BuildHost string - -// BuildTime is set by the compiler and is used by GetBuildTime -var BuildTime string - -func init() { - expvar.NewString("BuildID").Set(BuildID) - expvar.NewString("BuildTime").Set(BuildTime) -} - -// Random stuff - -type randSource interface { - Read(p []byte) (n int, err error) -} - -// RandReader is used so that it can be replaced in tests that require -// deterministic output -var RandReader randSource = rand.Reader - -// RandomString returns a randomly generated string of the requested length. -func RandomString(byteLength int) string { - b := make([]byte, byteLength) - _, err := io.ReadFull(RandReader, b) - if err != nil { - panic(fmt.Sprintf("Error reading random bytes: %s", err)) - } - return base64.RawURLEncoding.EncodeToString(b) -} - -// NewToken produces a random string for Challenges, etc. -func NewToken() string { - return RandomString(32) -} - -var tokenFormat = regexp.MustCompile(`^[\w-]{43}$`) - -// looksLikeAToken checks whether a string represents a 32-octet value in -// the URL-safe base64 alphabet. -func looksLikeAToken(token string) bool { - return tokenFormat.MatchString(token) -} - -// Fingerprints - -// Fingerprint256 produces an unpadded, URL-safe Base64-encoded SHA256 digest -// of the data. -func Fingerprint256(data []byte) string { - d := sha256.New() - _, _ = d.Write(data) // Never returns an error - return base64.RawURLEncoding.EncodeToString(d.Sum(nil)) -} - -type Sha256Digest [sha256.Size]byte - -// KeyDigest produces the SHA256 digest of a provided public key. -func KeyDigest(key crypto.PublicKey) (Sha256Digest, error) { - switch t := key.(type) { - case *jose.JSONWebKey: - if t == nil { - return Sha256Digest{}, errors.New("cannot compute digest of nil key") - } - return KeyDigest(t.Key) - case jose.JSONWebKey: - return KeyDigest(t.Key) - default: - keyDER, err := x509.MarshalPKIXPublicKey(key) - if err != nil { - return Sha256Digest{}, err - } - return sha256.Sum256(keyDER), nil - } -} - -// KeyDigestB64 produces a padded, standard Base64-encoded SHA256 digest of a -// provided public key. -func KeyDigestB64(key crypto.PublicKey) (string, error) { - digest, err := KeyDigest(key) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(digest[:]), nil -} - -// KeyDigestEquals determines whether two public keys have the same digest. -func KeyDigestEquals(j, k crypto.PublicKey) bool { - digestJ, errJ := KeyDigestB64(j) - digestK, errK := KeyDigestB64(k) - // Keys that don't have a valid digest (due to marshalling problems) - // are never equal. So, e.g. nil keys are not equal. - if errJ != nil || errK != nil { - return false - } - return digestJ == digestK -} - -// PublicKeysEqual determines whether two public keys are identical. -func PublicKeysEqual(a, b crypto.PublicKey) (bool, error) { - switch ak := a.(type) { - case *rsa.PublicKey: - return ak.Equal(b), nil - case *ecdsa.PublicKey: - return ak.Equal(b), nil - default: - return false, fmt.Errorf("unsupported public key type %T", ak) - } -} - -// SerialToString converts a certificate serial number (big.Int) to a String -// consistently. -func SerialToString(serial *big.Int) string { - return fmt.Sprintf("%036x", serial) -} - -// StringToSerial converts a string into a certificate serial number (big.Int) -// consistently. -func StringToSerial(serial string) (*big.Int, error) { - var serialNum big.Int - if !ValidSerial(serial) { - return &serialNum, fmt.Errorf("invalid serial number %q", serial) - } - _, err := fmt.Sscanf(serial, "%036x", &serialNum) - return &serialNum, err -} - -// ValidSerial tests whether the input string represents a syntactically -// valid serial number, i.e., that it is a valid hex string between 32 -// and 36 characters long. -func ValidSerial(serial string) bool { - // Originally, serial numbers were 32 hex characters long. We later increased - // them to 36, but we allow the shorter ones because they exist in some - // production databases. - if len(serial) != 32 && len(serial) != 36 { - return false - } - _, err := hex.DecodeString(serial) - return err == nil -} - -// GetBuildID identifies what build is running. -func GetBuildID() (retID string) { - retID = BuildID - if retID == "" { - retID = Unspecified - } - return -} - -// GetBuildTime identifies when this build was made -func GetBuildTime() (retID string) { - retID = BuildTime - if retID == "" { - retID = Unspecified - } - return -} - -// GetBuildHost identifies the building host -func GetBuildHost() (retID string) { - retID = BuildHost - if retID == "" { - retID = Unspecified - } - return -} - -// IsAnyNilOrZero returns whether any of the supplied values are nil, or (if not) -// if any of them is its type's zero-value. This is useful for validating that -// all required fields on a proto message are present. -func IsAnyNilOrZero(vals ...interface{}) bool { - for _, val := range vals { - switch v := val.(type) { - case nil: - return true - case bool: - if !v { - return true - } - case string: - if v == "" { - return true - } - case []string: - if len(v) == 0 { - return true - } - case byte: - // Byte is an alias for uint8 and will cover that case. - if v == 0 { - return true - } - case []byte: - if len(v) == 0 { - return true - } - case int: - if v == 0 { - return true - } - case int8: - if v == 0 { - return true - } - case int16: - if v == 0 { - return true - } - case int32: - if v == 0 { - return true - } - case int64: - if v == 0 { - return true - } - case uint: - if v == 0 { - return true - } - case uint16: - if v == 0 { - return true - } - case uint32: - if v == 0 { - return true - } - case uint64: - if v == 0 { - return true - } - case float32: - if v == 0 { - return true - } - case float64: - if v == 0 { - return true - } - case time.Time: - if v.IsZero() { - return true - } - case *timestamppb.Timestamp: - if v == nil || v.AsTime().IsZero() { - return true - } - case *durationpb.Duration: - if v == nil || v.AsDuration() == time.Duration(0) { - return true - } - default: - if reflect.ValueOf(v).IsZero() { - return true - } - } - } - return false -} - -// UniqueLowerNames returns the set of all unique names in the input after all -// of them are lowercased. The returned names will be in their lowercased form -// and sorted alphabetically. -func UniqueLowerNames(names []string) (unique []string) { - nameMap := make(map[string]int, len(names)) - for _, name := range names { - nameMap[strings.ToLower(name)] = 1 - } - - unique = make([]string, 0, len(nameMap)) - for name := range nameMap { - unique = append(unique, name) - } - sort.Strings(unique) - return -} - -// HashNames returns a hash of the names requested. This is intended for use -// when interacting with the orderFqdnSets table and rate limiting. -func HashNames(names []string) []byte { - names = UniqueLowerNames(names) - hash := sha256.Sum256([]byte(strings.Join(names, ","))) - return hash[:] -} - -// LoadCert loads a PEM certificate specified by filename or returns an error -func LoadCert(filename string) (*x509.Certificate, error) { - certPEM, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - block, _ := pem.Decode(certPEM) - if block == nil { - return nil, fmt.Errorf("no data in cert PEM file %q", filename) - } - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, err - } - return cert, nil -} - -// retryJitter is used to prevent bunched retried queries from falling into lockstep -const retryJitter = 0.2 - -// RetryBackoff calculates a backoff time based on number of retries, will always -// add jitter so requests that start in unison won't fall into lockstep. Because of -// this the returned duration can always be larger than the maximum by a factor of -// retryJitter. Adapted from -// https://github.com/grpc/grpc-go/blob/v1.11.3/backoff.go#L77-L96 -func RetryBackoff(retries int, base, max time.Duration, factor float64) time.Duration { - if retries == 0 { - return 0 - } - backoff, fMax := float64(base), float64(max) - for backoff < fMax && retries > 1 { - backoff *= factor - retries-- - } - if backoff > fMax { - backoff = fMax - } - // Randomize backoff delays so that if a cluster of requests start at - // the same time, they won't operate in lockstep. - backoff *= (1 - retryJitter) + 2*retryJitter*mrand.Float64() - return time.Duration(backoff) -} - -// IsASCII determines if every character in a string is encoded in -// the ASCII character set. -func IsASCII(str string) bool { - for _, r := range str { - if r > unicode.MaxASCII { - return false - } - } - return true -} - -func Command() string { - return path.Base(os.Args[0]) -} diff --git a/vendor/github.com/letsencrypt/boulder/goodkey/blocked.go b/vendor/github.com/letsencrypt/boulder/goodkey/blocked.go deleted file mode 100644 index 198c09db4ed..00000000000 --- a/vendor/github.com/letsencrypt/boulder/goodkey/blocked.go +++ /dev/null @@ -1,95 +0,0 @@ -package goodkey - -import ( - "crypto" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "errors" - "os" - - "github.com/letsencrypt/boulder/core" - "github.com/letsencrypt/boulder/strictyaml" -) - -// blockedKeys is a type for maintaining a map of SHA256 hashes -// of SubjectPublicKeyInfo's that should be considered blocked. -// blockedKeys are created by using loadBlockedKeysList. -type blockedKeys map[core.Sha256Digest]bool - -var ErrWrongDecodedSize = errors.New("not enough bytes decoded for sha256 hash") - -// blocked checks if the given public key is considered administratively -// blocked based on a SHA256 hash of the SubjectPublicKeyInfo. -// Important: blocked should not be called except on a blockedKeys instance -// returned from loadBlockedKeysList. -// function should not be used until after `loadBlockedKeysList` has returned. -func (b blockedKeys) blocked(key crypto.PublicKey) (bool, error) { - hash, err := core.KeyDigest(key) - if err != nil { - // the bool result should be ignored when err is != nil but to be on the - // paranoid side return true anyway so that a key we can't compute the - // digest for will always be blocked even if a caller foolishly discards the - // err result. - return true, err - } - return b[hash], nil -} - -// loadBlockedKeysList creates a blockedKeys object that can be used to check if -// a key is blocked. It creates a lookup map from a list of -// SHA256 hashes of SubjectPublicKeyInfo's in the input YAML file -// with the expected format: -// -// blocked: -// - cuwGhNNI6nfob5aqY90e7BleU6l7rfxku4X3UTJ3Z7M= -// -// - Qebc1V3SkX3izkYRGNJilm9Bcuvf0oox4U2Rn+b4JOE= -// -// If no hashes are found in the input YAML an error is returned. -func loadBlockedKeysList(filename string) (*blockedKeys, error) { - yamlBytes, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - - var list struct { - BlockedHashes []string `yaml:"blocked"` - BlockedHashesHex []string `yaml:"blockedHashesHex"` - } - err = strictyaml.Unmarshal(yamlBytes, &list) - if err != nil { - return nil, err - } - - if len(list.BlockedHashes) == 0 && len(list.BlockedHashesHex) == 0 { - return nil, errors.New("no blocked hashes in YAML") - } - - blockedKeys := make(blockedKeys, len(list.BlockedHashes)+len(list.BlockedHashesHex)) - for _, b64Hash := range list.BlockedHashes { - decoded, err := base64.StdEncoding.DecodeString(b64Hash) - if err != nil { - return nil, err - } - if len(decoded) != sha256.Size { - return nil, ErrWrongDecodedSize - } - var sha256Digest core.Sha256Digest - copy(sha256Digest[:], decoded[0:sha256.Size]) - blockedKeys[sha256Digest] = true - } - for _, hexHash := range list.BlockedHashesHex { - decoded, err := hex.DecodeString(hexHash) - if err != nil { - return nil, err - } - if len(decoded) != sha256.Size { - return nil, ErrWrongDecodedSize - } - var sha256Digest core.Sha256Digest - copy(sha256Digest[:], decoded[0:sha256.Size]) - blockedKeys[sha256Digest] = true - } - return &blockedKeys, nil -} diff --git a/vendor/github.com/letsencrypt/boulder/goodkey/good_key.go b/vendor/github.com/letsencrypt/boulder/goodkey/good_key.go deleted file mode 100644 index 04a075d35bb..00000000000 --- a/vendor/github.com/letsencrypt/boulder/goodkey/good_key.go +++ /dev/null @@ -1,460 +0,0 @@ -package goodkey - -import ( - "context" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rsa" - "errors" - "fmt" - "math/big" - "sync" - - "github.com/letsencrypt/boulder/core" - - "github.com/titanous/rocacheck" -) - -// To generate, run: primes 2 752 | tr '\n' , -var smallPrimeInts = []int64{ - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, - 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, - 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, - 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, - 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, - 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, - 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, - 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, - 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, - 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, - 719, 727, 733, 739, 743, 751, -} - -// singleton defines the object of a Singleton pattern -var ( - smallPrimesSingleton sync.Once - smallPrimesProduct *big.Int -) - -type Config struct { - // AllowedKeys enables or disables specific key algorithms and sizes. If - // nil, defaults to just those keys allowed by the Let's Encrypt CPS. - AllowedKeys *AllowedKeys - // WeakKeyFile is the path to a JSON file containing truncated modulus hashes - // of known weak RSA keys. If this config value is empty, then RSA modulus - // hash checking will be disabled. - WeakKeyFile string - // BlockedKeyFile is the path to a YAML file containing base64-encoded SHA256 - // hashes of PKIX Subject Public Keys that should be blocked. If this config - // value is empty, then blocked key checking will be disabled. - BlockedKeyFile string - // FermatRounds is an integer number of rounds of Fermat's factorization - // method that should be performed to attempt to detect keys whose modulus can - // be trivially factored because the two factors are very close to each other. - // If this config value is empty (0), no factorization will be attempted. - FermatRounds int -} - -// AllowedKeys is a map of six specific key algorithm and size combinations to -// booleans indicating whether keys of that type are considered good. -type AllowedKeys struct { - // Baseline Requirements, Section 6.1.5 requires key size >= 2048 and a multiple - // of 8 bits: https://github.com/cabforum/servercert/blob/main/docs/BR.md#615-key-sizes - // Baseline Requirements, Section 6.1.1.3 requires that we reject any keys which - // have a known method to easily compute their private key, such as Debian Weak - // Keys. Our enforcement mechanism relies on enumerating all Debian Weak Keys at - // common key sizes, so we restrict all issuance to those common key sizes. - RSA2048 bool - RSA3072 bool - RSA4096 bool - // Baseline Requirements, Section 6.1.5 requires that ECDSA keys be valid - // points on the NIST P-256, P-384, or P-521 elliptic curves. - ECDSAP256 bool - ECDSAP384 bool - ECDSAP521 bool -} - -// LetsEncryptCPS encodes the five key algorithms and sizes allowed by the Let's -// Encrypt CPS CV-SSL Subscriber Certificate Profile: RSA 2048, RSA 3076, RSA -// 4096, ECDSA 256 and ECDSA P384. -// https://github.com/letsencrypt/cp-cps/blob/main/CP-CPS.md#dv-ssl-subscriber-certificate -// If this is ever changed, the CP/CPS MUST be changed first. -func LetsEncryptCPS() AllowedKeys { - return AllowedKeys{ - RSA2048: true, - RSA3072: true, - RSA4096: true, - ECDSAP256: true, - ECDSAP384: true, - } -} - -// ErrBadKey represents an error with a key. It is distinct from the various -// ways in which an ACME request can have an erroneous key (BadPublicKeyError, -// BadCSRError) because this library is used to check both JWS signing keys and -// keys in CSRs. -var ErrBadKey = errors.New("") - -func badKey(msg string, args ...interface{}) error { - return fmt.Errorf("%w%s", ErrBadKey, fmt.Errorf(msg, args...)) -} - -// BlockedKeyCheckFunc is used to pass in the sa.BlockedKey functionality to KeyPolicy, -// rather than storing a full sa.SQLStorageAuthority. This allows external -// users who don’t want to import all of boulder/sa, and makes testing -// significantly simpler. -// On success, the function returns a boolean which is true if the key is blocked. -type BlockedKeyCheckFunc func(ctx context.Context, keyHash []byte) (bool, error) - -// KeyPolicy determines which types of key may be used with various boulder -// operations. -type KeyPolicy struct { - allowedKeys AllowedKeys - weakRSAList *WeakRSAKeys - blockedList *blockedKeys - fermatRounds int - blockedCheck BlockedKeyCheckFunc -} - -// NewPolicy returns a key policy based on the given configuration, with sane -// defaults. If the config's AllowedKeys is nil, the LetsEncryptCPS AllowedKeys -// is used. If the config's WeakKeyFile or BlockedKeyFile paths are empty, those -// checks are disabled. If the config's FermatRounds is 0, Fermat Factorization -// is disabled. -func NewPolicy(config *Config, bkc BlockedKeyCheckFunc) (KeyPolicy, error) { - if config == nil { - config = &Config{} - } - kp := KeyPolicy{ - blockedCheck: bkc, - } - if config.AllowedKeys == nil { - kp.allowedKeys = LetsEncryptCPS() - } else { - kp.allowedKeys = *config.AllowedKeys - } - if config.WeakKeyFile != "" { - keyList, err := LoadWeakRSASuffixes(config.WeakKeyFile) - if err != nil { - return KeyPolicy{}, err - } - kp.weakRSAList = keyList - } - if config.BlockedKeyFile != "" { - blocked, err := loadBlockedKeysList(config.BlockedKeyFile) - if err != nil { - return KeyPolicy{}, err - } - kp.blockedList = blocked - } - if config.FermatRounds < 0 { - return KeyPolicy{}, fmt.Errorf("Fermat factorization rounds cannot be negative: %d", config.FermatRounds) - } - kp.fermatRounds = config.FermatRounds - return kp, nil -} - -// GoodKey returns true if the key is acceptable for both TLS use and account -// key use (our requirements are the same for either one), according to basic -// strength and algorithm checking. GoodKey only supports pointers: *rsa.PublicKey -// and *ecdsa.PublicKey. It will reject non-pointer types. -// TODO: Support JSONWebKeys once go-jose migration is done. -func (policy *KeyPolicy) GoodKey(ctx context.Context, key crypto.PublicKey) error { - // Early rejection of unacceptable key types to guard subsequent checks. - switch t := key.(type) { - case *rsa.PublicKey, *ecdsa.PublicKey: - break - default: - return badKey("unsupported key type %T", t) - } - // If there is a blocked list configured then check if the public key is one - // that has been administratively blocked. - if policy.blockedList != nil { - if blocked, err := policy.blockedList.blocked(key); err != nil { - return fmt.Errorf("error checking blocklist for key: %v", key) - } else if blocked { - return badKey("public key is forbidden") - } - } - if policy.blockedCheck != nil { - digest, err := core.KeyDigest(key) - if err != nil { - return badKey("%w", err) - } - exists, err := policy.blockedCheck(ctx, digest[:]) - if err != nil { - return err - } else if exists { - return badKey("public key is forbidden") - } - } - switch t := key.(type) { - case *rsa.PublicKey: - return policy.goodKeyRSA(t) - case *ecdsa.PublicKey: - return policy.goodKeyECDSA(t) - default: - return badKey("unsupported key type %T", key) - } -} - -// GoodKeyECDSA determines if an ECDSA pubkey meets our requirements -func (policy *KeyPolicy) goodKeyECDSA(key *ecdsa.PublicKey) (err error) { - // Check the curve. - // - // The validity of the curve is an assumption for all following tests. - err = policy.goodCurve(key.Curve) - if err != nil { - return err - } - - // Key validation routine adapted from NIST SP800-56A § 5.6.2.3.2. - // - // - // Assuming a prime field since a) we are only allowing such curves and b) - // crypto/elliptic only supports prime curves. Where this assumption - // simplifies the code below, it is explicitly stated and explained. If ever - // adapting this code to support non-prime curves, refer to NIST SP800-56A § - // 5.6.2.3.2 and adapt this code appropriately. - params := key.Params() - - // SP800-56A § 5.6.2.3.2 Step 1. - // Partial check of the public key for an invalid range in the EC group: - // Verify that key is not the point at infinity O. - // This code assumes that the point at infinity is (0,0), which is the - // case for all supported curves. - if isPointAtInfinityNISTP(key.X, key.Y) { - return badKey("key x, y must not be the point at infinity") - } - - // SP800-56A § 5.6.2.3.2 Step 2. - // "Verify that x_Q and y_Q are integers in the interval [0,p-1] in the - // case that q is an odd prime p, or that x_Q and y_Q are bit strings - // of length m bits in the case that q = 2**m." - // - // Prove prime field: ASSUMED. - // Prove q != 2: ASSUMED. (Curve parameter. No supported curve has q == 2.) - // Prime field && q != 2 => q is an odd prime p - // Therefore "verify that x, y are in [0, p-1]" satisfies step 2. - // - // Therefore verify that both x and y of the public key point have the unique - // correct representation of an element in the underlying field by verifying - // that x and y are integers in [0, p-1]. - if key.X.Sign() < 0 || key.Y.Sign() < 0 { - return badKey("key x, y must not be negative") - } - - if key.X.Cmp(params.P) >= 0 || key.Y.Cmp(params.P) >= 0 { - return badKey("key x, y must not exceed P-1") - } - - // SP800-56A § 5.6.2.3.2 Step 3. - // "If q is an odd prime p, verify that (y_Q)**2 === (x_Q)***3 + a*x_Q + b (mod p). - // If q = 2**m, verify that (y_Q)**2 + (x_Q)*(y_Q) == (x_Q)**3 + a*(x_Q)*2 + b in - // the finite field of size 2**m. - // (Ensures that the public key is on the correct elliptic curve.)" - // - // q is an odd prime p: proven/assumed above. - // a = -3 for all supported curves. - // - // Therefore step 3 is satisfied simply by showing that - // y**2 === x**3 - 3*x + B (mod P). - // - // This proves that the public key is on the correct elliptic curve. - // But in practice, this test is provided by crypto/elliptic, so use that. - if !key.Curve.IsOnCurve(key.X, key.Y) { - return badKey("key point is not on the curve") - } - - // SP800-56A § 5.6.2.3.2 Step 4. - // "Verify that n*Q == Ø. - // (Ensures that the public key has the correct order. Along with check 1, - // ensures that the public key is in the correct range in the correct EC - // subgroup, that is, it is in the correct EC subgroup and is not the - // identity element.)" - // - // Ensure that public key has the correct order: - // verify that n*Q = Ø. - // - // n*Q = Ø iff n*Q is the point at infinity (see step 1). - ox, oy := key.Curve.ScalarMult(key.X, key.Y, params.N.Bytes()) - if !isPointAtInfinityNISTP(ox, oy) { - return badKey("public key does not have correct order") - } - - // End of SP800-56A § 5.6.2.3.2 Public Key Validation Routine. - // Key is valid. - return nil -} - -// Returns true iff the point (x,y) on NIST P-256, NIST P-384 or NIST P-521 is -// the point at infinity. These curves all have the same point at infinity -// (0,0). This function must ONLY be used on points on curves verified to have -// (0,0) as their point at infinity. -func isPointAtInfinityNISTP(x, y *big.Int) bool { - return x.Sign() == 0 && y.Sign() == 0 -} - -// GoodCurve determines if an elliptic curve meets our requirements. -func (policy *KeyPolicy) goodCurve(c elliptic.Curve) (err error) { - // Simply use a whitelist for now. - params := c.Params() - switch { - case policy.allowedKeys.ECDSAP256 && params == elliptic.P256().Params(): - return nil - case policy.allowedKeys.ECDSAP384 && params == elliptic.P384().Params(): - return nil - case policy.allowedKeys.ECDSAP521 && params == elliptic.P521().Params(): - return nil - default: - return badKey("ECDSA curve %v not allowed", params.Name) - } -} - -// GoodKeyRSA determines if a RSA pubkey meets our requirements -func (policy *KeyPolicy) goodKeyRSA(key *rsa.PublicKey) error { - modulus := key.N - - err := policy.goodRSABitLen(key) - if err != nil { - return err - } - - if policy.weakRSAList != nil && policy.weakRSAList.Known(key) { - return badKey("key is on a known weak RSA key list") - } - - // Rather than support arbitrary exponents, which significantly increases - // the size of the key space we allow, we restrict E to the defacto standard - // RSA exponent 65537. There is no specific standards document that specifies - // 65537 as the 'best' exponent, but ITU X.509 Annex C suggests there are - // notable merits for using it if using a fixed exponent. - // - // The CABF Baseline Requirements state: - // The CA SHALL confirm that the value of the public exponent is an - // odd number equal to 3 or more. Additionally, the public exponent - // SHOULD be in the range between 2^16 + 1 and 2^256-1. - // - // By only allowing one exponent, which fits these constraints, we satisfy - // these requirements. - if key.E != 65537 { - return badKey("key exponent must be 65537") - } - - // The modulus SHOULD also have the following characteristics: an odd - // number, not the power of a prime, and have no factors smaller than 752. - // TODO: We don't yet check for "power of a prime." - if checkSmallPrimes(modulus) { - return badKey("key divisible by small prime") - } - // Check for weak keys generated by Infineon hardware - // (see https://crocs.fi.muni.cz/public/papers/rsa_ccs17) - if rocacheck.IsWeak(key) { - return badKey("key generated by vulnerable Infineon-based hardware") - } - // Check if the key can be easily factored via Fermat's factorization method. - if policy.fermatRounds > 0 { - err := checkPrimeFactorsTooClose(modulus, policy.fermatRounds) - if err != nil { - return badKey("key generated with factors too close together: %w", err) - } - } - - return nil -} - -func (policy *KeyPolicy) goodRSABitLen(key *rsa.PublicKey) error { - // See comment on AllowedKeys above. - modulusBitLen := key.N.BitLen() - switch { - case modulusBitLen == 2048 && policy.allowedKeys.RSA2048: - return nil - case modulusBitLen == 3072 && policy.allowedKeys.RSA3072: - return nil - case modulusBitLen == 4096 && policy.allowedKeys.RSA4096: - return nil - default: - return badKey("key size not supported: %d", modulusBitLen) - } -} - -// Returns true iff integer i is divisible by any of the primes in smallPrimes. -// -// Short circuits; execution time is dependent on i. Do not use this on secret -// values. -// -// Rather than checking each prime individually (invoking Mod on each), -// multiply the primes together and let GCD do our work for us: if the -// GCD between and is not one, we know we have -// a bad key. This is substantially faster than checking each prime -// individually. -func checkSmallPrimes(i *big.Int) bool { - smallPrimesSingleton.Do(func() { - smallPrimesProduct = big.NewInt(1) - for _, prime := range smallPrimeInts { - smallPrimesProduct.Mul(smallPrimesProduct, big.NewInt(prime)) - } - }) - - // When the GCD is 1, i and smallPrimesProduct are coprime, meaning they - // share no common factors. When the GCD is not one, it is the product of - // all common factors, meaning we've identified at least one small prime - // which invalidates i as a valid key. - - var result big.Int - result.GCD(nil, nil, i, smallPrimesProduct) - return result.Cmp(big.NewInt(1)) != 0 -} - -// Returns an error if the modulus n is able to be factored into primes p and q -// via Fermat's factorization method. This method relies on the two primes being -// very close together, which means that they were almost certainly not picked -// independently from a uniform random distribution. Basically, if we can factor -// the key this easily, so can anyone else. -func checkPrimeFactorsTooClose(n *big.Int, rounds int) error { - // Pre-allocate some big numbers that we'll use a lot down below. - one := big.NewInt(1) - bb := new(big.Int) - - // Any odd integer is equal to a difference of squares of integers: - // n = a^2 - b^2 = (a + b)(a - b) - // Any RSA public key modulus is equal to a product of two primes: - // n = pq - // Here we try to find values for a and b, since doing so also gives us the - // prime factors p = (a + b) and q = (a - b). - - // We start with a close to the square root of the modulus n, to start with - // two candidate prime factors that are as close together as possible and - // work our way out from there. Specifically, we set a = ceil(sqrt(n)), the - // first integer greater than the square root of n. Unfortunately, big.Int's - // built-in square root function takes the floor, so we have to add one to get - // the ceil. - a := new(big.Int) - a.Sqrt(n).Add(a, one) - - // We calculate b2 to see if it is a perfect square (i.e. b^2), and therefore - // b is an integer. Specifically, b2 = a^2 - n. - b2 := new(big.Int) - b2.Mul(a, a).Sub(b2, n) - - for range rounds { - // To see if b2 is a perfect square, we take its square root, square that, - // and check to see if we got the same result back. - bb.Sqrt(b2).Mul(bb, bb) - if b2.Cmp(bb) == 0 { - // b2 is a perfect square, so we've found integer values of a and b, - // and can easily compute p and q as their sum and difference. - bb.Sqrt(bb) - p := new(big.Int).Add(a, bb) - q := new(big.Int).Sub(a, bb) - return fmt.Errorf("public modulus n = pq factored into p: %s; q: %s", p, q) - } - - // Set up the next iteration by incrementing a by one and recalculating b2. - a.Add(a, one) - b2.Mul(a, a).Sub(b2, n) - } - return nil -} diff --git a/vendor/github.com/letsencrypt/boulder/goodkey/weak.go b/vendor/github.com/letsencrypt/boulder/goodkey/weak.go deleted file mode 100644 index dd7afd5e4c7..00000000000 --- a/vendor/github.com/letsencrypt/boulder/goodkey/weak.go +++ /dev/null @@ -1,66 +0,0 @@ -package goodkey - -// This file defines a basic method for testing if a given RSA public key is on one of -// the Debian weak key lists and is therefore considered compromised. Instead of -// directly loading the hash suffixes from the individual lists we flatten them all -// into a single JSON list using cmd/weak-key-flatten for ease of use. - -import ( - "crypto/rsa" - "crypto/sha1" - "encoding/hex" - "encoding/json" - "fmt" - "os" -) - -type truncatedHash [10]byte - -type WeakRSAKeys struct { - suffixes map[truncatedHash]struct{} -} - -func LoadWeakRSASuffixes(path string) (*WeakRSAKeys, error) { - f, err := os.ReadFile(path) - if err != nil { - return nil, err - } - - var suffixList []string - err = json.Unmarshal(f, &suffixList) - if err != nil { - return nil, err - } - - wk := &WeakRSAKeys{suffixes: make(map[truncatedHash]struct{})} - for _, suffix := range suffixList { - err := wk.addSuffix(suffix) - if err != nil { - return nil, err - } - } - return wk, nil -} - -func (wk *WeakRSAKeys) addSuffix(str string) error { - var suffix truncatedHash - decoded, err := hex.DecodeString(str) - if err != nil { - return err - } - if len(decoded) != 10 { - return fmt.Errorf("unexpected suffix length of %d", len(decoded)) - } - copy(suffix[:], decoded) - wk.suffixes[suffix] = struct{}{} - return nil -} - -func (wk *WeakRSAKeys) Known(key *rsa.PublicKey) bool { - // Hash input is in the format "Modulus={upper-case hex of modulus}\n" - hash := sha1.Sum([]byte(fmt.Sprintf("Modulus=%X\n", key.N.Bytes()))) - var suffix truncatedHash - copy(suffix[:], hash[10:]) - _, present := wk.suffixes[suffix] - return present -} diff --git a/vendor/github.com/letsencrypt/boulder/identifier/identifier.go b/vendor/github.com/letsencrypt/boulder/identifier/identifier.go deleted file mode 100644 index cbf228f869f..00000000000 --- a/vendor/github.com/letsencrypt/boulder/identifier/identifier.go +++ /dev/null @@ -1,32 +0,0 @@ -// The identifier package defines types for RFC 8555 ACME identifiers. -package identifier - -// IdentifierType is a named string type for registered ACME identifier types. -// See https://tools.ietf.org/html/rfc8555#section-9.7.7 -type IdentifierType string - -const ( - // DNS is specified in RFC 8555 for DNS type identifiers. - DNS = IdentifierType("dns") -) - -// ACMEIdentifier is a struct encoding an identifier that can be validated. The -// protocol allows for different types of identifier to be supported (DNS -// names, IP addresses, etc.), but currently we only support RFC 8555 DNS type -// identifiers for domain names. -type ACMEIdentifier struct { - // Type is the registered IdentifierType of the identifier. - Type IdentifierType `json:"type"` - // Value is the value of the identifier. For a DNS type identifier it is - // a domain name. - Value string `json:"value"` -} - -// DNSIdentifier is a convenience function for creating an ACMEIdentifier with -// Type DNS for a given domain name. -func DNSIdentifier(domain string) ACMEIdentifier { - return ACMEIdentifier{ - Type: DNS, - Value: domain, - } -} diff --git a/vendor/github.com/letsencrypt/boulder/probs/probs.go b/vendor/github.com/letsencrypt/boulder/probs/probs.go deleted file mode 100644 index ec6c272ae52..00000000000 --- a/vendor/github.com/letsencrypt/boulder/probs/probs.go +++ /dev/null @@ -1,343 +0,0 @@ -package probs - -import ( - "fmt" - "net/http" - - "github.com/letsencrypt/boulder/identifier" -) - -const ( - // Error types that can be used in ACME payloads. These are sorted in the - // same order as they are defined in RFC8555 Section 6.7. We do not implement - // the `compound`, `externalAccountRequired`, or `userActionRequired` errors, - // because we have no path that would return them. - AccountDoesNotExistProblem = ProblemType("accountDoesNotExist") - AlreadyRevokedProblem = ProblemType("alreadyRevoked") - BadCSRProblem = ProblemType("badCSR") - BadNonceProblem = ProblemType("badNonce") - BadPublicKeyProblem = ProblemType("badPublicKey") - BadRevocationReasonProblem = ProblemType("badRevocationReason") - BadSignatureAlgorithmProblem = ProblemType("badSignatureAlgorithm") - CAAProblem = ProblemType("caa") - // ConflictProblem is a problem type that is not defined in RFC8555. - ConflictProblem = ProblemType("conflict") - ConnectionProblem = ProblemType("connection") - DNSProblem = ProblemType("dns") - InvalidContactProblem = ProblemType("invalidContact") - MalformedProblem = ProblemType("malformed") - OrderNotReadyProblem = ProblemType("orderNotReady") - RateLimitedProblem = ProblemType("rateLimited") - RejectedIdentifierProblem = ProblemType("rejectedIdentifier") - ServerInternalProblem = ProblemType("serverInternal") - TLSProblem = ProblemType("tls") - UnauthorizedProblem = ProblemType("unauthorized") - UnsupportedContactProblem = ProblemType("unsupportedContact") - UnsupportedIdentifierProblem = ProblemType("unsupportedIdentifier") - - ErrorNS = "urn:ietf:params:acme:error:" -) - -// ProblemType defines the error types in the ACME protocol -type ProblemType string - -// ProblemDetails objects represent problem documents -// https://tools.ietf.org/html/draft-ietf-appsawg-http-problem-00 -type ProblemDetails struct { - Type ProblemType `json:"type,omitempty"` - Detail string `json:"detail,omitempty"` - // HTTPStatus is the HTTP status code the ProblemDetails should probably be sent - // as. - HTTPStatus int `json:"status,omitempty"` - // SubProblems are optional additional per-identifier problems. See - // RFC 8555 Section 6.7.1: https://tools.ietf.org/html/rfc8555#section-6.7.1 - SubProblems []SubProblemDetails `json:"subproblems,omitempty"` -} - -// SubProblemDetails represents sub-problems specific to an identifier that are -// related to a top-level ProblemDetails. -// See RFC 8555 Section 6.7.1: https://tools.ietf.org/html/rfc8555#section-6.7.1 -type SubProblemDetails struct { - ProblemDetails - Identifier identifier.ACMEIdentifier `json:"identifier"` -} - -func (pd *ProblemDetails) Error() string { - return fmt.Sprintf("%s :: %s", pd.Type, pd.Detail) -} - -// WithSubProblems returns a new ProblemsDetails instance created by adding the -// provided subProbs to the existing ProblemsDetail. -func (pd *ProblemDetails) WithSubProblems(subProbs []SubProblemDetails) *ProblemDetails { - return &ProblemDetails{ - Type: pd.Type, - Detail: pd.Detail, - HTTPStatus: pd.HTTPStatus, - SubProblems: append(pd.SubProblems, subProbs...), - } -} - -// Helper functions which construct the basic RFC8555 Problem Documents, with -// the Type already set and the Details supplied by the caller. - -// AccountDoesNotExist returns a ProblemDetails representing an -// AccountDoesNotExistProblem error -func AccountDoesNotExist(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: AccountDoesNotExistProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// AlreadyRevoked returns a ProblemDetails with a AlreadyRevokedProblem and a 400 Bad -// Request status code. -func AlreadyRevoked(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: AlreadyRevokedProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// BadCSR returns a ProblemDetails representing a BadCSRProblem. -func BadCSR(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: BadCSRProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// BadNonce returns a ProblemDetails with a BadNonceProblem and a 400 Bad -// Request status code. -func BadNonce(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: BadNonceProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// BadPublicKey returns a ProblemDetails with a BadPublicKeyProblem and a 400 Bad -// Request status code. -func BadPublicKey(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: BadPublicKeyProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// BadRevocationReason returns a ProblemDetails representing -// a BadRevocationReasonProblem -func BadRevocationReason(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: BadRevocationReasonProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// BadSignatureAlgorithm returns a ProblemDetails with a BadSignatureAlgorithmProblem -// and a 400 Bad Request status code. -func BadSignatureAlgorithm(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: BadSignatureAlgorithmProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// CAA returns a ProblemDetails representing a CAAProblem -func CAA(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: CAAProblem, - Detail: detail, - HTTPStatus: http.StatusForbidden, - } -} - -// Connection returns a ProblemDetails representing a ConnectionProblem -// error -func Connection(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: ConnectionProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// DNS returns a ProblemDetails representing a DNSProblem -func DNS(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: DNSProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// InvalidContact returns a ProblemDetails representing an InvalidContactProblem. -func InvalidContact(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: InvalidContactProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// Malformed returns a ProblemDetails with a MalformedProblem and a 400 Bad -// Request status code. -func Malformed(detail string, a ...any) *ProblemDetails { - if len(a) > 0 { - detail = fmt.Sprintf(detail, a...) - } - return &ProblemDetails{ - Type: MalformedProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// OrderNotReady returns a ProblemDetails representing a OrderNotReadyProblem -func OrderNotReady(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: OrderNotReadyProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusForbidden, - } -} - -// RateLimited returns a ProblemDetails representing a RateLimitedProblem error -func RateLimited(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: RateLimitedProblem, - Detail: detail, - HTTPStatus: http.StatusTooManyRequests, - } -} - -// RejectedIdentifier returns a ProblemDetails with a RejectedIdentifierProblem and a 400 Bad -// Request status code. -func RejectedIdentifier(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: RejectedIdentifierProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// ServerInternal returns a ProblemDetails with a ServerInternalProblem and a -// 500 Internal Server Failure status code. -func ServerInternal(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: ServerInternalProblem, - Detail: detail, - HTTPStatus: http.StatusInternalServerError, - } -} - -// TLS returns a ProblemDetails representing a TLSProblem error -func TLS(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: TLSProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// Unauthorized returns a ProblemDetails with an UnauthorizedProblem and a 403 -// Forbidden status code. -func Unauthorized(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: UnauthorizedProblem, - Detail: detail, - HTTPStatus: http.StatusForbidden, - } -} - -// UnsupportedContact returns a ProblemDetails representing an -// UnsupportedContactProblem -func UnsupportedContact(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: UnsupportedContactProblem, - Detail: detail, - HTTPStatus: http.StatusBadRequest, - } -} - -// UnsupportedIdentifier returns a ProblemDetails representing an -// UnsupportedIdentifierProblem -func UnsupportedIdentifier(detail string, a ...any) *ProblemDetails { - return &ProblemDetails{ - Type: UnsupportedIdentifierProblem, - Detail: fmt.Sprintf(detail, a...), - HTTPStatus: http.StatusBadRequest, - } -} - -// Additional helper functions that return variations on MalformedProblem with -// different HTTP status codes set. - -// Canceled returns a ProblemDetails with a MalformedProblem and a 408 Request -// Timeout status code. -func Canceled(detail string, a ...any) *ProblemDetails { - if len(a) > 0 { - detail = fmt.Sprintf(detail, a...) - } - return &ProblemDetails{ - Type: MalformedProblem, - Detail: detail, - HTTPStatus: http.StatusRequestTimeout, - } -} - -// Conflict returns a ProblemDetails with a ConflictProblem and a 409 Conflict -// status code. -func Conflict(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: ConflictProblem, - Detail: detail, - HTTPStatus: http.StatusConflict, - } -} - -// ContentLengthRequired returns a ProblemDetails representing a missing -// Content-Length header error -func ContentLengthRequired() *ProblemDetails { - return &ProblemDetails{ - Type: MalformedProblem, - Detail: "missing Content-Length header", - HTTPStatus: http.StatusLengthRequired, - } -} - -// InvalidContentType returns a ProblemDetails suitable for a missing -// ContentType header, or an incorrect ContentType header -func InvalidContentType(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: MalformedProblem, - Detail: detail, - HTTPStatus: http.StatusUnsupportedMediaType, - } -} - -// MethodNotAllowed returns a ProblemDetails representing a disallowed HTTP -// method error. -func MethodNotAllowed() *ProblemDetails { - return &ProblemDetails{ - Type: MalformedProblem, - Detail: "Method not allowed", - HTTPStatus: http.StatusMethodNotAllowed, - } -} - -// NotFound returns a ProblemDetails with a MalformedProblem and a 404 Not Found -// status code. -func NotFound(detail string) *ProblemDetails { - return &ProblemDetails{ - Type: MalformedProblem, - Detail: detail, - HTTPStatus: http.StatusNotFound, - } -} diff --git a/vendor/github.com/letsencrypt/boulder/revocation/reasons.go b/vendor/github.com/letsencrypt/boulder/revocation/reasons.go deleted file mode 100644 index 50f556be011..00000000000 --- a/vendor/github.com/letsencrypt/boulder/revocation/reasons.go +++ /dev/null @@ -1,72 +0,0 @@ -package revocation - -import ( - "fmt" - "sort" - "strings" - - "golang.org/x/crypto/ocsp" -) - -// Reason is used to specify a certificate revocation reason -type Reason int - -// ReasonToString provides a map from reason code to string -var ReasonToString = map[Reason]string{ - ocsp.Unspecified: "unspecified", - ocsp.KeyCompromise: "keyCompromise", - ocsp.CACompromise: "cACompromise", - ocsp.AffiliationChanged: "affiliationChanged", - ocsp.Superseded: "superseded", - ocsp.CessationOfOperation: "cessationOfOperation", - ocsp.CertificateHold: "certificateHold", - // 7 is unused - ocsp.RemoveFromCRL: "removeFromCRL", - ocsp.PrivilegeWithdrawn: "privilegeWithdrawn", - ocsp.AACompromise: "aAcompromise", -} - -// UserAllowedReasons contains the subset of Reasons which users are -// allowed to use -var UserAllowedReasons = map[Reason]struct{}{ - ocsp.Unspecified: {}, - ocsp.KeyCompromise: {}, - ocsp.Superseded: {}, - ocsp.CessationOfOperation: {}, -} - -// AdminAllowedReasons contains the subset of Reasons which admins are allowed -// to use. Reasons not found here will soon be forbidden from appearing in CRLs -// or OCSP responses by root programs. -var AdminAllowedReasons = map[Reason]struct{}{ - ocsp.Unspecified: {}, - ocsp.KeyCompromise: {}, - ocsp.Superseded: {}, - ocsp.CessationOfOperation: {}, - ocsp.PrivilegeWithdrawn: {}, -} - -// UserAllowedReasonsMessage contains a string describing a list of user allowed -// revocation reasons. This is useful when a revocation is rejected because it -// is not a valid user supplied reason and the allowed values must be -// communicated. This variable is populated during package initialization. -var UserAllowedReasonsMessage = "" - -func init() { - // Build a slice of ints from the allowed reason codes. - // We want a slice because iterating `UserAllowedReasons` will change order - // and make the message unpredictable and cumbersome for unit testing. - // We use []ints instead of []Reason to use `sort.Ints` without fuss. - var allowed []int - for reason := range UserAllowedReasons { - allowed = append(allowed, int(reason)) - } - sort.Ints(allowed) - - var reasonStrings []string - for _, reason := range allowed { - reasonStrings = append(reasonStrings, fmt.Sprintf("%s (%d)", - ReasonToString[Reason(reason)], reason)) - } - UserAllowedReasonsMessage = strings.Join(reasonStrings, ", ") -} diff --git a/vendor/github.com/letsencrypt/boulder/strictyaml/yaml.go b/vendor/github.com/letsencrypt/boulder/strictyaml/yaml.go deleted file mode 100644 index 8e3bae9965a..00000000000 --- a/vendor/github.com/letsencrypt/boulder/strictyaml/yaml.go +++ /dev/null @@ -1,46 +0,0 @@ -// Package strictyaml provides a strict YAML unmarshaller based on `go-yaml/yaml` -package strictyaml - -import ( - "bytes" - "errors" - "fmt" - "io" - - "gopkg.in/yaml.v3" -) - -// Unmarshal takes a byte array and an interface passed by reference. The -// d.Decode will read the next YAML-encoded value from its input and store it in -// the value pointed to by yamlObj. Any config keys from the incoming YAML -// document which do not correspond to expected keys in the config struct will -// result in errors. -// -// TODO(https://github.com/go-yaml/yaml/issues/639): Replace this function with -// yaml.Unmarshal once a more ergonomic way to set unmarshal options is added -// upstream. -func Unmarshal(b []byte, yamlObj interface{}) error { - r := bytes.NewReader(b) - - d := yaml.NewDecoder(r) - d.KnownFields(true) - - // d.Decode will mutate yamlObj - err := d.Decode(yamlObj) - - if err != nil { - // io.EOF is returned when the YAML document is empty. - if errors.Is(err, io.EOF) { - return fmt.Errorf("unmarshalling YAML, bytes cannot be nil: %w", err) - } - return fmt.Errorf("unmarshalling YAML: %w", err) - } - - // As bytes are read by the decoder, the length of the byte buffer should - // decrease. If it doesn't, there's a problem. - if r.Len() != 0 { - return fmt.Errorf("yaml object of size %d bytes had %d bytes of unexpected unconsumed trailers", r.Size(), r.Len()) - } - - return nil -} diff --git a/vendor/github.com/modern-go/reflect2/safe_type.go b/vendor/github.com/modern-go/reflect2/safe_type.go index ee4e7bb6edf..5646309e09c 100644 --- a/vendor/github.com/modern-go/reflect2/safe_type.go +++ b/vendor/github.com/modern-go/reflect2/safe_type.go @@ -6,10 +6,12 @@ import ( ) type safeType struct { - reflect.Type - cfg *frozenConfig + Type reflect.Type + cfg *frozenConfig } +var _ Type = &safeType{} + func (type2 *safeType) New() interface{} { return reflect.New(type2.Type).Interface() } @@ -18,6 +20,22 @@ func (type2 *safeType) UnsafeNew() unsafe.Pointer { panic("does not support unsafe operation") } +func (type2 *safeType) Kind() reflect.Kind { + return type2.Type.Kind() +} + +func (type2 *safeType) Len() int { + return type2.Type.Len() +} + +func (type2 *safeType) NumField() int { + return type2.Type.NumField() +} + +func (type2 *safeType) String() string { + return type2.Type.String() +} + func (type2 *safeType) Elem() Type { return type2.cfg.Type2(type2.Type.Elem()) } diff --git a/vendor/github.com/opencontainers/cgroups/fs/blkio.go b/vendor/github.com/opencontainers/cgroups/fs/blkio.go deleted file mode 100644 index f3c4c5cf816..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/blkio.go +++ /dev/null @@ -1,310 +0,0 @@ -package fs - -import ( - "bufio" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/opencontainers/cgroups" -) - -type BlkioGroup struct { - weightFilename string - weightDeviceFilename string -} - -func (s *BlkioGroup) Name() string { - return "blkio" -} - -func (s *BlkioGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *BlkioGroup) Set(path string, r *cgroups.Resources) error { - s.detectWeightFilenames(path) - if r.BlkioWeight != 0 { - if err := cgroups.WriteFile(path, s.weightFilename, strconv.FormatUint(uint64(r.BlkioWeight), 10)); err != nil { - return err - } - } - - if r.BlkioLeafWeight != 0 { - if err := cgroups.WriteFile(path, "blkio.leaf_weight", strconv.FormatUint(uint64(r.BlkioLeafWeight), 10)); err != nil { - return err - } - } - for _, wd := range r.BlkioWeightDevice { - if wd.Weight != 0 { - if err := cgroups.WriteFile(path, s.weightDeviceFilename, wd.WeightString()); err != nil { - return err - } - } - if wd.LeafWeight != 0 { - if err := cgroups.WriteFile(path, "blkio.leaf_weight_device", wd.LeafWeightString()); err != nil { - return err - } - } - } - for _, td := range r.BlkioThrottleReadBpsDevice { - if err := cgroups.WriteFile(path, "blkio.throttle.read_bps_device", td.String()); err != nil { - return err - } - } - for _, td := range r.BlkioThrottleWriteBpsDevice { - if err := cgroups.WriteFile(path, "blkio.throttle.write_bps_device", td.String()); err != nil { - return err - } - } - for _, td := range r.BlkioThrottleReadIOPSDevice { - if err := cgroups.WriteFile(path, "blkio.throttle.read_iops_device", td.String()); err != nil { - return err - } - } - for _, td := range r.BlkioThrottleWriteIOPSDevice { - if err := cgroups.WriteFile(path, "blkio.throttle.write_iops_device", td.String()); err != nil { - return err - } - } - - return nil -} - -/* -examples: - - blkio.sectors - 8:0 6792 - - blkio.io_service_bytes - 8:0 Read 1282048 - 8:0 Write 2195456 - 8:0 Sync 2195456 - 8:0 Async 1282048 - 8:0 Total 3477504 - Total 3477504 - - blkio.io_serviced - 8:0 Read 124 - 8:0 Write 104 - 8:0 Sync 104 - 8:0 Async 124 - 8:0 Total 228 - Total 228 - - blkio.io_queued - 8:0 Read 0 - 8:0 Write 0 - 8:0 Sync 0 - 8:0 Async 0 - 8:0 Total 0 - Total 0 -*/ - -func splitBlkioStatLine(r rune) bool { - return r == ' ' || r == ':' -} - -func getBlkioStat(dir, file string) ([]cgroups.BlkioStatEntry, error) { - var blkioStats []cgroups.BlkioStatEntry - f, err := cgroups.OpenFile(dir, file, os.O_RDONLY) - if err != nil { - if os.IsNotExist(err) { - return blkioStats, nil - } - return nil, err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - // format: dev type amount - fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine) - if len(fields) < 3 { - if len(fields) == 2 && fields[0] == "Total" { - // skip total line - continue - } else { - return nil, malformedLine(dir, file, sc.Text()) - } - } - - v, err := strconv.ParseUint(fields[0], 10, 64) - if err != nil { - return nil, &parseError{Path: dir, File: file, Err: err} - } - major := v - - v, err = strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return nil, &parseError{Path: dir, File: file, Err: err} - } - minor := v - - op := "" - valueField := 2 - if len(fields) == 4 { - op = fields[2] - valueField = 3 - } - v, err = strconv.ParseUint(fields[valueField], 10, 64) - if err != nil { - return nil, &parseError{Path: dir, File: file, Err: err} - } - blkioStats = append(blkioStats, cgroups.BlkioStatEntry{Major: major, Minor: minor, Op: op, Value: v}) - } - if err := sc.Err(); err != nil { - return nil, &parseError{Path: dir, File: file, Err: err} - } - - return blkioStats, nil -} - -func (s *BlkioGroup) GetStats(path string, stats *cgroups.Stats) error { - type blkioStatInfo struct { - filename string - blkioStatEntriesPtr *[]cgroups.BlkioStatEntry - } - bfqDebugStats := []blkioStatInfo{ - { - filename: "blkio.bfq.sectors_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive, - }, - { - filename: "blkio.bfq.io_service_time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive, - }, - { - filename: "blkio.bfq.io_wait_time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive, - }, - { - filename: "blkio.bfq.io_merged_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive, - }, - { - filename: "blkio.bfq.io_queued_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive, - }, - { - filename: "blkio.bfq.time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive, - }, - { - filename: "blkio.bfq.io_serviced_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, - }, - { - filename: "blkio.bfq.io_service_bytes_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, - }, - } - bfqStats := []blkioStatInfo{ - { - filename: "blkio.bfq.io_serviced_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, - }, - { - filename: "blkio.bfq.io_service_bytes_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, - }, - } - cfqStats := []blkioStatInfo{ - { - filename: "blkio.sectors_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.SectorsRecursive, - }, - { - filename: "blkio.io_service_time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceTimeRecursive, - }, - { - filename: "blkio.io_wait_time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoWaitTimeRecursive, - }, - { - filename: "blkio.io_merged_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoMergedRecursive, - }, - { - filename: "blkio.io_queued_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoQueuedRecursive, - }, - { - filename: "blkio.time_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoTimeRecursive, - }, - { - filename: "blkio.io_serviced_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, - }, - { - filename: "blkio.io_service_bytes_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, - }, - } - throttleRecursiveStats := []blkioStatInfo{ - { - filename: "blkio.throttle.io_serviced_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, - }, - { - filename: "blkio.throttle.io_service_bytes_recursive", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, - }, - } - baseStats := []blkioStatInfo{ - { - filename: "blkio.throttle.io_serviced", - blkioStatEntriesPtr: &stats.BlkioStats.IoServicedRecursive, - }, - { - filename: "blkio.throttle.io_service_bytes", - blkioStatEntriesPtr: &stats.BlkioStats.IoServiceBytesRecursive, - }, - } - orderedStats := [][]blkioStatInfo{ - bfqDebugStats, - bfqStats, - cfqStats, - throttleRecursiveStats, - baseStats, - } - - var blkioStats []cgroups.BlkioStatEntry - var err error - - for _, statGroup := range orderedStats { - for i, statInfo := range statGroup { - if blkioStats, err = getBlkioStat(path, statInfo.filename); err != nil || blkioStats == nil { - // if error occurs on first file, move to next group - if i == 0 { - break - } - return err - } - *statInfo.blkioStatEntriesPtr = blkioStats - // finish if all stats are gathered - if i == len(statGroup)-1 { - return nil - } - } - } - return nil -} - -func (s *BlkioGroup) detectWeightFilenames(path string) { - if s.weightFilename != "" { - // Already detected. - return - } - if cgroups.PathExists(filepath.Join(path, "blkio.weight")) { - s.weightFilename = "blkio.weight" - s.weightDeviceFilename = "blkio.weight_device" - } else { - s.weightFilename = "blkio.bfq.weight" - s.weightDeviceFilename = "blkio.bfq.weight_device" - } -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/cpu.go b/vendor/github.com/opencontainers/cgroups/fs/cpu.go deleted file mode 100644 index 3e05788a3f6..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/cpu.go +++ /dev/null @@ -1,181 +0,0 @@ -package fs - -import ( - "bufio" - "errors" - "fmt" - "os" - "strconv" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" - "golang.org/x/sys/unix" -) - -type CpuGroup struct{} - -func (s *CpuGroup) Name() string { - return "cpu" -} - -func (s *CpuGroup) Apply(path string, r *cgroups.Resources, pid int) error { - if err := os.MkdirAll(path, 0o755); err != nil { - return err - } - // We should set the real-Time group scheduling settings before moving - // in the process because if the process is already in SCHED_RR mode - // and no RT bandwidth is set, adding it will fail. - if err := s.SetRtSched(path, r); err != nil { - return err - } - // Since we are not using apply(), we need to place the pid - // into the procs file. - return cgroups.WriteCgroupProc(path, pid) -} - -func (s *CpuGroup) SetRtSched(path string, r *cgroups.Resources) error { - var period string - if r.CpuRtPeriod != 0 { - period = strconv.FormatUint(r.CpuRtPeriod, 10) - if err := cgroups.WriteFile(path, "cpu.rt_period_us", period); err != nil { - // The values of cpu.rt_period_us and cpu.rt_runtime_us - // are inter-dependent and need to be set in a proper order. - // If the kernel rejects the new period value with EINVAL - // and the new runtime value is also being set, let's - // ignore the error for now and retry later. - if !errors.Is(err, unix.EINVAL) || r.CpuRtRuntime == 0 { - return err - } - } else { - period = "" - } - } - if r.CpuRtRuntime != 0 { - if err := cgroups.WriteFile(path, "cpu.rt_runtime_us", strconv.FormatInt(r.CpuRtRuntime, 10)); err != nil { - return err - } - if period != "" { - if err := cgroups.WriteFile(path, "cpu.rt_period_us", period); err != nil { - return err - } - } - } - return nil -} - -func (s *CpuGroup) Set(path string, r *cgroups.Resources) error { - if r.CpuShares != 0 { - shares := r.CpuShares - if err := cgroups.WriteFile(path, "cpu.shares", strconv.FormatUint(shares, 10)); err != nil { - return err - } - // read it back - sharesRead, err := fscommon.GetCgroupParamUint(path, "cpu.shares") - if err != nil { - return err - } - // ... and check - if shares > sharesRead { - return fmt.Errorf("the maximum allowed cpu-shares is %d", sharesRead) - } else if shares < sharesRead { - return fmt.Errorf("the minimum allowed cpu-shares is %d", sharesRead) - } - } - - var period string - if r.CpuPeriod != 0 { - period = strconv.FormatUint(r.CpuPeriod, 10) - if err := cgroups.WriteFile(path, "cpu.cfs_period_us", period); err != nil { - // Sometimes when the period to be set is smaller - // than the current one, it is rejected by the kernel - // (EINVAL) as old_quota/new_period exceeds the parent - // cgroup quota limit. If this happens and the quota is - // going to be set, ignore the error for now and retry - // after setting the quota. - if !errors.Is(err, unix.EINVAL) || r.CpuQuota == 0 { - return err - } - } else { - period = "" - } - } - - var burst string - if r.CpuBurst != nil { - burst = strconv.FormatUint(*r.CpuBurst, 10) - if err := cgroups.WriteFile(path, "cpu.cfs_burst_us", burst); err != nil { - if errors.Is(err, unix.ENOENT) { - // If CPU burst knob is not available (e.g. - // older kernel), ignore it. - burst = "" - } else { - // Sometimes when the burst to be set is larger - // than the current one, it is rejected by the kernel - // (EINVAL) as old_quota/new_burst exceeds the parent - // cgroup quota limit. If this happens and the quota is - // going to be set, ignore the error for now and retry - // after setting the quota. - if !errors.Is(err, unix.EINVAL) || r.CpuQuota == 0 { - return err - } - } - } else { - burst = "" - } - } - if r.CpuQuota != 0 { - if err := cgroups.WriteFile(path, "cpu.cfs_quota_us", strconv.FormatInt(r.CpuQuota, 10)); err != nil { - return err - } - if period != "" { - if err := cgroups.WriteFile(path, "cpu.cfs_period_us", period); err != nil { - return err - } - } - if burst != "" { - if err := cgroups.WriteFile(path, "cpu.cfs_burst_us", burst); err != nil { - return err - } - } - } - - if r.CPUIdle != nil { - idle := strconv.FormatInt(*r.CPUIdle, 10) - if err := cgroups.WriteFile(path, "cpu.idle", idle); err != nil { - return err - } - } - - return s.SetRtSched(path, r) -} - -func (s *CpuGroup) GetStats(path string, stats *cgroups.Stats) error { - const file = "cpu.stat" - f, err := cgroups.OpenFile(path, file, os.O_RDONLY) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer f.Close() - - sc := bufio.NewScanner(f) - for sc.Scan() { - t, v, err := fscommon.ParseKeyValue(sc.Text()) - if err != nil { - return &parseError{Path: path, File: file, Err: err} - } - switch t { - case "nr_periods": - stats.CpuStats.ThrottlingData.Periods = v - - case "nr_throttled": - stats.CpuStats.ThrottlingData.ThrottledPeriods = v - - case "throttled_time": - stats.CpuStats.ThrottlingData.ThrottledTime = v - } - } - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go b/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go deleted file mode 100644 index bde25b07594..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/cpuacct.go +++ /dev/null @@ -1,162 +0,0 @@ -package fs - -import ( - "bufio" - "os" - "strconv" - "strings" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -const ( - nsInSec = 1000000000 - - // The value comes from `C.sysconf(C._SC_CLK_TCK)`, and - // on Linux it's a constant which is safe to be hard coded, - // so we can avoid using cgo here. For details, see: - // https://github.com/containerd/cgroups/pull/12 - clockTicks uint64 = 100 -) - -type CpuacctGroup struct{} - -func (s *CpuacctGroup) Name() string { - return "cpuacct" -} - -func (s *CpuacctGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *CpuacctGroup) Set(_ string, _ *cgroups.Resources) error { - return nil -} - -func (s *CpuacctGroup) GetStats(path string, stats *cgroups.Stats) error { - if !cgroups.PathExists(path) { - return nil - } - userModeUsage, kernelModeUsage, err := getCpuUsageBreakdown(path) - if err != nil { - return err - } - - totalUsage, err := fscommon.GetCgroupParamUint(path, "cpuacct.usage") - if err != nil { - return err - } - - percpuUsage, err := getPercpuUsage(path) - if err != nil { - return err - } - - percpuUsageInKernelmode, percpuUsageInUsermode, err := getPercpuUsageInModes(path) - if err != nil { - return err - } - - stats.CpuStats.CpuUsage.TotalUsage = totalUsage - stats.CpuStats.CpuUsage.PercpuUsage = percpuUsage - stats.CpuStats.CpuUsage.PercpuUsageInKernelmode = percpuUsageInKernelmode - stats.CpuStats.CpuUsage.PercpuUsageInUsermode = percpuUsageInUsermode - stats.CpuStats.CpuUsage.UsageInUsermode = userModeUsage - stats.CpuStats.CpuUsage.UsageInKernelmode = kernelModeUsage - return nil -} - -// Returns user and kernel usage breakdown in nanoseconds. -func getCpuUsageBreakdown(path string) (uint64, uint64, error) { - var userModeUsage, kernelModeUsage uint64 - const ( - userField = "user" - systemField = "system" - file = "cpuacct.stat" - ) - - // Expected format: - // user - // system - data, err := cgroups.ReadFile(path, file) - if err != nil { - return 0, 0, err - } - - fields := strings.Fields(data) - if len(fields) < 4 || fields[0] != userField || fields[2] != systemField { - return 0, 0, malformedLine(path, file, data) - } - if userModeUsage, err = strconv.ParseUint(fields[1], 10, 64); err != nil { - return 0, 0, &parseError{Path: path, File: file, Err: err} - } - if kernelModeUsage, err = strconv.ParseUint(fields[3], 10, 64); err != nil { - return 0, 0, &parseError{Path: path, File: file, Err: err} - } - - return (userModeUsage * nsInSec) / clockTicks, (kernelModeUsage * nsInSec) / clockTicks, nil -} - -func getPercpuUsage(path string) ([]uint64, error) { - const file = "cpuacct.usage_percpu" - percpuUsage := []uint64{} - data, err := cgroups.ReadFile(path, file) - if err != nil { - return percpuUsage, err - } - for _, value := range strings.Fields(data) { - value, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return percpuUsage, &parseError{Path: path, File: file, Err: err} - } - percpuUsage = append(percpuUsage, value) - } - return percpuUsage, nil -} - -func getPercpuUsageInModes(path string) ([]uint64, []uint64, error) { - usageKernelMode := []uint64{} - usageUserMode := []uint64{} - const file = "cpuacct.usage_all" - - fd, err := cgroups.OpenFile(path, file, os.O_RDONLY) - if os.IsNotExist(err) { - return usageKernelMode, usageUserMode, nil - } else if err != nil { - return nil, nil, err - } - defer fd.Close() - - scanner := bufio.NewScanner(fd) - scanner.Scan() // Read header line. - const want = "cpu user system" - if hdr := scanner.Text(); !strings.HasPrefix(hdr, want) { - return nil, nil, malformedLine(path, file, hdr) - } - - for scanner.Scan() { - // Each line is: cpu user system. Keep N at 4 to ignore extra fields. - fields := strings.SplitN(scanner.Text(), " ", 4) - if len(fields) < 3 { - continue - } - - user, err := strconv.ParseUint(fields[1], 10, 64) - if err != nil { - return nil, nil, &parseError{Path: path, File: file, Err: err} - } - usageUserMode = append(usageUserMode, user) - - kernel, err := strconv.ParseUint(fields[2], 10, 64) - if err != nil { - return nil, nil, &parseError{Path: path, File: file, Err: err} - } - usageKernelMode = append(usageKernelMode, kernel) - } - if err := scanner.Err(); err != nil { - return nil, nil, &parseError{Path: path, File: file, Err: err} - } - - return usageKernelMode, usageUserMode, nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/cpuset.go b/vendor/github.com/opencontainers/cgroups/fs/cpuset.go deleted file mode 100644 index ef6ff7da303..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/cpuset.go +++ /dev/null @@ -1,276 +0,0 @@ -package fs - -import ( - "errors" - "os" - "path/filepath" - "strconv" - "strings" - "sync" - - "golang.org/x/sys/unix" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -var ( - cpusetLock sync.Mutex - cpusetPrefix = "cpuset." - cpusetFastPath bool -) - -func cpusetFile(path string, name string) string { - cpusetLock.Lock() - defer cpusetLock.Unlock() - - // Only the v1 cpuset cgroup is allowed to mount with noprefix. - // See kernel source: https://github.com/torvalds/linux/blob/2e1b3cc9d7f790145a80cb705b168f05dab65df2/kernel/cgroup/cgroup-v1.c#L1070 - // Cpuset cannot be mounted with and without prefix simultaneously. - // Commonly used in Android environments. - - if cpusetFastPath { - return cpusetPrefix + name - } - - err := unix.Access(filepath.Join(path, cpusetPrefix+name), unix.F_OK) - if err == nil { - // Use the fast path only if we can access one type of mount for cpuset already - cpusetFastPath = true - } else { - err = unix.Access(filepath.Join(path, name), unix.F_OK) - if err == nil { - cpusetPrefix = "" - cpusetFastPath = true - } - } - - return cpusetPrefix + name -} - -type CpusetGroup struct{} - -func (s *CpusetGroup) Name() string { - return "cpuset" -} - -func (s *CpusetGroup) Apply(path string, r *cgroups.Resources, pid int) error { - return s.ApplyDir(path, r, pid) -} - -func (s *CpusetGroup) Set(path string, r *cgroups.Resources) error { - if r.CpusetCpus != "" { - if err := cgroups.WriteFile(path, cpusetFile(path, "cpus"), r.CpusetCpus); err != nil { - return err - } - } - if r.CpusetMems != "" { - if err := cgroups.WriteFile(path, cpusetFile(path, "mems"), r.CpusetMems); err != nil { - return err - } - } - return nil -} - -func getCpusetStat(path string, file string) ([]uint16, error) { - var extracted []uint16 - fileContent, err := fscommon.GetCgroupParamString(path, file) - if err != nil { - return extracted, err - } - if len(fileContent) == 0 { - return extracted, &parseError{Path: path, File: file, Err: errors.New("empty file")} - } - - for _, s := range strings.Split(fileContent, ",") { - fromStr, toStr, ok := strings.Cut(s, "-") - if ok { - from, err := strconv.ParseUint(fromStr, 10, 16) - if err != nil { - return extracted, &parseError{Path: path, File: file, Err: err} - } - to, err := strconv.ParseUint(toStr, 10, 16) - if err != nil { - return extracted, &parseError{Path: path, File: file, Err: err} - } - if from > to { - return extracted, &parseError{Path: path, File: file, Err: errors.New("invalid values, from > to")} - } - for i := from; i <= to; i++ { - extracted = append(extracted, uint16(i)) - } - } else { - value, err := strconv.ParseUint(s, 10, 16) - if err != nil { - return extracted, &parseError{Path: path, File: file, Err: err} - } - extracted = append(extracted, uint16(value)) - } - } - - return extracted, nil -} - -func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { - var err error - - stats.CPUSetStats.CPUs, err = getCpusetStat(path, cpusetFile(path, "cpus")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.CPUExclusive, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "cpu_exclusive")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.Mems, err = getCpusetStat(path, cpusetFile(path, "mems")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemHardwall, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "mem_hardwall")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemExclusive, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "mem_exclusive")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemoryMigrate, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_migrate")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemorySpreadPage, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_spread_page")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemorySpreadSlab, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_spread_slab")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.MemoryPressure, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "memory_pressure")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.SchedLoadBalance, err = fscommon.GetCgroupParamUint(path, cpusetFile(path, "sched_load_balance")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - stats.CPUSetStats.SchedRelaxDomainLevel, err = fscommon.GetCgroupParamInt(path, cpusetFile(path, "sched_relax_domain_level")) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - - return nil -} - -func (s *CpusetGroup) ApplyDir(dir string, r *cgroups.Resources, pid int) error { - // This might happen if we have no cpuset cgroup mounted. - // Just do nothing and don't fail. - if dir == "" { - return nil - } - // 'ensureParent' start with parent because we don't want to - // explicitly inherit from parent, it could conflict with - // 'cpuset.cpu_exclusive'. - if err := cpusetEnsureParent(filepath.Dir(dir)); err != nil { - return err - } - if err := os.Mkdir(dir, 0o755); err != nil && !os.IsExist(err) { - return err - } - // We didn't inherit cpuset configs from parent, but we have - // to ensure cpuset configs are set before moving task into the - // cgroup. - // The logic is, if user specified cpuset configs, use these - // specified configs, otherwise, inherit from parent. This makes - // cpuset configs work correctly with 'cpuset.cpu_exclusive', and - // keep backward compatibility. - if err := s.ensureCpusAndMems(dir, r); err != nil { - return err - } - // Since we are not using apply(), we need to place the pid - // into the procs file. - return cgroups.WriteCgroupProc(dir, pid) -} - -func getCpusetSubsystemSettings(parent string) (cpus, mems string, err error) { - if cpus, err = cgroups.ReadFile(parent, cpusetFile(parent, "cpus")); err != nil { - return - } - if mems, err = cgroups.ReadFile(parent, cpusetFile(parent, "mems")); err != nil { - return - } - return cpus, mems, nil -} - -// cpusetEnsureParent makes sure that the parent directories of current -// are created and populated with the proper cpus and mems files copied -// from their respective parent. It does that recursively, starting from -// the top of the cpuset hierarchy (i.e. cpuset cgroup mount point). -func cpusetEnsureParent(current string) error { - var st unix.Statfs_t - - parent := filepath.Dir(current) - err := unix.Statfs(parent, &st) - if err == nil && st.Type != unix.CGROUP_SUPER_MAGIC { - return nil - } - // Treat non-existing directory as cgroupfs as it will be created, - // and the root cpuset directory obviously exists. - if err != nil && err != unix.ENOENT { - return &os.PathError{Op: "statfs", Path: parent, Err: err} - } - - if err := cpusetEnsureParent(parent); err != nil { - return err - } - if err := os.Mkdir(current, 0o755); err != nil && !os.IsExist(err) { - return err - } - return cpusetCopyIfNeeded(current, parent) -} - -// cpusetCopyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent -// directory to the current directory if the file's contents are 0 -func cpusetCopyIfNeeded(current, parent string) error { - currentCpus, currentMems, err := getCpusetSubsystemSettings(current) - if err != nil { - return err - } - parentCpus, parentMems, err := getCpusetSubsystemSettings(parent) - if err != nil { - return err - } - - if isEmptyCpuset(currentCpus) { - if err := cgroups.WriteFile(current, cpusetFile(current, "cpus"), parentCpus); err != nil { - return err - } - } - if isEmptyCpuset(currentMems) { - if err := cgroups.WriteFile(current, cpusetFile(current, "mems"), parentMems); err != nil { - return err - } - } - return nil -} - -func isEmptyCpuset(str string) bool { - return str == "" || str == "\n" -} - -func (s *CpusetGroup) ensureCpusAndMems(path string, r *cgroups.Resources) error { - if err := s.Set(path, r); err != nil { - return err - } - return cpusetCopyIfNeeded(path, filepath.Dir(path)) -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/devices.go b/vendor/github.com/opencontainers/cgroups/fs/devices.go deleted file mode 100644 index 26483ecb7dd..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/devices.go +++ /dev/null @@ -1,38 +0,0 @@ -package fs - -import ( - "github.com/opencontainers/cgroups" -) - -type DevicesGroup struct{} - -func (s *DevicesGroup) Name() string { - return "devices" -} - -func (s *DevicesGroup) Apply(path string, r *cgroups.Resources, pid int) error { - if r.SkipDevices { - return nil - } - if path == "" { - // Return error here, since devices cgroup - // is a hard requirement for container's security. - return errSubsystemDoesNotExist - } - - return apply(path, pid) -} - -func (s *DevicesGroup) Set(path string, r *cgroups.Resources) error { - if cgroups.DevicesSetV1 == nil { - if len(r.Devices) == 0 { - return nil - } - return cgroups.ErrDevicesUnsupported - } - return cgroups.DevicesSetV1(path, r) -} - -func (s *DevicesGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/error.go b/vendor/github.com/opencontainers/cgroups/fs/error.go deleted file mode 100644 index f13033e3d8b..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/error.go +++ /dev/null @@ -1,15 +0,0 @@ -package fs - -import ( - "fmt" - - "github.com/opencontainers/cgroups/fscommon" -) - -type parseError = fscommon.ParseError - -// malformedLine is used by all cgroupfs file parsers that expect a line -// in a particular format but get some garbage instead. -func malformedLine(path, file, line string) error { - return &parseError{Path: path, File: file, Err: fmt.Errorf("malformed line: %s", line)} -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/freezer.go b/vendor/github.com/opencontainers/cgroups/fs/freezer.go deleted file mode 100644 index fe0f0dde482..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/freezer.go +++ /dev/null @@ -1,157 +0,0 @@ -package fs - -import ( - "errors" - "fmt" - "os" - "strings" - "time" - - "github.com/opencontainers/cgroups" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" -) - -type FreezerGroup struct{} - -func (s *FreezerGroup) Name() string { - return "freezer" -} - -func (s *FreezerGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *FreezerGroup) Set(path string, r *cgroups.Resources) (Err error) { - switch r.Freezer { - case cgroups.Frozen: - defer func() { - if Err != nil { - // Freezing failed, and it is bad and dangerous - // to leave the cgroup in FROZEN or FREEZING - // state, so (try to) thaw it back. - _ = cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed)) - } - }() - - // As per older kernel docs (freezer-subsystem.txt before - // kernel commit ef9fe980c6fcc1821), if FREEZING is seen, - // userspace should either retry or thaw. While current - // kernel cgroup v1 docs no longer mention a need to retry, - // even a recent kernel (v5.4, Ubuntu 20.04) can't reliably - // freeze a cgroup v1 while new processes keep appearing in it - // (either via fork/clone or by writing new PIDs to - // cgroup.procs). - // - // The numbers below are empirically chosen to have a decent - // chance to succeed in various scenarios ("runc pause/unpause - // with parallel runc exec" and "bare freeze/unfreeze on a very - // slow system"), tested on RHEL7 and Ubuntu 20.04 kernels. - // - // Adding any amount of sleep in between retries did not - // increase the chances of successful freeze in "pause/unpause - // with parallel exec" reproducer. OTOH, adding an occasional - // sleep helped for the case where the system is extremely slow - // (CentOS 7 VM on GHA CI). - // - // Alas, this is still a game of chances, since the real fix - // belong to the kernel (cgroup v2 do not have this bug). - - for i := range 1000 { - if i%50 == 49 { - // Occasional thaw and sleep improves - // the chances to succeed in freezing - // in case new processes keep appearing - // in the cgroup. - _ = cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed)) - time.Sleep(10 * time.Millisecond) - } - - if err := cgroups.WriteFile(path, "freezer.state", string(cgroups.Frozen)); err != nil { - return err - } - - if i%25 == 24 { - // Occasional short sleep before reading - // the state back also improves the chances to - // succeed in freezing in case of a very slow - // system. - time.Sleep(10 * time.Microsecond) - } - state, err := cgroups.ReadFile(path, "freezer.state") - if err != nil { - return err - } - state = strings.TrimSpace(state) - switch state { - case "FREEZING": - continue - case string(cgroups.Frozen): - if i > 1 { - logrus.Debugf("frozen after %d retries", i) - } - return nil - default: - // should never happen - return fmt.Errorf("unexpected state %s while freezing", strings.TrimSpace(state)) - } - } - // Despite our best efforts, it got stuck in FREEZING. - return errors.New("unable to freeze") - case cgroups.Thawed: - return cgroups.WriteFile(path, "freezer.state", string(cgroups.Thawed)) - case cgroups.Undefined: - return nil - default: - return fmt.Errorf("Invalid argument '%s' to freezer.state", string(r.Freezer)) - } -} - -func (s *FreezerGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} - -func (s *FreezerGroup) GetState(path string) (cgroups.FreezerState, error) { - for { - state, err := cgroups.ReadFile(path, "freezer.state") - if err != nil { - // If the kernel is too old, then we just treat the freezer as - // being in an "undefined" state. - if os.IsNotExist(err) || errors.Is(err, unix.ENODEV) { - err = nil - } - return cgroups.Undefined, err - } - switch strings.TrimSpace(state) { - case "THAWED": - return cgroups.Thawed, nil - case "FROZEN": - // Find out whether the cgroup is frozen directly, - // or indirectly via an ancestor. - self, err := cgroups.ReadFile(path, "freezer.self_freezing") - if err != nil { - // If the kernel is too old, then we just treat - // it as being frozen. - if errors.Is(err, os.ErrNotExist) || errors.Is(err, unix.ENODEV) { - err = nil - } - return cgroups.Frozen, err - } - switch self { - case "0\n": - return cgroups.Thawed, nil - case "1\n": - return cgroups.Frozen, nil - default: - return cgroups.Undefined, fmt.Errorf(`unknown "freezer.self_freezing" state: %q`, self) - } - case "FREEZING": - // Make sure we get a stable freezer state, so retry if the cgroup - // is still undergoing freezing. This should be a temporary delay. - time.Sleep(1 * time.Millisecond) - continue - default: - return cgroups.Undefined, fmt.Errorf("unknown freezer.state %q", state) - } - } -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/fs.go b/vendor/github.com/opencontainers/cgroups/fs/fs.go deleted file mode 100644 index 625931193ec..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/fs.go +++ /dev/null @@ -1,294 +0,0 @@ -package fs - -import ( - "errors" - "fmt" - "os" - "path" - "strings" - "sync" - - "golang.org/x/sys/unix" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -var subsystems = []subsystem{ - &CpusetGroup{}, - &DevicesGroup{}, - &MemoryGroup{}, - &CpuGroup{}, - &CpuacctGroup{}, - &PidsGroup{}, - &BlkioGroup{}, - &HugetlbGroup{}, - &NetClsGroup{}, - &NetPrioGroup{}, - &PerfEventGroup{}, - &FreezerGroup{}, - &RdmaGroup{}, - &NameGroup{GroupName: "name=systemd", Join: true}, - &NameGroup{GroupName: "misc", Join: true}, -} - -var errSubsystemDoesNotExist = errors.New("cgroup: subsystem does not exist") - -func init() { - // If using cgroups-hybrid mode then add a "" controller indicating - // it should join the cgroups v2. - if cgroups.IsCgroup2HybridMode() { - subsystems = append(subsystems, &NameGroup{GroupName: "", Join: true}) - } -} - -type subsystem interface { - // Name returns the name of the subsystem. - Name() string - // GetStats fills in the stats for the subsystem. - GetStats(path string, stats *cgroups.Stats) error - // Apply creates and joins a cgroup, adding pid into it. Some - // subsystems use resources to pre-configure the cgroup parents - // before creating or joining it. - Apply(path string, r *cgroups.Resources, pid int) error - // Set sets the cgroup resources. - Set(path string, r *cgroups.Resources) error -} - -type Manager struct { - mu sync.Mutex - cgroups *cgroups.Cgroup - paths map[string]string -} - -func NewManager(cg *cgroups.Cgroup, paths map[string]string) (*Manager, error) { - // Some v1 controllers (cpu, cpuset, and devices) expect - // cgroups.Resources to not be nil in Apply. - if cg.Resources == nil { - return nil, errors.New("cgroup v1 manager needs cgroups.Resources to be set during manager creation") - } - if cg.Resources.Unified != nil { - return nil, cgroups.ErrV1NoUnified - } - - if paths == nil { - var err error - paths, err = initPaths(cg) - if err != nil { - return nil, err - } - } - - return &Manager{ - cgroups: cg, - paths: paths, - }, nil -} - -// isIgnorableError returns whether err is a permission error (in the loose -// sense of the word). This includes EROFS (which for an unprivileged user is -// basically a permission error) and EACCES (for similar reasons) as well as -// the normal EPERM. -func isIgnorableError(rootless bool, err error) bool { - // We do not ignore errors if we are root. - if !rootless { - return false - } - // Is it an ordinary EPERM? - if errors.Is(err, os.ErrPermission) { - return true - } - // Handle some specific syscall errors. - var errno unix.Errno - if errors.As(err, &errno) { - return errno == unix.EROFS || errno == unix.EPERM || errno == unix.EACCES - } - return false -} - -func (m *Manager) Apply(pid int) (retErr error) { - m.mu.Lock() - defer m.mu.Unlock() - - c := m.cgroups - - for _, sys := range subsystems { - name := sys.Name() - p, ok := m.paths[name] - if !ok { - continue - } - - if err := sys.Apply(p, c.Resources, pid); err != nil { - // In the case of rootless (including euid=0 in userns), where an - // explicit cgroup path hasn't been set, we don't bail on error in - // case of permission problems here, but do delete the path from - // the m.paths map, since it is either non-existent and could not - // be created, or the pid could not be added to it. - // - // Cases where limits for the subsystem have been set are handled - // later by Set, which fails with a friendly error (see - // if path == "" in Set). - if isIgnorableError(c.Rootless, err) && c.Path == "" { - retErr = cgroups.ErrRootless - delete(m.paths, name) - continue - } - return err - } - - } - return retErr -} - -// AddPid adds a process with a given pid to an existing cgroup. -// The subcgroup argument is either empty, or a path relative to -// a cgroup under under the manager's cgroup. -func (m *Manager) AddPid(subcgroup string, pid int) (retErr error) { - m.mu.Lock() - defer m.mu.Unlock() - - c := m.cgroups - - for _, dir := range m.paths { - path := path.Join(dir, subcgroup) - if !strings.HasPrefix(path, dir) { - return fmt.Errorf("bad sub cgroup path: %s", subcgroup) - } - - if err := cgroups.WriteCgroupProc(path, pid); err != nil { - if isIgnorableError(c.Rootless, err) && c.Path == "" { - retErr = cgroups.ErrRootless - continue - } - return err - } - } - - return retErr -} - -func (m *Manager) Destroy() error { - m.mu.Lock() - defer m.mu.Unlock() - return cgroups.RemovePaths(m.paths) -} - -func (m *Manager) Path(subsys string) string { - m.mu.Lock() - defer m.mu.Unlock() - return m.paths[subsys] -} - -func (m *Manager) GetStats() (*cgroups.Stats, error) { - m.mu.Lock() - defer m.mu.Unlock() - stats := cgroups.NewStats() - for _, sys := range subsystems { - path := m.paths[sys.Name()] - if path == "" { - continue - } - if err := sys.GetStats(path, stats); err != nil { - return nil, err - } - } - return stats, nil -} - -func (m *Manager) Set(r *cgroups.Resources) error { - if r == nil { - return nil - } - - if r.Unified != nil { - return cgroups.ErrV1NoUnified - } - - m.mu.Lock() - defer m.mu.Unlock() - for _, sys := range subsystems { - path := m.paths[sys.Name()] - if err := sys.Set(path, r); err != nil { - // When rootless is true, errors from the device subsystem - // are ignored, as it is really not expected to work. - if m.cgroups.Rootless && sys.Name() == "devices" && !errors.Is(err, cgroups.ErrDevicesUnsupported) { - continue - } - // However, errors from other subsystems are not ignored. - // see @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error" - if path == "" { - // We never created a path for this cgroup, so we cannot set - // limits for it (though we have already tried at this point). - return fmt.Errorf("cannot set %s limit: container could not join or create cgroup", sys.Name()) - } - return err - } - } - - return nil -} - -// Freeze toggles the container's freezer cgroup depending on the state -// provided -func (m *Manager) Freeze(state cgroups.FreezerState) error { - path := m.Path("freezer") - if path == "" { - return errors.New("cannot toggle freezer: cgroups not configured for container") - } - - prevState := m.cgroups.Resources.Freezer - m.cgroups.Resources.Freezer = state - freezer := &FreezerGroup{} - if err := freezer.Set(path, m.cgroups.Resources); err != nil { - m.cgroups.Resources.Freezer = prevState - return err - } - return nil -} - -func (m *Manager) GetPids() ([]int, error) { - return cgroups.GetPids(m.Path("devices")) -} - -func (m *Manager) GetAllPids() ([]int, error) { - return cgroups.GetAllPids(m.Path("devices")) -} - -func (m *Manager) GetPaths() map[string]string { - m.mu.Lock() - defer m.mu.Unlock() - return m.paths -} - -func (m *Manager) GetCgroups() (*cgroups.Cgroup, error) { - return m.cgroups, nil -} - -func (m *Manager) GetFreezerState() (cgroups.FreezerState, error) { - dir := m.Path("freezer") - // If the container doesn't have the freezer cgroup, say it's undefined. - if dir == "" { - return cgroups.Undefined, nil - } - freezer := &FreezerGroup{} - return freezer.GetState(dir) -} - -func (m *Manager) Exists() bool { - return cgroups.PathExists(m.Path("devices")) -} - -func OOMKillCount(path string) (uint64, error) { - return fscommon.GetValueByKey(path, "memory.oom_control", "oom_kill") -} - -func (m *Manager) OOMKillCount() (uint64, error) { - c, err := OOMKillCount(m.Path("memory")) - // Ignore ENOENT when rootless as it couldn't create cgroup. - if err != nil && m.cgroups.Rootless && os.IsNotExist(err) { - err = nil - } - - return c, err -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/hugetlb.go b/vendor/github.com/opencontainers/cgroups/fs/hugetlb.go deleted file mode 100644 index 698fd691e10..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/hugetlb.go +++ /dev/null @@ -1,83 +0,0 @@ -package fs - -import ( - "errors" - "os" - "strconv" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -type HugetlbGroup struct{} - -func (s *HugetlbGroup) Name() string { - return "hugetlb" -} - -func (s *HugetlbGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *HugetlbGroup) Set(path string, r *cgroups.Resources) error { - const suffix = ".limit_in_bytes" - skipRsvd := false - - for _, hugetlb := range r.HugetlbLimit { - prefix := "hugetlb." + hugetlb.Pagesize - val := strconv.FormatUint(hugetlb.Limit, 10) - if err := cgroups.WriteFile(path, prefix+suffix, val); err != nil { - return err - } - if skipRsvd { - continue - } - if err := cgroups.WriteFile(path, prefix+".rsvd"+suffix, val); err != nil { - if errors.Is(err, os.ErrNotExist) { - skipRsvd = true - continue - } - return err - } - } - - return nil -} - -func (s *HugetlbGroup) GetStats(path string, stats *cgroups.Stats) error { - if !cgroups.PathExists(path) { - return nil - } - rsvd := ".rsvd" - hugetlbStats := cgroups.HugetlbStats{} - for _, pageSize := range cgroups.HugePageSizes() { - again: - prefix := "hugetlb." + pageSize + rsvd - - value, err := fscommon.GetCgroupParamUint(path, prefix+".usage_in_bytes") - if err != nil { - if rsvd != "" && errors.Is(err, os.ErrNotExist) { - rsvd = "" - goto again - } - return err - } - hugetlbStats.Usage = value - - value, err = fscommon.GetCgroupParamUint(path, prefix+".max_usage_in_bytes") - if err != nil { - return err - } - hugetlbStats.MaxUsage = value - - value, err = fscommon.GetCgroupParamUint(path, prefix+".failcnt") - if err != nil { - return err - } - hugetlbStats.Failcnt = value - - stats.HugetlbStats[pageSize] = hugetlbStats - } - - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/memory.go b/vendor/github.com/opencontainers/cgroups/fs/memory.go deleted file mode 100644 index d92f2322beb..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/memory.go +++ /dev/null @@ -1,356 +0,0 @@ -package fs - -import ( - "bufio" - "errors" - "fmt" - "math" - "os" - "path/filepath" - "strconv" - "strings" - - "golang.org/x/sys/unix" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -const ( - cgroupMemorySwapLimit = "memory.memsw.limit_in_bytes" - cgroupMemoryLimit = "memory.limit_in_bytes" - cgroupMemoryUsage = "memory.usage_in_bytes" - cgroupMemoryMaxUsage = "memory.max_usage_in_bytes" -) - -type MemoryGroup struct{} - -func (s *MemoryGroup) Name() string { - return "memory" -} - -func (s *MemoryGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func setMemory(path string, val int64) error { - if val == 0 { - return nil - } - - err := cgroups.WriteFile(path, cgroupMemoryLimit, strconv.FormatInt(val, 10)) - if !errors.Is(err, unix.EBUSY) { - return err - } - - // EBUSY means the kernel can't set new limit as it's too low - // (lower than the current usage). Return more specific error. - usage, err := fscommon.GetCgroupParamUint(path, cgroupMemoryUsage) - if err != nil { - return err - } - max, err := fscommon.GetCgroupParamUint(path, cgroupMemoryMaxUsage) - if err != nil { - return err - } - - return fmt.Errorf("unable to set memory limit to %d (current usage: %d, peak usage: %d)", val, usage, max) -} - -func setSwap(path string, val int64) error { - if val == 0 { - return nil - } - - return cgroups.WriteFile(path, cgroupMemorySwapLimit, strconv.FormatInt(val, 10)) -} - -func setMemoryAndSwap(path string, r *cgroups.Resources) error { - // If the memory update is set to -1 and the swap is not explicitly - // set, we should also set swap to -1, it means unlimited memory. - if r.Memory == -1 && r.MemorySwap == 0 { - // Only set swap if it's enabled in kernel - if cgroups.PathExists(filepath.Join(path, cgroupMemorySwapLimit)) { - r.MemorySwap = -1 - } - } - - // When memory and swap memory are both set, we need to handle the cases - // for updating container. - if r.Memory != 0 && r.MemorySwap != 0 { - curLimit, err := fscommon.GetCgroupParamUint(path, cgroupMemoryLimit) - if err != nil { - return err - } - - // When update memory limit, we should adapt the write sequence - // for memory and swap memory, so it won't fail because the new - // value and the old value don't fit kernel's validation. - if r.MemorySwap == -1 || curLimit < uint64(r.MemorySwap) { - if err := setSwap(path, r.MemorySwap); err != nil { - return err - } - if err := setMemory(path, r.Memory); err != nil { - return err - } - return nil - } - } - - if err := setMemory(path, r.Memory); err != nil { - return err - } - if err := setSwap(path, r.MemorySwap); err != nil { - return err - } - - return nil -} - -func (s *MemoryGroup) Set(path string, r *cgroups.Resources) error { - if err := setMemoryAndSwap(path, r); err != nil { - return err - } - - // ignore KernelMemory and KernelMemoryTCP - - if r.MemoryReservation != 0 { - if err := cgroups.WriteFile(path, "memory.soft_limit_in_bytes", strconv.FormatInt(r.MemoryReservation, 10)); err != nil { - return err - } - } - - if r.OomKillDisable { - if err := cgroups.WriteFile(path, "memory.oom_control", "1"); err != nil { - return err - } - } - if r.MemorySwappiness == nil || int64(*r.MemorySwappiness) == -1 { - return nil - } else if *r.MemorySwappiness <= 100 { - if err := cgroups.WriteFile(path, "memory.swappiness", strconv.FormatUint(*r.MemorySwappiness, 10)); err != nil { - return err - } - } else { - return fmt.Errorf("invalid memory swappiness value: %d (valid range is 0-100)", *r.MemorySwappiness) - } - - return nil -} - -func (s *MemoryGroup) GetStats(path string, stats *cgroups.Stats) error { - const file = "memory.stat" - statsFile, err := cgroups.OpenFile(path, file, os.O_RDONLY) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - defer statsFile.Close() - - sc := bufio.NewScanner(statsFile) - for sc.Scan() { - t, v, err := fscommon.ParseKeyValue(sc.Text()) - if err != nil { - return &parseError{Path: path, File: file, Err: err} - } - stats.MemoryStats.Stats[t] = v - } - stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"] - - memoryUsage, err := getMemoryData(path, "") - if err != nil { - return err - } - stats.MemoryStats.Usage = memoryUsage - swapUsage, err := getMemoryData(path, "memsw") - if err != nil { - return err - } - stats.MemoryStats.SwapUsage = swapUsage - stats.MemoryStats.SwapOnlyUsage = cgroups.MemoryData{ - Usage: swapUsage.Usage - memoryUsage.Usage, - Failcnt: swapUsage.Failcnt - memoryUsage.Failcnt, - } - kernelUsage, err := getMemoryData(path, "kmem") - if err != nil { - return err - } - stats.MemoryStats.KernelUsage = kernelUsage - kernelTCPUsage, err := getMemoryData(path, "kmem.tcp") - if err != nil { - return err - } - stats.MemoryStats.KernelTCPUsage = kernelTCPUsage - - value, err := fscommon.GetCgroupParamUint(path, "memory.use_hierarchy") - if err != nil { - return err - } - if value == 1 { - stats.MemoryStats.UseHierarchy = true - } - - pagesByNUMA, err := getPageUsageByNUMA(path) - if err != nil { - return err - } - stats.MemoryStats.PageUsageByNUMA = pagesByNUMA - - return nil -} - -func getMemoryData(path, name string) (cgroups.MemoryData, error) { - memoryData := cgroups.MemoryData{} - - moduleName := "memory" - if name != "" { - moduleName = "memory." + name - } - var ( - usage = moduleName + ".usage_in_bytes" - maxUsage = moduleName + ".max_usage_in_bytes" - failcnt = moduleName + ".failcnt" - limit = moduleName + ".limit_in_bytes" - ) - - value, err := fscommon.GetCgroupParamUint(path, usage) - if err != nil { - if name != "" && os.IsNotExist(err) { - // Ignore ENOENT as swap and kmem controllers - // are optional in the kernel. - return cgroups.MemoryData{}, nil - } - return cgroups.MemoryData{}, err - } - memoryData.Usage = value - value, err = fscommon.GetCgroupParamUint(path, maxUsage) - if err != nil { - return cgroups.MemoryData{}, err - } - memoryData.MaxUsage = value - value, err = fscommon.GetCgroupParamUint(path, failcnt) - if err != nil { - return cgroups.MemoryData{}, err - } - memoryData.Failcnt = value - value, err = fscommon.GetCgroupParamUint(path, limit) - if err != nil { - if name == "kmem" && os.IsNotExist(err) { - // Ignore ENOENT as kmem.limit_in_bytes has - // been removed in newer kernels. - return memoryData, nil - } - - return cgroups.MemoryData{}, err - } - memoryData.Limit = value - - return memoryData, nil -} - -func getPageUsageByNUMA(path string) (cgroups.PageUsageByNUMA, error) { - const ( - maxColumns = math.MaxUint8 + 1 - file = "memory.numa_stat" - ) - stats := cgroups.PageUsageByNUMA{} - - fd, err := cgroups.OpenFile(path, file, os.O_RDONLY) - if os.IsNotExist(err) { - return stats, nil - } else if err != nil { - return stats, err - } - defer fd.Close() - - // File format is documented in linux/Documentation/cgroup-v1/memory.txt - // and it looks like this: - // - // total= N0= N1= ... - // file= N0= N1= ... - // anon= N0= N1= ... - // unevictable= N0= N1= ... - // hierarchical_= N0= N1= ... - - scanner := bufio.NewScanner(fd) - for scanner.Scan() { - var field *cgroups.PageStats - - line := scanner.Text() - columns := strings.SplitN(line, " ", maxColumns) - for i, column := range columns { - key, val, ok := strings.Cut(column, "=") - // Some custom kernels have non-standard fields, like - // numa_locality 0 0 0 0 0 0 0 0 0 0 - // numa_exectime 0 - if !ok { - if i == 0 { - // Ignore/skip those. - break - } else { - // The first column was already validated, - // so be strict to the rest. - return stats, malformedLine(path, file, line) - } - } - if i == 0 { // First column: key is name, val is total. - field = getNUMAField(&stats, key) - if field == nil { // unknown field (new kernel?) - break - } - field.Total, err = strconv.ParseUint(val, 0, 64) - if err != nil { - return stats, &parseError{Path: path, File: file, Err: err} - } - field.Nodes = map[uint8]uint64{} - } else { // Subsequent columns: key is N, val is usage. - if len(key) < 2 || key[0] != 'N' { - // This is definitely an error. - return stats, malformedLine(path, file, line) - } - - n, err := strconv.ParseUint(key[1:], 10, 8) - if err != nil { - return stats, &parseError{Path: path, File: file, Err: err} - } - - usage, err := strconv.ParseUint(val, 10, 64) - if err != nil { - return stats, &parseError{Path: path, File: file, Err: err} - } - - field.Nodes[uint8(n)] = usage - } - - } - } - if err := scanner.Err(); err != nil { - return cgroups.PageUsageByNUMA{}, &parseError{Path: path, File: file, Err: err} - } - - return stats, nil -} - -func getNUMAField(stats *cgroups.PageUsageByNUMA, name string) *cgroups.PageStats { - switch name { - case "total": - return &stats.Total - case "file": - return &stats.File - case "anon": - return &stats.Anon - case "unevictable": - return &stats.Unevictable - case "hierarchical_total": - return &stats.Hierarchical.Total - case "hierarchical_file": - return &stats.Hierarchical.File - case "hierarchical_anon": - return &stats.Hierarchical.Anon - case "hierarchical_unevictable": - return &stats.Hierarchical.Unevictable - } - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/name.go b/vendor/github.com/opencontainers/cgroups/fs/name.go deleted file mode 100644 index 28643519b58..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/name.go +++ /dev/null @@ -1,30 +0,0 @@ -package fs - -import ( - "github.com/opencontainers/cgroups" -) - -type NameGroup struct { - GroupName string - Join bool -} - -func (s *NameGroup) Name() string { - return s.GroupName -} - -func (s *NameGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - if s.Join { - // Ignore errors if the named cgroup does not exist. - _ = apply(path, pid) - } - return nil -} - -func (s *NameGroup) Set(_ string, _ *cgroups.Resources) error { - return nil -} - -func (s *NameGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/net_cls.go b/vendor/github.com/opencontainers/cgroups/fs/net_cls.go deleted file mode 100644 index 2bd6c5ab218..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/net_cls.go +++ /dev/null @@ -1,31 +0,0 @@ -package fs - -import ( - "strconv" - - "github.com/opencontainers/cgroups" -) - -type NetClsGroup struct{} - -func (s *NetClsGroup) Name() string { - return "net_cls" -} - -func (s *NetClsGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *NetClsGroup) Set(path string, r *cgroups.Resources) error { - if r.NetClsClassid != 0 { - if err := cgroups.WriteFile(path, "net_cls.classid", strconv.FormatUint(uint64(r.NetClsClassid), 10)); err != nil { - return err - } - } - - return nil -} - -func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/net_prio.go b/vendor/github.com/opencontainers/cgroups/fs/net_prio.go deleted file mode 100644 index b51682b6da0..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/net_prio.go +++ /dev/null @@ -1,29 +0,0 @@ -package fs - -import ( - "github.com/opencontainers/cgroups" -) - -type NetPrioGroup struct{} - -func (s *NetPrioGroup) Name() string { - return "net_prio" -} - -func (s *NetPrioGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *NetPrioGroup) Set(path string, r *cgroups.Resources) error { - for _, prioMap := range r.NetPrioIfpriomap { - if err := cgroups.WriteFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil { - return err - } - } - - return nil -} - -func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/paths.go b/vendor/github.com/opencontainers/cgroups/fs/paths.go deleted file mode 100644 index edbe041ea8d..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/paths.go +++ /dev/null @@ -1,169 +0,0 @@ -package fs - -import ( - "errors" - "os" - "path/filepath" - "sync" - - "golang.org/x/sys/unix" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/internal/path" -) - -// The absolute path to the root of the cgroup hierarchies. -var ( - cgroupRootLock sync.Mutex - cgroupRoot string -) - -const defaultCgroupRoot = "/sys/fs/cgroup" - -func initPaths(cg *cgroups.Cgroup) (map[string]string, error) { - root, err := rootPath() - if err != nil { - return nil, err - } - - inner, err := path.Inner(cg) - if err != nil { - return nil, err - } - - paths := make(map[string]string) - for _, sys := range subsystems { - name := sys.Name() - path, err := subsysPath(root, inner, name) - if err != nil { - // The non-presence of the devices subsystem - // is considered fatal for security reasons. - if cgroups.IsNotFound(err) && (cg.SkipDevices || name != "devices") { - continue - } - - return nil, err - } - paths[name] = path - } - - return paths, nil -} - -func tryDefaultCgroupRoot() string { - var st, pst unix.Stat_t - - // (1) it should be a directory... - err := unix.Lstat(defaultCgroupRoot, &st) - if err != nil || st.Mode&unix.S_IFDIR == 0 { - return "" - } - - // (2) ... and a mount point ... - err = unix.Lstat(filepath.Dir(defaultCgroupRoot), &pst) - if err != nil { - return "" - } - - if st.Dev == pst.Dev { - // parent dir has the same dev -- not a mount point - return "" - } - - // (3) ... of 'tmpfs' fs type. - var fst unix.Statfs_t - err = unix.Statfs(defaultCgroupRoot, &fst) - if err != nil || fst.Type != unix.TMPFS_MAGIC { - return "" - } - - // (4) it should have at least 1 entry ... - dir, err := os.Open(defaultCgroupRoot) - if err != nil { - return "" - } - defer dir.Close() - names, err := dir.Readdirnames(1) - if err != nil { - return "" - } - if len(names) < 1 { - return "" - } - // ... which is a cgroup mount point. - err = unix.Statfs(filepath.Join(defaultCgroupRoot, names[0]), &fst) - if err != nil || fst.Type != unix.CGROUP_SUPER_MAGIC { - return "" - } - - return defaultCgroupRoot -} - -// rootPath finds and returns path to the root of the cgroup hierarchies. -func rootPath() (string, error) { - cgroupRootLock.Lock() - defer cgroupRootLock.Unlock() - - if cgroupRoot != "" { - return cgroupRoot, nil - } - - // fast path - cgroupRoot = tryDefaultCgroupRoot() - if cgroupRoot != "" { - return cgroupRoot, nil - } - - // slow path: parse mountinfo - mi, err := cgroups.GetCgroupMounts(false) - if err != nil { - return "", err - } - if len(mi) < 1 { - return "", errors.New("no cgroup mount found in mountinfo") - } - - // Get the first cgroup mount (e.g. "/sys/fs/cgroup/memory"), - // use its parent directory. - root := filepath.Dir(mi[0].Mountpoint) - - if _, err := os.Stat(root); err != nil { - return "", err - } - - cgroupRoot = root - return cgroupRoot, nil -} - -func subsysPath(root, inner, subsystem string) (string, error) { - // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. - if filepath.IsAbs(inner) { - mnt, err := cgroups.FindCgroupMountpoint(root, subsystem) - // If we didn't mount the subsystem, there is no point we make the path. - if err != nil { - return "", err - } - - // Sometimes subsystems can be mounted together as 'cpu,cpuacct'. - return filepath.Join(root, filepath.Base(mnt), inner), nil - } - - // Use GetOwnCgroupPath for dind-like cases, when cgroupns is not - // available. This is ugly. - parentPath, err := cgroups.GetOwnCgroupPath(subsystem) - if err != nil { - return "", err - } - - return filepath.Join(parentPath, inner), nil -} - -func apply(path string, pid int) error { - if path == "" { - return nil - } - if err := os.MkdirAll(path, 0o755); err != nil { - return err - } - return cgroups.WriteCgroupProc(path, pid) -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/perf_event.go b/vendor/github.com/opencontainers/cgroups/fs/perf_event.go deleted file mode 100644 index 929c412a3a7..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/perf_event.go +++ /dev/null @@ -1,23 +0,0 @@ -package fs - -import ( - "github.com/opencontainers/cgroups" -) - -type PerfEventGroup struct{} - -func (s *PerfEventGroup) Name() string { - return "perf_event" -} - -func (s *PerfEventGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *PerfEventGroup) Set(_ string, _ *cgroups.Resources) error { - return nil -} - -func (s *PerfEventGroup) GetStats(path string, stats *cgroups.Stats) error { - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/pids.go b/vendor/github.com/opencontainers/cgroups/fs/pids.go deleted file mode 100644 index 36bd339af82..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/pids.go +++ /dev/null @@ -1,66 +0,0 @@ -package fs - -import ( - "math" - "strconv" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -type PidsGroup struct{} - -func (s *PidsGroup) Name() string { - return "pids" -} - -func (s *PidsGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *PidsGroup) Set(path string, r *cgroups.Resources) error { - if r.PidsLimit == nil { - return nil - } - - // "max" is the fallback value. - val := "max" - if limit := *r.PidsLimit; limit > 0 { - val = strconv.FormatInt(limit, 10) - } else if limit == 0 { - // systemd doesn't support setting pids.max to "0", so when setting - // TasksMax we need to remap it to "1". We do the same thing here to - // avoid flip-flop behaviour between the fs and systemd drivers. In - // practice, the pids cgroup behaviour is basically identical. - val = "1" - } - if err := cgroups.WriteFile(path, "pids.max", val); err != nil { - return err - } - return nil -} - -func (s *PidsGroup) GetStats(path string, stats *cgroups.Stats) error { - if !cgroups.PathExists(path) { - return nil - } - current, err := fscommon.GetCgroupParamUint(path, "pids.current") - if err != nil { - return err - } - - max, err := fscommon.GetCgroupParamUint(path, "pids.max") - if err != nil { - return err - } - // If no limit is set, read from pids.max returns "max", which is - // converted to MaxUint64 by GetCgroupParamUint. Historically, we - // represent "no limit" for pids as 0, thus this conversion. - if max == math.MaxUint64 { - max = 0 - } - - stats.PidsStats.Current = current - stats.PidsStats.Limit = max - return nil -} diff --git a/vendor/github.com/opencontainers/cgroups/fs/rdma.go b/vendor/github.com/opencontainers/cgroups/fs/rdma.go deleted file mode 100644 index 4b175365f27..00000000000 --- a/vendor/github.com/opencontainers/cgroups/fs/rdma.go +++ /dev/null @@ -1,24 +0,0 @@ -package fs - -import ( - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fscommon" -) - -type RdmaGroup struct{} - -func (s *RdmaGroup) Name() string { - return "rdma" -} - -func (s *RdmaGroup) Apply(path string, _ *cgroups.Resources, pid int) error { - return apply(path, pid) -} - -func (s *RdmaGroup) Set(path string, r *cgroups.Resources) error { - return fscommon.RdmaSet(path, r) -} - -func (s *RdmaGroup) GetStats(path string, stats *cgroups.Stats) error { - return fscommon.RdmaGetStats(path, stats) -} diff --git a/vendor/github.com/pkg/browser/LICENSE b/vendor/github.com/pkg/browser/LICENSE new file mode 100644 index 00000000000..65f78fb6291 --- /dev/null +++ b/vendor/github.com/pkg/browser/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2014, Dave Cheney +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pkg/browser/README.md b/vendor/github.com/pkg/browser/README.md new file mode 100644 index 00000000000..72b1976e303 --- /dev/null +++ b/vendor/github.com/pkg/browser/README.md @@ -0,0 +1,55 @@ + +# browser + import "github.com/pkg/browser" + +Package browser provides helpers to open files, readers, and urls in a browser window. + +The choice of which browser is started is entirely client dependant. + + + + + +## Variables +``` go +var Stderr io.Writer = os.Stderr +``` +Stderr is the io.Writer to which executed commands write standard error. + +``` go +var Stdout io.Writer = os.Stdout +``` +Stdout is the io.Writer to which executed commands write standard output. + + +## func OpenFile +``` go +func OpenFile(path string) error +``` +OpenFile opens new browser window for the file path. + + +## func OpenReader +``` go +func OpenReader(r io.Reader) error +``` +OpenReader consumes the contents of r and presents the +results in a new browser window. + + +## func OpenURL +``` go +func OpenURL(url string) error +``` +OpenURL opens a new browser window pointing to url. + + + + + + + + + +- - - +Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md) diff --git a/vendor/github.com/pkg/browser/browser.go b/vendor/github.com/pkg/browser/browser.go new file mode 100644 index 00000000000..d7969d74d80 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser.go @@ -0,0 +1,57 @@ +// Package browser provides helpers to open files, readers, and urls in a browser window. +// +// The choice of which browser is started is entirely client dependant. +package browser + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "path/filepath" +) + +// Stdout is the io.Writer to which executed commands write standard output. +var Stdout io.Writer = os.Stdout + +// Stderr is the io.Writer to which executed commands write standard error. +var Stderr io.Writer = os.Stderr + +// OpenFile opens new browser window for the file path. +func OpenFile(path string) error { + path, err := filepath.Abs(path) + if err != nil { + return err + } + return OpenURL("file://" + path) +} + +// OpenReader consumes the contents of r and presents the +// results in a new browser window. +func OpenReader(r io.Reader) error { + f, err := ioutil.TempFile("", "browser.*.html") + if err != nil { + return fmt.Errorf("browser: could not create temporary file: %v", err) + } + if _, err := io.Copy(f, r); err != nil { + f.Close() + return fmt.Errorf("browser: caching temporary file failed: %v", err) + } + if err := f.Close(); err != nil { + return fmt.Errorf("browser: caching temporary file failed: %v", err) + } + return OpenFile(f.Name()) +} + +// OpenURL opens a new browser window pointing to url. +func OpenURL(url string) error { + return openBrowser(url) +} + +func runCmd(prog string, args ...string) error { + cmd := exec.Command(prog, args...) + cmd.Stdout = Stdout + cmd.Stderr = Stderr + return cmd.Run() +} diff --git a/vendor/github.com/pkg/browser/browser_darwin.go b/vendor/github.com/pkg/browser/browser_darwin.go new file mode 100644 index 00000000000..8507cf7c2b4 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_darwin.go @@ -0,0 +1,5 @@ +package browser + +func openBrowser(url string) error { + return runCmd("open", url) +} diff --git a/vendor/github.com/pkg/browser/browser_freebsd.go b/vendor/github.com/pkg/browser/browser_freebsd.go new file mode 100644 index 00000000000..4fc7ff0761b --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_freebsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_linux.go b/vendor/github.com/pkg/browser/browser_linux.go new file mode 100644 index 00000000000..d26cdddf9c1 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_linux.go @@ -0,0 +1,21 @@ +package browser + +import ( + "os/exec" + "strings" +) + +func openBrowser(url string) error { + providers := []string{"xdg-open", "x-www-browser", "www-browser"} + + // There are multiple possible providers to open a browser on linux + // One of them is xdg-open, another is x-www-browser, then there's www-browser, etc. + // Look for one that exists and run it + for _, provider := range providers { + if _, err := exec.LookPath(provider); err == nil { + return runCmd(provider, url) + } + } + + return &exec.Error{Name: strings.Join(providers, ","), Err: exec.ErrNotFound} +} diff --git a/vendor/github.com/pkg/browser/browser_netbsd.go b/vendor/github.com/pkg/browser/browser_netbsd.go new file mode 100644 index 00000000000..65a5e5a2934 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_netbsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from pkgsrc(7)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_openbsd.go b/vendor/github.com/pkg/browser/browser_openbsd.go new file mode 100644 index 00000000000..4fc7ff0761b --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_openbsd.go @@ -0,0 +1,14 @@ +package browser + +import ( + "errors" + "os/exec" +) + +func openBrowser(url string) error { + err := runCmd("xdg-open", url) + if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound { + return errors.New("xdg-open: command not found - install xdg-utils from ports(8)") + } + return err +} diff --git a/vendor/github.com/pkg/browser/browser_unsupported.go b/vendor/github.com/pkg/browser/browser_unsupported.go new file mode 100644 index 00000000000..7c5c17d34d2 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_unsupported.go @@ -0,0 +1,12 @@ +// +build !linux,!windows,!darwin,!openbsd,!freebsd,!netbsd + +package browser + +import ( + "fmt" + "runtime" +) + +func openBrowser(url string) error { + return fmt.Errorf("openBrowser: unsupported operating system: %v", runtime.GOOS) +} diff --git a/vendor/github.com/pkg/browser/browser_windows.go b/vendor/github.com/pkg/browser/browser_windows.go new file mode 100644 index 00000000000..63e192959a5 --- /dev/null +++ b/vendor/github.com/pkg/browser/browser_windows.go @@ -0,0 +1,7 @@ +package browser + +import "golang.org/x/sys/windows" + +func openBrowser(url string) error { + return windows.ShellExecute(0, nil, windows.StringToUTF16Ptr(url), nil, nil, windows.SW_SHOWNORMAL) +} diff --git a/vendor/github.com/proglottis/gpgme/data.go b/vendor/github.com/proglottis/gpgme/data.go index 0e81c36d662..bbbe86a5a94 100644 --- a/vendor/github.com/proglottis/gpgme/data.go +++ b/vendor/github.com/proglottis/gpgme/data.go @@ -156,31 +156,38 @@ func (d *Data) Close() error { if d.cbc > 0 { d.cbc.Delete() } - _, err := C.gpgme_data_release(d.dh) + C.gpgme_data_release(d.dh) runtime.KeepAlive(d) d.dh = nil - return err + return nil } func (d *Data) Write(p []byte) (int, error) { - var buffer *byte - if len(p) > 0 { - buffer = &p[0] + total := 0 + for total < len(p) { + remaining := p[total:] + + var buffer *byte + if len(remaining) > 0 { + buffer = &remaining[0] + } + + n, err := C.gpgme_data_write(d.dh, unsafe.Pointer(buffer), C.size_t(len(remaining))) + runtime.KeepAlive(d) + switch { + case d.err != nil: + defer func() { d.err = nil }() + return total, d.err + case n < 0: + return total, err + case n == 0: // This should never happen, but ensure we don’t loop forever + // If we got here, we know len(p) > 0, so ErrShortWrite is appropriate. + return total, io.ErrShortWrite + } + + total += int(n) } - - n, err := C.gpgme_data_write(d.dh, unsafe.Pointer(buffer), C.size_t(len(p))) - runtime.KeepAlive(d) - switch { - case d.err != nil: - defer func() { d.err = nil }() - - return 0, d.err - case err != nil: - return 0, err - case len(p) > 0 && n == 0: - return 0, io.EOF - } - return int(n), nil + return total, nil } func (d *Data) Read(p []byte) (int, error) { @@ -196,7 +203,7 @@ func (d *Data) Read(p []byte) (int, error) { defer func() { d.err = nil }() return 0, d.err - case err != nil: + case n < 0: return 0, err case len(p) > 0 && n == 0: return 0, io.EOF @@ -212,7 +219,7 @@ func (d *Data) Seek(offset int64, whence int) (int64, error) { defer func() { d.err = nil }() return 0, d.err - case err != nil: + case n < 0: return 0, err } return int64(n), nil diff --git a/vendor/github.com/proglottis/gpgme/gpgme.go b/vendor/github.com/proglottis/gpgme/gpgme.go index 62a095c1289..6e8d04c62ad 100644 --- a/vendor/github.com/proglottis/gpgme/gpgme.go +++ b/vendor/github.com/proglottis/gpgme/gpgme.go @@ -144,7 +144,16 @@ func (e Error) Code() ErrorCode { } func (e Error) Error() string { - return C.GoString(C.gpgme_strerror(e.err)) + // gpgme_error_t, aka gpg_error_t, is a single 32-bit integer, so it does not include + // strings of arbitrary length + // (compare https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgpg-error.git;a=blob;f=src/err-codes.h.in;hb=HEAD ). + // + // So, a medium-size hard-coded buffer is sufficient. + var buf [1024]C.char + _ = C.gpgme_strerror_r(e.err, &buf[0], C.size_t(len(buf))) + buf[len(buf)-1] = 0 // If gpgme_strerror_r returns ERANGE, the buffer is not guaranteed to be null-terminated + + return C.GoString(&buf[0]) } func handleError(err C.gpgme_error_t) error { @@ -377,20 +386,19 @@ func (c *Context) PinEntryMode() PinEntryMode { } func (c *Context) SetCallback(callback Callback) error { - var err error c.callback = callback if c.cbc > 0 { c.cbc.Delete() } if callback != nil { c.cbc = cgo.NewHandle(c) - _, err = C.gpgme_set_passphrase_cb(c.ctx, C.gpgme_passphrase_cb_t(C.gogpgme_passfunc), unsafe.Pointer(&c.cbc)) + C.gpgme_set_passphrase_cb(c.ctx, C.gpgme_passphrase_cb_t(C.gogpgme_passfunc), unsafe.Pointer(&c.cbc)) } else { c.cbc = 0 - _, err = C.gpgme_set_passphrase_cb(c.ctx, nil, nil) + C.gpgme_set_passphrase_cb(c.ctx, nil, nil) } runtime.KeepAlive(c) - return err + return nil } func (c *Context) EngineInfo() *EngineInfo { diff --git a/vendor/github.com/segmentio/ksuid/.gitignore b/vendor/github.com/segmentio/ksuid/.gitignore deleted file mode 100644 index 4b7a3f38b35..00000000000 --- a/vendor/github.com/segmentio/ksuid/.gitignore +++ /dev/null @@ -1,31 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof -/ksuid - -# Emacs -*~ - -# govendor -/vendor/*/ diff --git a/vendor/github.com/segmentio/ksuid/LICENSE.md b/vendor/github.com/segmentio/ksuid/LICENSE.md deleted file mode 100644 index aefb7931894..00000000000 --- a/vendor/github.com/segmentio/ksuid/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Segment.io - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/segmentio/ksuid/README.md b/vendor/github.com/segmentio/ksuid/README.md deleted file mode 100644 index b23e1a6e5c3..00000000000 --- a/vendor/github.com/segmentio/ksuid/README.md +++ /dev/null @@ -1,234 +0,0 @@ -# ksuid [![Go Report Card](https://goreportcard.com/badge/github.com/segmentio/ksuid)](https://goreportcard.com/report/github.com/segmentio/ksuid) [![GoDoc](https://godoc.org/github.com/segmentio/ksuid?status.svg)](https://godoc.org/github.com/segmentio/ksuid) [![Circle CI](https://circleci.com/gh/segmentio/ksuid.svg?style=shield)](https://circleci.com/gh/segmentio/ksuid.svg?style=shield) - -ksuid is an efficient, comprehensive, battle-tested Go library for -generating and parsing a specific kind of globally unique identifier -called a *KSUID*. This library serves as its reference implementation. - -## Install -```sh -go get -u github.com/segmentio/ksuid -``` - -## What is a KSUID? - -KSUID is for K-Sortable Unique IDentifier. It is a kind of globally -unique identifier similar to a [RFC 4122 UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), built from the ground-up to be "naturally" -sorted by generation timestamp without any special type-aware logic. - -In short, running a set of KSUIDs through the UNIX `sort` command will result -in a list ordered by generation time. - -## Why use KSUIDs? - -There are numerous methods for generating unique identifiers, so why KSUID? - -1. Naturally ordered by generation time -2. Collision-free, coordination-free, dependency-free -3. Highly portable representations - -Even if only one of these properties are important to you, KSUID is a great -choice! :) Many projects chose to use KSUIDs *just* because the text -representation is copy-and-paste friendly. - -### 1. Naturally Ordered By Generation Time - -Unlike the more ubiquitous UUIDv4, a KSUID contains a timestamp component -that allows them to be loosely sorted by generation time. This is not a strong -guarantee (an invariant) as it depends on wall clocks, but is still incredibly -useful in practice. Both the binary and text representations will sort by -creation time without any special sorting logic. - -### 2. Collision-free, Coordination-free, Dependency-free - -While RFC 4122 UUIDv1s *do* include a time component, there aren't enough -bytes of randomness to provide strong protection against collisions -(duplicates). With such a low amount of entropy, it is feasible for a -malicious party to guess generated IDs, creating a problem for systems whose -security is, implicitly or explicitly, sensitive to an adversary guessing -identifiers. - -To fit into a 64-bit number space, [Snowflake IDs](https://blog.twitter.com/2010/announcing-snowflake) -and its derivatives require coordination to avoid collisions, which -significantly increases the deployment complexity and operational burden. - -A KSUID includes 128 bits of pseudorandom data ("entropy"). This number space -is 64 times larger than the 122 bits used by the well-accepted RFC 4122 UUIDv4 -standard. The additional timestamp component can be considered "bonus entropy" -which further decreases the probability of collisions, to the point of physical -infeasibility in any practical implementation. - -### Highly Portable Representations - -The text *and* binary representations are lexicographically sortable, which -allows them to be dropped into systems which do not natively support KSUIDs -and retain their time-ordered property. - -The text representation is an alphanumeric base62 encoding, so it "fits" -anywhere alphanumeric strings are accepted. No delimiters are used, so -stringified KSUIDs won't be inadvertently truncated or tokenized when -interpreted by software that is designed for human-readable text, a common -problem for the text representation of RFC 4122 UUIDs. - -## How do KSUIDs work? - -Binary KSUIDs are 20-bytes: a 32-bit unsigned integer UTC timestamp and -a 128-bit randomly generated payload. The timestamp uses big-endian -encoding, to support lexicographic sorting. The timestamp epoch is adjusted -to March 5th, 2014, providing over 100 years of life. The payload is -generated by a cryptographically-strong pseudorandom number generator. - -The text representation is always 27 characters, encoded in alphanumeric -base62 that will lexicographically sort by timestamp. - -## High Performance - -This library is designed to be used in code paths that are performance -critical. Its code has been tuned to eliminate all non-essential -overhead. The `KSUID` type is derived from a fixed-size array, which -eliminates the additional reference chasing and allocation involved in -a variable-width type. - -The API provides an interface for use in code paths which are sensitive -to allocation. For example, the `Append` method can be used to parse the -text representation and replace the contents of a `KSUID` value -without additional heap allocation. - -All public package level "pure" functions are concurrency-safe, protected -by a global mutex. For hot loops that generate a large amount of KSUIDs -from a single Goroutine, the `Sequence` type is provided to elide the -potential contention. - -By default, out of an abundance of caution, the cryptographically-secure -PRNG is used to generate the random bits of a KSUID. This can be relaxed -in extremely performance-critical code using the included `FastRander` -type. `FastRander` uses the standard PRNG with a seed generated by the -cryptographically-secure PRNG. - -*_NOTE:_ While there is no evidence that `FastRander` will increase the -probability of a collision, it shouldn't be used in scenarios where -uniqueness is important to security, as there is an increased chance -the generated IDs can be predicted by an adversary.* - -## Battle Tested - -This code has been used in production at Segment for several years, -across a diverse array of projects. Trillions upon trillions of -KSUIDs have been generated in some of Segment's most -performance-critical, large-scale distributed systems. - -## Plays Well With Others - -Designed to be integrated with other libraries, the `KSUID` type -implements many standard library interfaces, including: - -* `Stringer` -* `database/sql.Scanner` and `database/sql/driver.Valuer` -* `encoding.BinaryMarshal` and `encoding.BinaryUnmarshal` -* `encoding.TextMarshal` and `encoding.TextUnmarshal` - (`encoding/json` friendly!) - -## Command Line Tool - -This package comes with a command-line tool `ksuid`, useful for -generating KSUIDs as well as inspecting the internal components of -existing KSUIDs. Machine-friendly output is provided for scripting -use cases. - -Given a Go build environment, it can be installed with the command: - -```sh -$ go install github.com/segmentio/ksuid/cmd/ksuid -``` - -## CLI Usage Examples - -### Generate a KSUID - -```sh -$ ksuid -0ujsswThIGTUYm2K8FjOOfXtY1K -``` - -### Generate 4 KSUIDs - -```sh -$ ksuid -n 4 -0ujsszwN8NRY24YaXiTIE2VWDTS -0ujsswThIGTUYm2K8FjOOfXtY1K -0ujssxh0cECutqzMgbtXSGnjorm -0ujsszgFvbiEr7CDgE3z8MAUPFt -``` - -### Inspect the components of a KSUID - -```sh -$ ksuid -f inspect 0ujtsYcgvSTl8PAuAdqWYSMnLOv - -REPRESENTATION: - - String: 0ujtsYcgvSTl8PAuAdqWYSMnLOv - Raw: 0669F7EFB5A1CD34B5F99D1154FB6853345C9735 - -COMPONENTS: - - Time: 2017-10-09 21:00:47 -0700 PDT - Timestamp: 107608047 - Payload: B5A1CD34B5F99D1154FB6853345C9735 -``` - -### Generate a KSUID and inspect its components - -```sh -$ ksuid -f inspect - -REPRESENTATION: - - String: 0ujzPyRiIAffKhBux4PvQdDqMHY - Raw: 066A029C73FC1AA3B2446246D6E89FCD909E8FE8 - -COMPONENTS: - - Time: 2017-10-09 21:46:20 -0700 PDT - Timestamp: 107610780 - Payload: 73FC1AA3B2446246D6E89FCD909E8FE8 - -``` - -### Inspect a KSUID with template formatted inspection output - -```sh -$ ksuid -f template -t '{{ .Time }}: {{ .Payload }}' 0ujtsYcgvSTl8PAuAdqWYSMnLOv -2017-10-09 21:00:47 -0700 PDT: B5A1CD34B5F99D1154FB6853345C9735 -``` - -### Inspect multiple KSUIDs with template formatted output - -```sh -$ ksuid -f template -t '{{ .Time }}: {{ .Payload }}' $(ksuid -n 4) -2017-10-09 21:05:37 -0700 PDT: 304102BC687E087CC3A811F21D113CCF -2017-10-09 21:05:37 -0700 PDT: EAF0B240A9BFA55E079D887120D962F0 -2017-10-09 21:05:37 -0700 PDT: DF0761769909ABB0C7BB9D66F79FC041 -2017-10-09 21:05:37 -0700 PDT: 1A8F0E3D0BDEB84A5FAD702876F46543 -``` - -### Generate KSUIDs and output JSON using template formatting - -```sh -$ ksuid -f template -t '{ "timestamp": "{{ .Timestamp }}", "payload": "{{ .Payload }}", "ksuid": "{{.String}}"}' -n 4 -{ "timestamp": "107611700", "payload": "9850EEEC191BF4FF26F99315CE43B0C8", "ksuid": "0uk1Hbc9dQ9pxyTqJ93IUrfhdGq"} -{ "timestamp": "107611700", "payload": "CC55072555316F45B8CA2D2979D3ED0A", "ksuid": "0uk1HdCJ6hUZKDgcxhpJwUl5ZEI"} -{ "timestamp": "107611700", "payload": "BA1C205D6177F0992D15EE606AE32238", "ksuid": "0uk1HcdvF0p8C20KtTfdRSB9XIm"} -{ "timestamp": "107611700", "payload": "67517BA309EA62AE7991B27BB6F2FCAC", "ksuid": "0uk1Ha7hGJ1Q9Xbnkt0yZgNwg3g"} -``` - -## Implementations for other languages - -- Python: [svix-ksuid](https://github.com/svixhq/python-ksuid/) -- Ruby: [ksuid-ruby](https://github.com/michaelherold/ksuid-ruby) -- Java: [ksuid](https://github.com/ksuid/ksuid) -- Rust: [rksuid](https://github.com/nharring/rksuid) -- dotNet: [Ksuid.Net](https://github.com/JoyMoe/Ksuid.Net) - -## License - -ksuid source code is available under an MIT [License](/LICENSE.md). diff --git a/vendor/github.com/segmentio/ksuid/base62.go b/vendor/github.com/segmentio/ksuid/base62.go deleted file mode 100644 index 146a41f0fb3..00000000000 --- a/vendor/github.com/segmentio/ksuid/base62.go +++ /dev/null @@ -1,202 +0,0 @@ -package ksuid - -import ( - "encoding/binary" - "errors" -) - -const ( - // lexographic ordering (based on Unicode table) is 0-9A-Za-z - base62Characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - zeroString = "000000000000000000000000000" - offsetUppercase = 10 - offsetLowercase = 36 -) - -var ( - errShortBuffer = errors.New("the output buffer is too small to hold to decoded value") -) - -// Converts a base 62 byte into the number value that it represents. -func base62Value(digit byte) byte { - switch { - case digit >= '0' && digit <= '9': - return digit - '0' - case digit >= 'A' && digit <= 'Z': - return offsetUppercase + (digit - 'A') - default: - return offsetLowercase + (digit - 'a') - } -} - -// This function encodes the base 62 representation of the src KSUID in binary -// form into dst. -// -// In order to support a couple of optimizations the function assumes that src -// is 20 bytes long and dst is 27 bytes long. -// -// Any unused bytes in dst will be set to the padding '0' byte. -func fastEncodeBase62(dst []byte, src []byte) { - const srcBase = 4294967296 - const dstBase = 62 - - // Split src into 5 4-byte words, this is where most of the efficiency comes - // from because this is a O(N^2) algorithm, and we make N = N / 4 by working - // on 32 bits at a time. - parts := [5]uint32{ - binary.BigEndian.Uint32(src[0:4]), - binary.BigEndian.Uint32(src[4:8]), - binary.BigEndian.Uint32(src[8:12]), - binary.BigEndian.Uint32(src[12:16]), - binary.BigEndian.Uint32(src[16:20]), - } - - n := len(dst) - bp := parts[:] - bq := [5]uint32{} - - for len(bp) != 0 { - quotient := bq[:0] - remainder := uint64(0) - - for _, c := range bp { - value := uint64(c) + uint64(remainder)*srcBase - digit := value / dstBase - remainder = value % dstBase - - if len(quotient) != 0 || digit != 0 { - quotient = append(quotient, uint32(digit)) - } - } - - // Writes at the end of the destination buffer because we computed the - // lowest bits first. - n-- - dst[n] = base62Characters[remainder] - bp = quotient - } - - // Add padding at the head of the destination buffer for all bytes that were - // not set. - copy(dst[:n], zeroString) -} - -// This function appends the base 62 representation of the KSUID in src to dst, -// and returns the extended byte slice. -// The result is left-padded with '0' bytes to always append 27 bytes to the -// destination buffer. -func fastAppendEncodeBase62(dst []byte, src []byte) []byte { - dst = reserve(dst, stringEncodedLength) - n := len(dst) - fastEncodeBase62(dst[n:n+stringEncodedLength], src) - return dst[:n+stringEncodedLength] -} - -// This function decodes the base 62 representation of the src KSUID to the -// binary form into dst. -// -// In order to support a couple of optimizations the function assumes that src -// is 27 bytes long and dst is 20 bytes long. -// -// Any unused bytes in dst will be set to zero. -func fastDecodeBase62(dst []byte, src []byte) error { - const srcBase = 62 - const dstBase = 4294967296 - - // This line helps BCE (Bounds Check Elimination). - // It may be safely removed. - _ = src[26] - - parts := [27]byte{ - base62Value(src[0]), - base62Value(src[1]), - base62Value(src[2]), - base62Value(src[3]), - base62Value(src[4]), - base62Value(src[5]), - base62Value(src[6]), - base62Value(src[7]), - base62Value(src[8]), - base62Value(src[9]), - - base62Value(src[10]), - base62Value(src[11]), - base62Value(src[12]), - base62Value(src[13]), - base62Value(src[14]), - base62Value(src[15]), - base62Value(src[16]), - base62Value(src[17]), - base62Value(src[18]), - base62Value(src[19]), - - base62Value(src[20]), - base62Value(src[21]), - base62Value(src[22]), - base62Value(src[23]), - base62Value(src[24]), - base62Value(src[25]), - base62Value(src[26]), - } - - n := len(dst) - bp := parts[:] - bq := [stringEncodedLength]byte{} - - for len(bp) > 0 { - quotient := bq[:0] - remainder := uint64(0) - - for _, c := range bp { - value := uint64(c) + uint64(remainder)*srcBase - digit := value / dstBase - remainder = value % dstBase - - if len(quotient) != 0 || digit != 0 { - quotient = append(quotient, byte(digit)) - } - } - - if n < 4 { - return errShortBuffer - } - - dst[n-4] = byte(remainder >> 24) - dst[n-3] = byte(remainder >> 16) - dst[n-2] = byte(remainder >> 8) - dst[n-1] = byte(remainder) - n -= 4 - bp = quotient - } - - var zero [20]byte - copy(dst[:n], zero[:]) - return nil -} - -// This function appends the base 62 decoded version of src into dst. -func fastAppendDecodeBase62(dst []byte, src []byte) []byte { - dst = reserve(dst, byteLength) - n := len(dst) - fastDecodeBase62(dst[n:n+byteLength], src) - return dst[:n+byteLength] -} - -// Ensures that at least nbytes are available in the remaining capacity of the -// destination slice, if not, a new copy is made and returned by the function. -func reserve(dst []byte, nbytes int) []byte { - c := cap(dst) - n := len(dst) - - if avail := c - n; avail < nbytes { - c *= 2 - if (c - n) < nbytes { - c = n + nbytes - } - b := make([]byte, n, c) - copy(b, dst) - dst = b - } - - return dst -} diff --git a/vendor/github.com/segmentio/ksuid/ksuid.go b/vendor/github.com/segmentio/ksuid/ksuid.go deleted file mode 100644 index dbe1f9c7f30..00000000000 --- a/vendor/github.com/segmentio/ksuid/ksuid.go +++ /dev/null @@ -1,352 +0,0 @@ -package ksuid - -import ( - "bytes" - "crypto/rand" - "database/sql/driver" - "encoding/binary" - "fmt" - "io" - "math" - "sync" - "time" -) - -const ( - // KSUID's epoch starts more recently so that the 32-bit number space gives a - // significantly higher useful lifetime of around 136 years from March 2017. - // This number (14e8) was picked to be easy to remember. - epochStamp int64 = 1400000000 - - // Timestamp is a uint32 - timestampLengthInBytes = 4 - - // Payload is 16-bytes - payloadLengthInBytes = 16 - - // KSUIDs are 20 bytes when binary encoded - byteLength = timestampLengthInBytes + payloadLengthInBytes - - // The length of a KSUID when string (base62) encoded - stringEncodedLength = 27 - - // A string-encoded minimum value for a KSUID - minStringEncoded = "000000000000000000000000000" - - // A string-encoded maximum value for a KSUID - maxStringEncoded = "aWgEPTl1tmebfsQzFP4bxwgy80V" -) - -// KSUIDs are 20 bytes: -// 00-03 byte: uint32 BE UTC timestamp with custom epoch -// 04-19 byte: random "payload" -type KSUID [byteLength]byte - -var ( - rander = rand.Reader - randMutex = sync.Mutex{} - randBuffer = [payloadLengthInBytes]byte{} - - errSize = fmt.Errorf("Valid KSUIDs are %v bytes", byteLength) - errStrSize = fmt.Errorf("Valid encoded KSUIDs are %v characters", stringEncodedLength) - errStrValue = fmt.Errorf("Valid encoded KSUIDs are bounded by %s and %s", minStringEncoded, maxStringEncoded) - errPayloadSize = fmt.Errorf("Valid KSUID payloads are %v bytes", payloadLengthInBytes) - - // Represents a completely empty (invalid) KSUID - Nil KSUID - // Represents the highest value a KSUID can have - Max = KSUID{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} -) - -// Append appends the string representation of i to b, returning a slice to a -// potentially larger memory area. -func (i KSUID) Append(b []byte) []byte { - return fastAppendEncodeBase62(b, i[:]) -} - -// The timestamp portion of the ID as a Time object -func (i KSUID) Time() time.Time { - return correctedUTCTimestampToTime(i.Timestamp()) -} - -// The timestamp portion of the ID as a bare integer which is uncorrected -// for KSUID's special epoch. -func (i KSUID) Timestamp() uint32 { - return binary.BigEndian.Uint32(i[:timestampLengthInBytes]) -} - -// The 16-byte random payload without the timestamp -func (i KSUID) Payload() []byte { - return i[timestampLengthInBytes:] -} - -// String-encoded representation that can be passed through Parse() -func (i KSUID) String() string { - return string(i.Append(make([]byte, 0, stringEncodedLength))) -} - -// Raw byte representation of KSUID -func (i KSUID) Bytes() []byte { - // Safe because this is by-value - return i[:] -} - -// IsNil returns true if this is a "nil" KSUID -func (i KSUID) IsNil() bool { - return i == Nil -} - -// Get satisfies the flag.Getter interface, making it possible to use KSUIDs as -// part of of the command line options of a program. -func (i KSUID) Get() interface{} { - return i -} - -// Set satisfies the flag.Value interface, making it possible to use KSUIDs as -// part of of the command line options of a program. -func (i *KSUID) Set(s string) error { - return i.UnmarshalText([]byte(s)) -} - -func (i KSUID) MarshalText() ([]byte, error) { - return []byte(i.String()), nil -} - -func (i KSUID) MarshalBinary() ([]byte, error) { - return i.Bytes(), nil -} - -func (i *KSUID) UnmarshalText(b []byte) error { - id, err := Parse(string(b)) - if err != nil { - return err - } - *i = id - return nil -} - -func (i *KSUID) UnmarshalBinary(b []byte) error { - id, err := FromBytes(b) - if err != nil { - return err - } - *i = id - return nil -} - -// Value converts the KSUID into a SQL driver value which can be used to -// directly use the KSUID as parameter to a SQL query. -func (i KSUID) Value() (driver.Value, error) { - if i.IsNil() { - return nil, nil - } - return i.String(), nil -} - -// Scan implements the sql.Scanner interface. It supports converting from -// string, []byte, or nil into a KSUID value. Attempting to convert from -// another type will return an error. -func (i *KSUID) Scan(src interface{}) error { - switch v := src.(type) { - case nil: - return i.scan(nil) - case []byte: - return i.scan(v) - case string: - return i.scan([]byte(v)) - default: - return fmt.Errorf("Scan: unable to scan type %T into KSUID", v) - } -} - -func (i *KSUID) scan(b []byte) error { - switch len(b) { - case 0: - *i = Nil - return nil - case byteLength: - return i.UnmarshalBinary(b) - case stringEncodedLength: - return i.UnmarshalText(b) - default: - return errSize - } -} - -// Parse decodes a string-encoded representation of a KSUID object -func Parse(s string) (KSUID, error) { - if len(s) != stringEncodedLength { - return Nil, errStrSize - } - - src := [stringEncodedLength]byte{} - dst := [byteLength]byte{} - - copy(src[:], s[:]) - - if err := fastDecodeBase62(dst[:], src[:]); err != nil { - return Nil, errStrValue - } - - return FromBytes(dst[:]) -} - -func timeToCorrectedUTCTimestamp(t time.Time) uint32 { - return uint32(t.Unix() - epochStamp) -} - -func correctedUTCTimestampToTime(ts uint32) time.Time { - return time.Unix(int64(ts)+epochStamp, 0) -} - -// Generates a new KSUID. In the strange case that random bytes -// can't be read, it will panic. -func New() KSUID { - ksuid, err := NewRandom() - if err != nil { - panic(fmt.Sprintf("Couldn't generate KSUID, inconceivable! error: %v", err)) - } - return ksuid -} - -// Generates a new KSUID -func NewRandom() (ksuid KSUID, err error) { - return NewRandomWithTime(time.Now()) -} - -func NewRandomWithTime(t time.Time) (ksuid KSUID, err error) { - // Go's default random number generators are not safe for concurrent use by - // multiple goroutines, the use of the rander and randBuffer are explicitly - // synchronized here. - randMutex.Lock() - - _, err = io.ReadAtLeast(rander, randBuffer[:], len(randBuffer)) - copy(ksuid[timestampLengthInBytes:], randBuffer[:]) - - randMutex.Unlock() - - if err != nil { - ksuid = Nil // don't leak random bytes on error - return - } - - ts := timeToCorrectedUTCTimestamp(t) - binary.BigEndian.PutUint32(ksuid[:timestampLengthInBytes], ts) - return -} - -// Constructs a KSUID from constituent parts -func FromParts(t time.Time, payload []byte) (KSUID, error) { - if len(payload) != payloadLengthInBytes { - return Nil, errPayloadSize - } - - var ksuid KSUID - - ts := timeToCorrectedUTCTimestamp(t) - binary.BigEndian.PutUint32(ksuid[:timestampLengthInBytes], ts) - - copy(ksuid[timestampLengthInBytes:], payload) - - return ksuid, nil -} - -// Constructs a KSUID from a 20-byte binary representation -func FromBytes(b []byte) (KSUID, error) { - var ksuid KSUID - - if len(b) != byteLength { - return Nil, errSize - } - - copy(ksuid[:], b) - return ksuid, nil -} - -// Sets the global source of random bytes for KSUID generation. This -// should probably only be set once globally. While this is technically -// thread-safe as in it won't cause corruption, there's no guarantee -// on ordering. -func SetRand(r io.Reader) { - if r == nil { - rander = rand.Reader - return - } - rander = r -} - -// Implements comparison for KSUID type -func Compare(a, b KSUID) int { - return bytes.Compare(a[:], b[:]) -} - -// Sorts the given slice of KSUIDs -func Sort(ids []KSUID) { - quickSort(ids, 0, len(ids)-1) -} - -// IsSorted checks whether a slice of KSUIDs is sorted -func IsSorted(ids []KSUID) bool { - if len(ids) != 0 { - min := ids[0] - for _, id := range ids[1:] { - if bytes.Compare(min[:], id[:]) > 0 { - return false - } - min = id - } - } - return true -} - -func quickSort(a []KSUID, lo int, hi int) { - if lo < hi { - pivot := a[hi] - i := lo - 1 - - for j, n := lo, hi; j != n; j++ { - if bytes.Compare(a[j][:], pivot[:]) < 0 { - i++ - a[i], a[j] = a[j], a[i] - } - } - - i++ - if bytes.Compare(a[hi][:], a[i][:]) < 0 { - a[i], a[hi] = a[hi], a[i] - } - - quickSort(a, lo, i-1) - quickSort(a, i+1, hi) - } -} - -// Next returns the next KSUID after id. -func (id KSUID) Next() KSUID { - zero := makeUint128(0, 0) - - t := id.Timestamp() - u := uint128Payload(id) - v := add128(u, makeUint128(0, 1)) - - if v == zero { // overflow - t++ - } - - return v.ksuid(t) -} - -// Prev returns the previoud KSUID before id. -func (id KSUID) Prev() KSUID { - max := makeUint128(math.MaxUint64, math.MaxUint64) - - t := id.Timestamp() - u := uint128Payload(id) - v := sub128(u, makeUint128(0, 1)) - - if v == max { // overflow - t-- - } - - return v.ksuid(t) -} diff --git a/vendor/github.com/segmentio/ksuid/rand.go b/vendor/github.com/segmentio/ksuid/rand.go deleted file mode 100644 index 66edbd4d832..00000000000 --- a/vendor/github.com/segmentio/ksuid/rand.go +++ /dev/null @@ -1,55 +0,0 @@ -package ksuid - -import ( - cryptoRand "crypto/rand" - "encoding/binary" - "io" - "math/rand" -) - -// FastRander is an io.Reader that uses math/rand and is optimized for -// generating 16 bytes KSUID payloads. It is intended to be used as a -// performance improvements for programs that have no need for -// cryptographically secure KSUIDs and are generating a lot of them. -var FastRander = newRBG() - -func newRBG() io.Reader { - r, err := newRandomBitsGenerator() - if err != nil { - panic(err) - } - return r -} - -func newRandomBitsGenerator() (r io.Reader, err error) { - var seed int64 - - if seed, err = readCryptoRandomSeed(); err != nil { - return - } - - r = &randSourceReader{source: rand.NewSource(seed).(rand.Source64)} - return -} - -func readCryptoRandomSeed() (seed int64, err error) { - var b [8]byte - - if _, err = io.ReadFull(cryptoRand.Reader, b[:]); err != nil { - return - } - - seed = int64(binary.LittleEndian.Uint64(b[:])) - return -} - -type randSourceReader struct { - source rand.Source64 -} - -func (r *randSourceReader) Read(b []byte) (int, error) { - // optimized for generating 16 bytes payloads - binary.LittleEndian.PutUint64(b[:8], r.source.Uint64()) - binary.LittleEndian.PutUint64(b[8:], r.source.Uint64()) - return 16, nil -} diff --git a/vendor/github.com/segmentio/ksuid/sequence.go b/vendor/github.com/segmentio/ksuid/sequence.go deleted file mode 100644 index 9f1c33a0c82..00000000000 --- a/vendor/github.com/segmentio/ksuid/sequence.go +++ /dev/null @@ -1,55 +0,0 @@ -package ksuid - -import ( - "encoding/binary" - "errors" - "math" -) - -// Sequence is a KSUID generator which produces a sequence of ordered KSUIDs -// from a seed. -// -// Up to 65536 KSUIDs can be generated by for a single seed. -// -// A typical usage of a Sequence looks like this: -// -// seq := ksuid.Sequence{ -// Seed: ksuid.New(), -// } -// id, err := seq.Next() -// -// Sequence values are not safe to use concurrently from multiple goroutines. -type Sequence struct { - // The seed is used as base for the KSUID generator, all generated KSUIDs - // share the same leading 18 bytes of the seed. - Seed KSUID - count uint32 // uint32 for overflow, only 2 bytes are used -} - -// Next produces the next KSUID in the sequence, or returns an error if the -// sequence has been exhausted. -func (seq *Sequence) Next() (KSUID, error) { - id := seq.Seed // copy - count := seq.count - if count > math.MaxUint16 { - return Nil, errors.New("too many IDs were generated") - } - seq.count++ - return withSequenceNumber(id, uint16(count)), nil -} - -// Bounds returns the inclusive min and max bounds of the KSUIDs that may be -// generated by the sequence. If all ids have been generated already then the -// returned min value is equal to the max. -func (seq *Sequence) Bounds() (min KSUID, max KSUID) { - count := seq.count - if count > math.MaxUint16 { - count = math.MaxUint16 - } - return withSequenceNumber(seq.Seed, uint16(count)), withSequenceNumber(seq.Seed, math.MaxUint16) -} - -func withSequenceNumber(id KSUID, n uint16) KSUID { - binary.BigEndian.PutUint16(id[len(id)-2:], n) - return id -} diff --git a/vendor/github.com/segmentio/ksuid/set.go b/vendor/github.com/segmentio/ksuid/set.go deleted file mode 100644 index a6b0e6582cd..00000000000 --- a/vendor/github.com/segmentio/ksuid/set.go +++ /dev/null @@ -1,343 +0,0 @@ -package ksuid - -import ( - "bytes" - "encoding/binary" -) - -// CompressedSet is an immutable data type which stores a set of KSUIDs. -type CompressedSet []byte - -// Iter returns an iterator that produces all KSUIDs in the set. -func (set CompressedSet) Iter() CompressedSetIter { - return CompressedSetIter{ - content: []byte(set), - } -} - -// String satisfies the fmt.Stringer interface, returns a human-readable string -// representation of the set. -func (set CompressedSet) String() string { - b := bytes.Buffer{} - b.WriteByte('[') - set.writeTo(&b) - b.WriteByte(']') - return b.String() -} - -// String satisfies the fmt.GoStringer interface, returns a Go representation of -// the set. -func (set CompressedSet) GoString() string { - b := bytes.Buffer{} - b.WriteString("ksuid.CompressedSet{") - set.writeTo(&b) - b.WriteByte('}') - return b.String() -} - -func (set CompressedSet) writeTo(b *bytes.Buffer) { - a := [27]byte{} - - for i, it := 0, set.Iter(); it.Next(); i++ { - if i != 0 { - b.WriteString(", ") - } - b.WriteByte('"') - it.KSUID.Append(a[:0]) - b.Write(a[:]) - b.WriteByte('"') - } -} - -// Compress creates and returns a compressed set of KSUIDs from the list given -// as arguments. -func Compress(ids ...KSUID) CompressedSet { - c := 1 + byteLength + (len(ids) / 5) - b := make([]byte, 0, c) - return AppendCompressed(b, ids...) -} - -// AppendCompressed uses the given byte slice as pre-allocated storage space to -// build a KSUID set. -// -// Note that the set uses a compression technique to store the KSUIDs, so the -// resuling length is not 20 x len(ids). The rule of thumb here is for the given -// byte slice to reserve the amount of memory that the application would be OK -// to waste. -func AppendCompressed(set []byte, ids ...KSUID) CompressedSet { - if len(ids) != 0 { - if !IsSorted(ids) { - Sort(ids) - } - one := makeUint128(0, 1) - - // The first KSUID is always written to the set, this is the starting - // point for all deltas. - set = append(set, byte(rawKSUID)) - set = append(set, ids[0][:]...) - - timestamp := ids[0].Timestamp() - lastKSUID := ids[0] - lastValue := uint128Payload(ids[0]) - - for i := 1; i != len(ids); i++ { - id := ids[i] - - if id == lastKSUID { - continue - } - - t := id.Timestamp() - v := uint128Payload(id) - - if t != timestamp { - d := t - timestamp - n := varintLength32(d) - - set = append(set, timeDelta|byte(n)) - set = appendVarint32(set, d, n) - set = append(set, id[timestampLengthInBytes:]...) - - timestamp = t - } else { - d := sub128(v, lastValue) - - if d != one { - n := varintLength128(d) - - set = append(set, payloadDelta|byte(n)) - set = appendVarint128(set, d, n) - } else { - l, c := rangeLength(ids[i+1:], t, id, v) - m := uint64(l + 1) - n := varintLength64(m) - - set = append(set, payloadRange|byte(n)) - set = appendVarint64(set, m, n) - - i += c - id = ids[i] - v = uint128Payload(id) - } - } - - lastKSUID = id - lastValue = v - } - } - return CompressedSet(set) -} - -func rangeLength(ids []KSUID, timestamp uint32, lastKSUID KSUID, lastValue uint128) (length int, count int) { - one := makeUint128(0, 1) - - for i := range ids { - id := ids[i] - - if id == lastKSUID { - continue - } - - if id.Timestamp() != timestamp { - count = i - return - } - - v := uint128Payload(id) - - if sub128(v, lastValue) != one { - count = i - return - } - - lastKSUID = id - lastValue = v - length++ - } - - count = len(ids) - return -} - -func appendVarint128(b []byte, v uint128, n int) []byte { - c := v.bytes() - return append(b, c[len(c)-n:]...) -} - -func appendVarint64(b []byte, v uint64, n int) []byte { - c := [8]byte{} - binary.BigEndian.PutUint64(c[:], v) - return append(b, c[len(c)-n:]...) -} - -func appendVarint32(b []byte, v uint32, n int) []byte { - c := [4]byte{} - binary.BigEndian.PutUint32(c[:], v) - return append(b, c[len(c)-n:]...) -} - -func varint128(b []byte) uint128 { - a := [16]byte{} - copy(a[16-len(b):], b) - return makeUint128FromPayload(a[:]) -} - -func varint64(b []byte) uint64 { - a := [8]byte{} - copy(a[8-len(b):], b) - return binary.BigEndian.Uint64(a[:]) -} - -func varint32(b []byte) uint32 { - a := [4]byte{} - copy(a[4-len(b):], b) - return binary.BigEndian.Uint32(a[:]) -} - -func varintLength128(v uint128) int { - if v[1] != 0 { - return 8 + varintLength64(v[1]) - } - return varintLength64(v[0]) -} - -func varintLength64(v uint64) int { - switch { - case (v & 0xFFFFFFFFFFFFFF00) == 0: - return 1 - case (v & 0xFFFFFFFFFFFF0000) == 0: - return 2 - case (v & 0xFFFFFFFFFF000000) == 0: - return 3 - case (v & 0xFFFFFFFF00000000) == 0: - return 4 - case (v & 0xFFFFFF0000000000) == 0: - return 5 - case (v & 0xFFFF000000000000) == 0: - return 6 - case (v & 0xFF00000000000000) == 0: - return 7 - default: - return 8 - } -} - -func varintLength32(v uint32) int { - switch { - case (v & 0xFFFFFF00) == 0: - return 1 - case (v & 0xFFFF0000) == 0: - return 2 - case (v & 0xFF000000) == 0: - return 3 - default: - return 4 - } -} - -const ( - rawKSUID = 0 - timeDelta = (1 << 6) - payloadDelta = (1 << 7) - payloadRange = (1 << 6) | (1 << 7) -) - -// CompressedSetIter is an iterator type returned by Set.Iter to produce the -// list of KSUIDs stored in a set. -// -// Here's is how the iterator type is commonly used: -// -// for it := set.Iter(); it.Next(); { -// id := it.KSUID -// // ... -// } -// -// CompressedSetIter values are not safe to use concurrently from multiple -// goroutines. -type CompressedSetIter struct { - // KSUID is modified by calls to the Next method to hold the KSUID loaded - // by the iterator. - KSUID KSUID - - content []byte - offset int - - seqlength uint64 - timestamp uint32 - lastValue uint128 -} - -// Next moves the iterator forward, returning true if there a KSUID was found, -// or false if the iterator as reached the end of the set it was created from. -func (it *CompressedSetIter) Next() bool { - if it.seqlength != 0 { - value := incr128(it.lastValue) - it.KSUID = value.ksuid(it.timestamp) - it.seqlength-- - it.lastValue = value - return true - } - - if it.offset == len(it.content) { - return false - } - - b := it.content[it.offset] - it.offset++ - - const mask = rawKSUID | timeDelta | payloadDelta | payloadRange - tag := int(b) & mask - cnt := int(b) & ^mask - - switch tag { - case rawKSUID: - off0 := it.offset - off1 := off0 + byteLength - - copy(it.KSUID[:], it.content[off0:off1]) - - it.offset = off1 - it.timestamp = it.KSUID.Timestamp() - it.lastValue = uint128Payload(it.KSUID) - - case timeDelta: - off0 := it.offset - off1 := off0 + cnt - off2 := off1 + payloadLengthInBytes - - it.timestamp += varint32(it.content[off0:off1]) - - binary.BigEndian.PutUint32(it.KSUID[:timestampLengthInBytes], it.timestamp) - copy(it.KSUID[timestampLengthInBytes:], it.content[off1:off2]) - - it.offset = off2 - it.lastValue = uint128Payload(it.KSUID) - - case payloadDelta: - off0 := it.offset - off1 := off0 + cnt - - delta := varint128(it.content[off0:off1]) - value := add128(it.lastValue, delta) - - it.KSUID = value.ksuid(it.timestamp) - it.offset = off1 - it.lastValue = value - - case payloadRange: - off0 := it.offset - off1 := off0 + cnt - - value := incr128(it.lastValue) - it.KSUID = value.ksuid(it.timestamp) - it.seqlength = varint64(it.content[off0:off1]) - it.offset = off1 - it.seqlength-- - it.lastValue = value - - default: - panic("KSUID set iterator is reading malformed data") - } - - return true -} diff --git a/vendor/github.com/segmentio/ksuid/uint128.go b/vendor/github.com/segmentio/ksuid/uint128.go deleted file mode 100644 index b934489ce11..00000000000 --- a/vendor/github.com/segmentio/ksuid/uint128.go +++ /dev/null @@ -1,141 +0,0 @@ -package ksuid - -import "fmt" - -// uint128 represents an unsigned 128 bits little endian integer. -type uint128 [2]uint64 - -func uint128Payload(ksuid KSUID) uint128 { - return makeUint128FromPayload(ksuid[timestampLengthInBytes:]) -} - -func makeUint128(high uint64, low uint64) uint128 { - return uint128{low, high} -} - -func makeUint128FromPayload(payload []byte) uint128 { - return uint128{ - // low - uint64(payload[8])<<56 | - uint64(payload[9])<<48 | - uint64(payload[10])<<40 | - uint64(payload[11])<<32 | - uint64(payload[12])<<24 | - uint64(payload[13])<<16 | - uint64(payload[14])<<8 | - uint64(payload[15]), - // high - uint64(payload[0])<<56 | - uint64(payload[1])<<48 | - uint64(payload[2])<<40 | - uint64(payload[3])<<32 | - uint64(payload[4])<<24 | - uint64(payload[5])<<16 | - uint64(payload[6])<<8 | - uint64(payload[7]), - } -} - -func (v uint128) ksuid(timestamp uint32) KSUID { - return KSUID{ - // time - byte(timestamp >> 24), - byte(timestamp >> 16), - byte(timestamp >> 8), - byte(timestamp), - - // high - byte(v[1] >> 56), - byte(v[1] >> 48), - byte(v[1] >> 40), - byte(v[1] >> 32), - byte(v[1] >> 24), - byte(v[1] >> 16), - byte(v[1] >> 8), - byte(v[1]), - - // low - byte(v[0] >> 56), - byte(v[0] >> 48), - byte(v[0] >> 40), - byte(v[0] >> 32), - byte(v[0] >> 24), - byte(v[0] >> 16), - byte(v[0] >> 8), - byte(v[0]), - } -} - -func (v uint128) bytes() [16]byte { - return [16]byte{ - // high - byte(v[1] >> 56), - byte(v[1] >> 48), - byte(v[1] >> 40), - byte(v[1] >> 32), - byte(v[1] >> 24), - byte(v[1] >> 16), - byte(v[1] >> 8), - byte(v[1]), - - // low - byte(v[0] >> 56), - byte(v[0] >> 48), - byte(v[0] >> 40), - byte(v[0] >> 32), - byte(v[0] >> 24), - byte(v[0] >> 16), - byte(v[0] >> 8), - byte(v[0]), - } -} - -func (v uint128) String() string { - return fmt.Sprintf("0x%016X%016X", v[0], v[1]) -} - -const wordBitSize = 64 - -func cmp128(x, y uint128) int { - if x[1] < y[1] { - return -1 - } - if x[1] > y[1] { - return 1 - } - if x[0] < y[0] { - return -1 - } - if x[0] > y[0] { - return 1 - } - return 0 -} - -func add128(x, y uint128) (z uint128) { - x0 := x[0] - y0 := y[0] - z0 := x0 + y0 - z[0] = z0 - - c := (x0&y0 | (x0|y0)&^z0) >> (wordBitSize - 1) - - z[1] = x[1] + y[1] + c - return -} - -func sub128(x, y uint128) (z uint128) { - x0 := x[0] - y0 := y[0] - z0 := x0 - y0 - z[0] = z0 - - c := (y0&^x0 | (y0|^x0)&z0) >> (wordBitSize - 1) - - z[1] = x[1] - y[1] - c - return -} - -func incr128(x uint128) uint128 { - return add128(x, uint128{1, 0}) -} diff --git a/vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go b/vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go index 584aac971f3..4ed41e31a1f 100644 --- a/vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go +++ b/vendor/github.com/sigstore/fulcio/pkg/certificate/extensions.go @@ -53,6 +53,7 @@ var ( OIDBuildTrigger = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 20} OIDRunInvocationURI = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 21} OIDSourceRepositoryVisibilityAtSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 22} + OIDDeploymentEnvironment = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 1, 23} ) // Extensions contains all custom x509 extensions defined by Fulcio @@ -132,6 +133,9 @@ type Extensions struct { // Source repository visibility at the time of signing the certificate. SourceRepositoryVisibilityAtSigning string `json:"SourceRepositoryVisibilityAtSigning,omitempty" yaml:"source-repository-visibility-at-signing,omitempty"` // 1.3.6.1.4.1.57264.1.22 + + // Deployment target for a workflow or job + DeploymentEnvironment string `json:"DeploymentEnvironment,omitempty" yaml:"deployment-environment,omitempty"` // 1.3.6.1.4.1.57264.1.23 } func (e Extensions) Render() ([]pkix.Extension, error) { @@ -334,6 +338,16 @@ func (e Extensions) Render() ([]pkix.Extension, error) { Value: val, }) } + if e.DeploymentEnvironment != "" { + val, err := asn1.MarshalWithParams(e.DeploymentEnvironment, "utf8") + if err != nil { + return nil, err + } + exts = append(exts, pkix.Extension{ + Id: OIDDeploymentEnvironment, + Value: val, + }) + } return exts, nil } @@ -417,6 +431,10 @@ func ParseExtensions(ext []pkix.Extension) (Extensions, error) { if err := ParseDERString(e.Value, &out.SourceRepositoryVisibilityAtSigning); err != nil { return Extensions{}, err } + case e.Id.Equal(OIDDeploymentEnvironment): + if err := ParseDERString(e.Value, &out.DeploymentEnvironment); err != nil { + return Extensions{}, err + } } } diff --git a/vendor/github.com/sigstore/protobuf-specs/gen/pb-go/common/v1/sigstore_common.pb.go b/vendor/github.com/sigstore/protobuf-specs/gen/pb-go/common/v1/sigstore_common.pb.go index 40725bd79c3..5f339b2d78d 100644 --- a/vendor/github.com/sigstore/protobuf-specs/gen/pb-go/common/v1/sigstore_common.pb.go +++ b/vendor/github.com/sigstore/protobuf-specs/gen/pb-go/common/v1/sigstore_common.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.5 -// protoc v5.29.4 +// protoc v6.30.2 // source: sigstore_common.proto package v1 @@ -112,7 +112,8 @@ func (HashAlgorithm) EnumDescriptor() ([]byte, []int) { // opinionated options instead of allowing every possible permutation. // // Any changes to this enum MUST be reflected in the algorithm registry. -// See: docs/algorithm-registry.md +// +// See: // // To avoid the possibility of contradicting formats such as PKCS1 with // ED25519 the valid permutations are listed as a linear set instead of a @@ -159,8 +160,9 @@ const ( PublicKeyDetails_PKIX_ECDSA_P521_SHA_256 PublicKeyDetails = 20 // LMS and LM-OTS // - // These keys and signatures may be used by private Sigstore - // deployments, but are not currently supported by the public + // These algorithms are deprecated and should not be used. + // Keys and signatures MAY be used by private Sigstore + // deployments, but will not be supported by the public // good instance. // // USER WARNING: LMS and LM-OTS are both stateful signature schemes. @@ -170,8 +172,26 @@ const ( // MUST NOT be used for more than one signature per LM-OTS key. // If you cannot maintain these invariants, you MUST NOT use these // schemes. - PublicKeyDetails_LMS_SHA256 PublicKeyDetails = 14 + // + // Deprecated: Marked as deprecated in sigstore_common.proto. + PublicKeyDetails_LMS_SHA256 PublicKeyDetails = 14 + // Deprecated: Marked as deprecated in sigstore_common.proto. PublicKeyDetails_LMOTS_SHA256 PublicKeyDetails = 15 + // ML-DSA + // + // These ML_DSA_65 and ML-DSA_87 algorithms are the pure variants that + // take data to sign rather than the prehash variants (HashML-DSA), which + // take digests. While considered quantum-resistant, their usage + // involves tradeoffs in that signatures and keys are much larger, and + // this makes deployments more costly. + // + // USER WARNING: ML_DSA_65 and ML_DSA_87 are experimental algorithms. + // In the future they MAY be used by private Sigstore deployments, but + // they are not yet fully functional. This warning will be removed when + // these algorithms are widely supported by Sigstore clients and servers, + // but care should still be taken for production environments. + PublicKeyDetails_ML_DSA_65 PublicKeyDetails = 21 // See NIST FIPS 204 + PublicKeyDetails_ML_DSA_87 PublicKeyDetails = 22 ) // Enum value maps for PublicKeyDetails. @@ -198,6 +218,8 @@ var ( 20: "PKIX_ECDSA_P521_SHA_256", 14: "LMS_SHA256", 15: "LMOTS_SHA256", + 21: "ML_DSA_65", + 22: "ML_DSA_87", } PublicKeyDetails_value = map[string]int32{ "PUBLIC_KEY_DETAILS_UNSPECIFIED": 0, @@ -221,6 +243,8 @@ var ( "PKIX_ECDSA_P521_SHA_256": 20, "LMS_SHA256": 14, "LMOTS_SHA256": 15, + "ML_DSA_65": 21, + "ML_DSA_87": 22, } ) @@ -1134,7 +1158,7 @@ var file_sigstore_common_proto_rawDesc = string([]byte{ 0x48, 0x41, 0x32, 0x5f, 0x33, 0x38, 0x34, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x32, 0x5f, 0x35, 0x31, 0x32, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x41, 0x33, 0x5f, 0x33, 0x38, - 0x34, 0x10, 0x05, 0x2a, 0xe9, 0x04, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x34, 0x10, 0x05, 0x2a, 0x8f, 0x05, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x44, 0x45, 0x54, 0x41, 0x49, 0x4c, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x11, @@ -1170,25 +1194,27 @@ var file_sigstore_common_proto_rawDesc = string([]byte{ 0x44, 0x53, 0x41, 0x5f, 0x50, 0x33, 0x38, 0x34, 0x5f, 0x53, 0x48, 0x41, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x13, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x1f, 0x0a, 0x17, 0x50, 0x4b, 0x49, 0x58, 0x5f, 0x45, 0x43, 0x44, 0x53, 0x41, 0x5f, 0x50, 0x35, 0x32, 0x31, 0x5f, 0x53, 0x48, 0x41, 0x5f, 0x32, 0x35, - 0x36, 0x10, 0x14, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4c, 0x4d, 0x53, 0x5f, 0x53, - 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4d, 0x4f, 0x54, 0x53, - 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x0f, 0x22, 0x04, 0x08, 0x15, 0x10, 0x32, 0x2a, - 0x6f, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x74, 0x69, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, - 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x41, 0x4c, 0x54, 0x45, 0x52, 0x4e, 0x41, - 0x54, 0x49, 0x56, 0x45, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, - 0x45, 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x52, 0x49, 0x10, 0x02, - 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x03, - 0x42, 0x7c, 0x0a, 0x1c, 0x64, 0x65, 0x76, 0x2e, 0x73, 0x69, 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x67, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2d, 0x73, 0x70, - 0x65, 0x63, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x62, 0x2d, 0x67, 0x6f, 0x2f, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x14, 0x53, 0x69, 0x67, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x36, 0x10, 0x14, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x12, 0x0a, 0x0a, 0x4c, 0x4d, 0x53, 0x5f, 0x53, + 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x0e, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x14, 0x0a, 0x0c, 0x4c, + 0x4d, 0x4f, 0x54, 0x53, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x0f, 0x1a, 0x02, 0x08, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x4c, 0x5f, 0x44, 0x53, 0x41, 0x5f, 0x36, 0x35, 0x10, 0x15, + 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x4c, 0x5f, 0x44, 0x53, 0x41, 0x5f, 0x38, 0x37, 0x10, 0x16, 0x22, + 0x04, 0x08, 0x17, 0x10, 0x32, 0x2a, 0x6f, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x41, + 0x4c, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x54, 0x49, 0x56, 0x45, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x41, 0x49, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, + 0x03, 0x55, 0x52, 0x49, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x5f, + 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x03, 0x42, 0x7c, 0x0a, 0x1c, 0x64, 0x65, 0x76, 0x2e, 0x73, 0x69, + 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x73, 0x69, 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2d, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x62, + 0x2d, 0x67, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0xea, 0x02, 0x14, + 0x53, 0x69, 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3a, 0x3a, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go index 1e2fa031be9..63e789a8d2d 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go @@ -16,7 +16,6 @@ package cryptoutils import ( - "context" "crypto" "crypto/ecdsa" "crypto/ed25519" @@ -29,8 +28,6 @@ import ( "encoding/pem" "errors" "fmt" - - "github.com/letsencrypt/boulder/goodkey" ) const ( @@ -133,54 +130,3 @@ func genErrMsg(first, second crypto.PublicKey, keyType string) string { } return fmt.Sprintf("%s (%s, %s)", msg, hex.EncodeToString(firstSKID), hex.EncodeToString(secondSKID)) } - -// ValidatePubKey validates the parameters of an RSA, ECDSA, or ED25519 public key. -func ValidatePubKey(pub crypto.PublicKey) error { - // goodkey policy enforces: - // * RSA - // * Size of key: 2048 <= size <= 4096, size % 8 = 0 - // * Exponent E = 65537 (Default exponent for OpenSSL and Golang) - // * Small primes check for modulus - // * Weak keys generated by Infineon hardware (see https://crocs.fi.muni.cz/public/papers/rsa_ccs17) - // * Key is easily factored with Fermat's factorization method - // * EC - // * Public key Q is not the identity element (Ø) - // * Public key Q's x and y are within [0, p-1] - // * Public key Q is on the curve - // * Public key Q's order matches the subgroups (nQ = Ø) - allowedKeys := &goodkey.AllowedKeys{ - RSA2048: true, - RSA3072: true, - RSA4096: true, - ECDSAP256: true, - ECDSAP384: true, - ECDSAP521: true, - } - cfg := &goodkey.Config{ - FermatRounds: 100, - AllowedKeys: allowedKeys, - } - p, err := goodkey.NewPolicy(cfg, nil) - if err != nil { - // Should not occur, only chances to return errors are if fermat rounds - // are <0 or when loading blocked/weak keys from disk (not used here) - return errors.New("unable to initialize key policy") - } - - switch pk := pub.(type) { - case *rsa.PublicKey: - // ctx is unused - return p.GoodKey(context.Background(), pub) - case *ecdsa.PublicKey: - // ctx is unused - return p.GoodKey(context.Background(), pub) - case ed25519.PublicKey: - return validateEd25519Key(pk) - } - return errors.New("unsupported public key type") -} - -// No validations currently, ED25519 supports only one key size. -func validateEd25519Key(_ ed25519.PublicKey) error { - return nil -} diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/safestring.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/safestring.go new file mode 100644 index 00000000000..cdc69aec377 --- /dev/null +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/safestring.go @@ -0,0 +1,34 @@ +// +// Copyright 2025 The Sigstore Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cryptoutils + +import ( + "crypto/rand" + "encoding/base64" +) + +// GenerateRandomURLSafeString generates a cryptographically secure random +// URL-safe string with the specified number of bits of entropy. +func GenerateRandomURLSafeString(entropyLength uint) string { + if entropyLength == 0 { + return "" + } + // Round up to the nearest byte to ensure minimum entropy is met + entropyBytes := (entropyLength + 7) / 8 + b := make([]byte, entropyBytes) + _, _ = rand.Read(b) + return base64.RawURLEncoding.EncodeToString(b) +} diff --git a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/sans.go b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/sans.go index d237ef58ea6..abcea306a03 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/sans.go +++ b/vendor/github.com/sigstore/sigstore/pkg/cryptoutils/sans.go @@ -132,6 +132,9 @@ func UnmarshalOtherNameSAN(exts []pkix.Extension) (string, error) { // and OtherName SANs func GetSubjectAlternateNames(cert *x509.Certificate) []string { sans := []string{} + if cert == nil { + return sans + } sans = append(sans, cert.DNSNames...) sans = append(sans, cert.EmailAddresses...) for _, ip := range cert.IPAddresses { diff --git a/vendor/github.com/sigstore/sigstore/pkg/oauthflow/interactive.go b/vendor/github.com/sigstore/sigstore/pkg/oauthflow/interactive.go index 6714b3488ee..de21064e453 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/oauthflow/interactive.go +++ b/vendor/github.com/sigstore/sigstore/pkg/oauthflow/interactive.go @@ -27,14 +27,14 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/segmentio/ksuid" - "github.com/skratchdot/open-golang/open" + "github.com/pkg/browser" + "github.com/sigstore/sigstore/pkg/cryptoutils" "golang.org/x/oauth2" ) const oobRedirectURI = "urn:ietf:wg:oauth:2.0:oob" -var browserOpener = open.Run +var browserOpener = browser.OpenURL // InteractiveIDTokenGetter is a type to get ID tokens for oauth flows type InteractiveIDTokenGetter struct { @@ -47,8 +47,8 @@ type InteractiveIDTokenGetter struct { // GetIDToken gets an OIDC ID Token from the specified provider using an interactive browser session func (i *InteractiveIDTokenGetter) GetIDToken(p *oidc.Provider, cfg oauth2.Config) (*OIDCIDToken, error) { // generate random fields and save them for comparison after OAuth2 dance - stateToken := randStr() - nonce := randStr() + stateToken := cryptoutils.GenerateRandomURLSafeString(128) + nonce := cryptoutils.GenerateRandomURLSafeString(128) doneCh := make(chan string) errCh := make(chan error) @@ -231,11 +231,3 @@ func getCode(doneCh chan string, errCh chan error) (string, error) { return "", errors.New("timeout") } } - -func randStr() string { - // we use ksuid here to ensure we get globally unique values to mitigate - // risk of replay attacks - - // output is a 27 character base62 string which is by default URL-safe - return ksuid.New().String() -} diff --git a/vendor/github.com/sigstore/sigstore/pkg/oauthflow/pkce.go b/vendor/github.com/sigstore/sigstore/pkg/oauthflow/pkce.go index be8e23b838f..9cce026dc7d 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/oauthflow/pkce.go +++ b/vendor/github.com/sigstore/sigstore/pkg/oauthflow/pkce.go @@ -22,6 +22,7 @@ import ( "regexp" "github.com/coreos/go-oidc/v3/oidc" + "github.com/sigstore/sigstore/pkg/cryptoutils" "golang.org/x/oauth2" ) @@ -66,9 +67,10 @@ func NewPKCE(provider *oidc.Provider) (*PKCE, error) { } } - // we use two 27 character strings to meet requirements of RFC 7636: + // The value must meet requirements of RFC 7636: // (minimum length of 43 characters and a maximum length of 128 characters) - value := randStr() + randStr() + // 384 bits of entropy (48 bytes) to be encoded in base64 URL-safe without padding yields 64 characters. + value := cryptoutils.GenerateRandomURLSafeString(384) h := sha256.New() _, _ = h.Write([]byte(value)) diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/message.go b/vendor/github.com/sigstore/sigstore/pkg/signature/message.go index 6f8449eea9c..44771ff3daa 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/message.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/message.go @@ -55,10 +55,10 @@ func ComputeDigestForSigning(rawMessage io.Reader, defaultHashFunc crypto.Hash, if hashedWith != crypto.Hash(0) && len(digest) != hashedWith.Size() { err = errors.New("unexpected length of digest for hash function specified") } - return + return digest, hashedWith, err } digest, err = hashMessage(rawMessage, hashedWith) - return + return digest, hashedWith, err } // ComputeDigestForVerifying calculates the digest value for the specified message using a hash function selected by the following process: @@ -81,10 +81,10 @@ func ComputeDigestForVerifying(rawMessage io.Reader, defaultHashFunc crypto.Hash if hashedWith != crypto.Hash(0) && len(digest) != hashedWith.Size() { err = errors.New("unexpected length of digest for hash function specified") } - return + return digest, hashedWith, err } digest, err = hashMessage(rawMessage, hashedWith) - return + return digest, hashedWith, err } func hashMessage(rawMessage io.Reader, hashFunc crypto.Hash) ([]byte, error) { diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go index 499789984d2..69956b425a1 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go @@ -1,4 +1,4 @@ -// +build darwin dragonfly freebsd netbsd openbsd +// +build darwin dragonfly freebsd netbsd openbsd hurd // +build !js package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go index 04748b8515f..c9aed267a4c 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go @@ -1,5 +1,7 @@ +//go:build (linux || aix || zos) && !js && !wasi // +build linux aix zos // +build !js +// +build !wasi package logrus diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go new file mode 100644 index 00000000000..2822b212fbf --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_wasi.go @@ -0,0 +1,8 @@ +//go:build wasi +// +build wasi + +package logrus + +func isTerminal(fd int) bool { + return false +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go b/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go new file mode 100644 index 00000000000..108a6be12b1 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_wasip1.go @@ -0,0 +1,8 @@ +//go:build wasip1 +// +build wasip1 + +package logrus + +func isTerminal(fd int) bool { + return false +} diff --git a/vendor/github.com/skratchdot/open-golang/LICENSE b/vendor/github.com/skratchdot/open-golang/LICENSE deleted file mode 100644 index afd04c82161..00000000000 --- a/vendor/github.com/skratchdot/open-golang/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2013 skratchdot - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/skratchdot/open-golang/open/exec.go b/vendor/github.com/skratchdot/open-golang/open/exec.go deleted file mode 100644 index 1b0e713685c..00000000000 --- a/vendor/github.com/skratchdot/open-golang/open/exec.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !windows,!darwin - -package open - -import ( - "os/exec" -) - -// http://sources.debian.net/src/xdg-utils/1.1.0~rc1%2Bgit20111210-7.1/scripts/xdg-open/ -// http://sources.debian.net/src/xdg-utils/1.1.0~rc1%2Bgit20111210-7.1/scripts/xdg-mime/ - -func open(input string) *exec.Cmd { - return exec.Command("xdg-open", input) -} - -func openWith(input string, appName string) *exec.Cmd { - return exec.Command(appName, input) -} diff --git a/vendor/github.com/skratchdot/open-golang/open/exec_darwin.go b/vendor/github.com/skratchdot/open-golang/open/exec_darwin.go deleted file mode 100644 index 16160e6f043..00000000000 --- a/vendor/github.com/skratchdot/open-golang/open/exec_darwin.go +++ /dev/null @@ -1,15 +0,0 @@ -// +build darwin - -package open - -import ( - "os/exec" -) - -func open(input string) *exec.Cmd { - return exec.Command("open", input) -} - -func openWith(input string, appName string) *exec.Cmd { - return exec.Command("open", "-a", appName, input) -} diff --git a/vendor/github.com/skratchdot/open-golang/open/exec_windows.go b/vendor/github.com/skratchdot/open-golang/open/exec_windows.go deleted file mode 100644 index 6e46c005427..00000000000 --- a/vendor/github.com/skratchdot/open-golang/open/exec_windows.go +++ /dev/null @@ -1,33 +0,0 @@ -// +build windows - -package open - -import ( - "os" - "os/exec" - "path/filepath" - "strings" - // "syscall" -) - -var ( - cmd = "url.dll,FileProtocolHandler" - runDll32 = filepath.Join(os.Getenv("SYSTEMROOT"), "System32", "rundll32.exe") -) - -func cleaninput(input string) string { - r := strings.NewReplacer("&", "^&") - return r.Replace(input) -} - -func open(input string) *exec.Cmd { - cmd := exec.Command(runDll32, cmd, input) - //cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - return cmd -} - -func openWith(input string, appName string) *exec.Cmd { - cmd := exec.Command("cmd", "/C", "start", "", appName, cleaninput(input)) - //cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - return cmd -} diff --git a/vendor/github.com/skratchdot/open-golang/open/open.go b/vendor/github.com/skratchdot/open-golang/open/open.go deleted file mode 100644 index b1f648ff51e..00000000000 --- a/vendor/github.com/skratchdot/open-golang/open/open.go +++ /dev/null @@ -1,50 +0,0 @@ -/* - - Open a file, directory, or URI using the OS's default - application for that object type. Optionally, you can - specify an application to use. - - This is a proxy for the following commands: - - OSX: "open" - Windows: "start" - Linux/Other: "xdg-open" - - This is a golang port of the node.js module: https://github.com/pwnall/node-open - -*/ -package open - -/* - Open a file, directory, or URI using the OS's default - application for that object type. Wait for the open - command to complete. -*/ -func Run(input string) error { - return open(input).Run() -} - -/* - Open a file, directory, or URI using the OS's default - application for that object type. Don't wait for the - open command to complete. -*/ -func Start(input string) error { - return open(input).Start() -} - -/* - Open a file, directory, or URI using the specified application. - Wait for the open command to complete. -*/ -func RunWith(input string, appName string) error { - return openWith(input, appName).Run() -} - -/* - Open a file, directory, or URI using the specified application. - Don't wait for the open command to complete. -*/ -func StartWith(input string, appName string) error { - return openWith(input, appName).Start() -} diff --git a/vendor/github.com/titanous/rocacheck/LICENSE b/vendor/github.com/titanous/rocacheck/LICENSE deleted file mode 100644 index 7bdce481fa2..00000000000 --- a/vendor/github.com/titanous/rocacheck/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2017, Jonathan Rudenberg -Copyright (c) 2017, CRoCS, EnigmaBridge Ltd. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/titanous/rocacheck/README.md b/vendor/github.com/titanous/rocacheck/README.md deleted file mode 100644 index b8e765ea9c4..00000000000 --- a/vendor/github.com/titanous/rocacheck/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# rocacheck [![GoDoc](https://godoc.org/github.com/titanous/rocacheck?status.svg)](https://godoc.org/github.com/titanous/rocacheck) - -Package rocacheck is a Go implementation of the [key fingerprint -algorithm](https://github.com/crocs-muni/roca) that checks if an RSA key was -generated by broken Infineon code and is vulnerable to factorization via the -[Return of Coppersmith's Attack -(ROCA)](https://crocs.fi.muni.cz/public/papers/rsa_ccs17) / CVE-2017-15361. diff --git a/vendor/github.com/titanous/rocacheck/rocacheck.go b/vendor/github.com/titanous/rocacheck/rocacheck.go deleted file mode 100644 index e813579bb87..00000000000 --- a/vendor/github.com/titanous/rocacheck/rocacheck.go +++ /dev/null @@ -1,52 +0,0 @@ -// Package rocacheck checks if a key was generated by broken Infineon code and -// is vulnerable to factorization via the Return of Coppersmith's Attack (ROCA) -// / CVE-2017-15361. -package rocacheck - -import ( - "crypto/rsa" - "math/big" -) - -type test struct { - Prime *big.Int - Fingerprints map[int64]struct{} -} - -var tests = make([]test, 17) - -func init() { - bigOne := big.NewInt(1) - n := &big.Int{} - // relations table from https://github.com/crocs-muni/roca/pull/40 - for i, r := range [][2]int64{ - {2, 11}, {6, 13}, {8, 17}, {9, 19}, {3, 37}, {26, 53}, {20, 61}, - {35, 71}, {24, 73}, {13, 79}, {6, 97}, {51, 103}, {53, 107}, - {54, 109}, {42, 127}, {50, 151}, {78, 157}, - } { - fps := make(map[int64]struct{}) - bp := big.NewInt(r[1]) - br := big.NewInt(r[0]) - for j := int64(0); j < r[1]; j++ { - if n.Exp(big.NewInt(j), br, bp).Cmp(bigOne) == 0 { - fps[j] = struct{}{} - } - } - tests[i] = test{ - Prime: big.NewInt(r[1]), - Fingerprints: fps, - } - } -} - -// IsWeak returns true if a RSA public key is vulnerable to Return of -// Coppersmith's Attack (ROCA). -func IsWeak(k *rsa.PublicKey) bool { - tmp := &big.Int{} - for _, t := range tests { - if _, ok := t.Fingerprints[tmp.Mod(k.N, t.Prime).Int64()]; !ok { - return false - } - } - return true -} diff --git a/vendor/go.podman.io/common/libnetwork/cni/network.go b/vendor/go.podman.io/common/libnetwork/cni/network.go index 8a22773388a..33220a2827b 100644 --- a/vendor/go.podman.io/common/libnetwork/cni/network.go +++ b/vendor/go.podman.io/common/libnetwork/cni/network.go @@ -327,9 +327,10 @@ func (n *cniNetwork) NetworkInfo() types.NetworkInfo { } info := types.NetworkInfo{ - Backend: types.CNI, - Package: packageVersion, - Path: path, + Backend: types.CNI, + Package: packageVersion, + Path: path, + DefaultNetwork: n.defaultNetwork, } dnsPath := filepath.Join(path, "dnsname") diff --git a/vendor/go.podman.io/common/libnetwork/netavark/network.go b/vendor/go.podman.io/common/libnetwork/netavark/network.go index 855023db7d8..9dbe3b452da 100644 --- a/vendor/go.podman.io/common/libnetwork/netavark/network.go +++ b/vendor/go.podman.io/common/libnetwork/netavark/network.go @@ -369,10 +369,11 @@ func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo { logrus.Infof("Failed to get the netavark version: %v", err) } info := types.NetworkInfo{ - Backend: types.Netavark, - Version: programVersion, - Package: packageVersion, - Path: path, + Backend: types.Netavark, + Version: programVersion, + Package: packageVersion, + Path: path, + DefaultNetwork: n.defaultNetwork, } dnsPath := n.aardvarkBinary diff --git a/vendor/go.podman.io/common/libnetwork/types/network.go b/vendor/go.podman.io/common/libnetwork/types/network.go index 5b15d080372..4471f6c507f 100644 --- a/vendor/go.podman.io/common/libnetwork/types/network.go +++ b/vendor/go.podman.io/common/libnetwork/types/network.go @@ -97,11 +97,12 @@ type NetworkUpdateOptions struct { // NetworkInfo contains the network information. type NetworkInfo struct { - Backend NetworkBackend `json:"backend"` - Version string `json:"version,omitempty"` - Package string `json:"package,omitempty"` - Path string `json:"path,omitempty"` - DNS DNSNetworkInfo `json:"dns,omitempty"` + Backend NetworkBackend `json:"backend"` + Version string `json:"version,omitempty"` + Package string `json:"package,omitempty"` + Path string `json:"path,omitempty"` + DNS DNSNetworkInfo `json:"dns,omitempty"` + DefaultNetwork string `json:"default_network,omitempty"` } // DNSNetworkInfo contains the DNS information. diff --git a/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go b/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go index 4d85ba4a707..c12bb09580f 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/blkio_linux.go @@ -3,145 +3,55 @@ package cgroups import ( - "bufio" - "errors" - "fmt" - "os" - "path/filepath" "strconv" "strings" "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fs" - "github.com/opencontainers/cgroups/fs2" ) -type linuxBlkioHandler struct { - Blkio fs.BlkioGroup -} - -func getBlkioHandler() *linuxBlkioHandler { - return &linuxBlkioHandler{} -} - -// Apply set the specified constraints. -func (c *linuxBlkioHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) - } - path := filepath.Join(cgroupRoot, Blkio, ctr.config.Path) - return c.Blkio.Set(path, res) -} - -// Create the cgroup. -func (c *linuxBlkioHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Blkio) -} - -// Destroy the cgroup. -func (c *linuxBlkioHandler) Destroy(ctr *CgroupControl) error { - return rmDirRecursively(ctr.getCgroupv1Path(Blkio)) -} - -// Stat fills a metrics structure with usage stats for the controller. -func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { +// blkioStat fills a metrics structure with usage stats for the blkio controller. +func blkioStat(ctr *CgroupControl, m *cgroups.Stats) error { var ioServiceBytesRecursive []cgroups.BlkioStatEntry - if ctr.cgroup2 { - // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html - values, err := readCgroup2MapFile(ctr, "io.stat") + // more details on the io.stat file format:X https://facebookmicrosites.github.io/cgroup2/docs/io-controller.html + values, err := readCgroup2MapFile(ctr, "io.stat") + if err != nil { + return err + } + for k, v := range values { + d := strings.Split(k, ":") + if len(d) != 2 { + continue + } + minor, err := strconv.ParseUint(d[0], 10, 0) if err != nil { return err } - for k, v := range values { - d := strings.Split(k, ":") - if len(d) != 2 { - continue - } - minor, err := strconv.ParseUint(d[0], 10, 0) - if err != nil { - return err - } - major, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err - } - - for _, item := range v { - d := strings.Split(item, "=") - if len(d) != 2 { - continue - } - op := d[0] - - // Accommodate the cgroup v1 naming - switch op { - case "rbytes": - op = "read" - case "wbytes": - op = "write" - } - - value, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err - } - - entry := cgroups.BlkioStatEntry{ - Op: op, - Major: major, - Minor: minor, - Value: value, - } - ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) - } - } - } else { - BlkioRoot := ctr.getCgroupv1Path(Blkio) - - p := filepath.Join(BlkioRoot, "blkio.throttle.io_service_bytes_recursive") - f, err := os.Open(p) + major, err := strconv.ParseUint(d[1], 10, 0) if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil - } - return fmt.Errorf("open %s: %w", p, err) + return err } - defer f.Close() - scanner := bufio.NewScanner(f) - for scanner.Scan() { - line := scanner.Text() - parts := strings.Fields(line) - if len(parts) < 3 { - continue - } - d := strings.Split(parts[0], ":") + for _, item := range v { + d := strings.Split(item, "=") if len(d) != 2 { continue } - minor, err := strconv.ParseUint(d[0], 10, 0) - if err != nil { - return err + op := d[0] + + // Accommodate the cgroup v1 naming + switch op { + case "rbytes": + op = "read" + case "wbytes": + op = "write" } - major, err := strconv.ParseUint(d[1], 10, 0) - if err != nil { - return err - } - - op := parts[1] - value, err := strconv.ParseUint(parts[2], 10, 0) + value, err := strconv.ParseUint(d[1], 10, 0) if err != nil { return err } + entry := cgroups.BlkioStatEntry{ Op: op, Major: major, @@ -150,9 +60,6 @@ func (c *linuxBlkioHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { } ioServiceBytesRecursive = append(ioServiceBytesRecursive, entry) } - if err := scanner.Err(); err != nil { - return fmt.Errorf("parse %s: %w", p, err) - } } m.BlkioStats.IoServiceBytesRecursive = ioServiceBytesRecursive return nil diff --git a/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go index 1c66a8d9cc4..f7ac8ba12cd 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cgroups_linux.go @@ -8,11 +8,9 @@ import ( "context" "errors" "fmt" - "maps" "math" "os" "path/filepath" - "slices" "strconv" "strings" "sync" @@ -23,7 +21,6 @@ import ( "github.com/godbus/dbus/v5" "github.com/opencontainers/cgroups" "github.com/opencontainers/cgroups/fs2" - "github.com/sirupsen/logrus" "go.podman.io/storage/pkg/fileutils" "go.podman.io/storage/pkg/unshare" "golang.org/x/sys/unix" @@ -32,9 +29,7 @@ import ( var ( // ErrCgroupDeleted means the cgroup was deleted. ErrCgroupDeleted = errors.New("cgroup deleted") - // ErrCgroupV1Rootless means the cgroup v1 were attempted to be used in rootless environment. - ErrCgroupV1Rootless = errors.New("no support for CGroups V1 in rootless environments") - ErrStatCgroup = errors.New("no cgroup available for gathering user statistics") + ErrStatCgroup = errors.New("no cgroup available for gathering user statistics") isUnifiedOnce sync.Once isUnified bool @@ -43,34 +38,17 @@ var ( // CgroupControl controls a cgroup hierarchy. type CgroupControl struct { - cgroup2 bool config *cgroups.Cgroup systemd bool - // List of additional cgroup subsystems joined that - // do not have a custom handler. - additionalControllers []controller } -type controller struct { - name string - symlink bool -} - -type controllerHandler interface { - Create(*CgroupControl) (bool, error) - Apply(*CgroupControl, *cgroups.Resources) error - Destroy(*CgroupControl) error - Stat(*CgroupControl, *cgroups.Stats) error -} +// statFunc is a function that gathers statistics for a cgroup controller. +type statFunc func(*CgroupControl, *cgroups.Stats) error const ( cgroupRoot = "/sys/fs/cgroup" // CPU is the cpu controller. CPU = "cpu" - // CPUAcct is the cpuacct controller. - CPUAcct = "cpuacct" - // CPUset is the cpuset controller. - CPUset = "cpuset" // Memory is the memory controller. Memory = "memory" // Pids is the pids controller. @@ -79,110 +57,36 @@ const ( Blkio = "blkio" ) -var handlers map[string]controllerHandler - -func init() { - handlers = map[string]controllerHandler{ - CPU: getCPUHandler(), - CPUset: getCpusetHandler(), - Memory: getMemoryHandler(), - Pids: getPidsHandler(), - Blkio: getBlkioHandler(), - } +var handlers = map[string]statFunc{ + CPU: cpuStat, + Memory: memoryStat, + Pids: pidsStat, + Blkio: blkioStat, } -// getAvailableControllers get the available controllers. -func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]controller, error) { - if cgroup2 { - controllers := []controller{} - controllersFile := filepath.Join(cgroupRoot, "cgroup.controllers") - - // rootless cgroupv2: check available controllers for current user, systemd or servicescope will inherit - if unshare.IsRootless() { - userSlice, err := getCgroupPathForCurrentProcess() - if err != nil { - return controllers, err - } - // userSlice already contains '/' so not adding here - basePath := cgroupRoot + userSlice - controllersFile = filepath.Join(basePath, "cgroup.controllers") - } - controllersFileBytes, err := os.ReadFile(controllersFile) - if err != nil { - return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err) - } - for controllerName := range strings.FieldsSeq(string(controllersFileBytes)) { - c := controller{ - name: controllerName, - symlink: false, - } - controllers = append(controllers, c) - } - return controllers, nil - } +// AvailableControllers get string:bool map of all the available controllers. +func AvailableControllers() ([]string, error) { + controllers := []string{} + controllersFile := filepath.Join(cgroupRoot, "cgroup.controllers") - subsystems, _ := cgroupV1GetAllSubsystems() - controllers := []controller{} - // cgroupv1 and rootless: No subsystem is available: delegation is unsafe. + // rootless cgroupv2: check available controllers for current user, systemd or servicescope will inherit if unshare.IsRootless() { - return controllers, nil - } - - for _, name := range subsystems { - if _, found := exclude[name]; found { - continue - } - fileInfo, err := os.Stat(cgroupRoot + "/" + name) + userSlice, err := getCgroupPathForCurrentProcess() if err != nil { - continue - } - c := controller{ - name: name, - symlink: !fileInfo.IsDir(), + return controllers, err } - controllers = append(controllers, c) - } - - return controllers, nil -} - -// AvailableControllers get string:bool map of all the available controllers. -func AvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]string, error) { - availableControllers, err := getAvailableControllers(exclude, cgroup2) - if err != nil { - return nil, err - } - controllerList := []string{} - for _, controller := range availableControllers { - controllerList = append(controllerList, controller.name) + // userSlice already contains '/' so not adding here + basePath := cgroupRoot + userSlice + controllersFile = filepath.Join(basePath, "cgroup.controllers") } - - return controllerList, nil -} - -func cgroupV1GetAllSubsystems() ([]string, error) { - f, err := os.Open("/proc/cgroups") + controllersFileBytes, err := os.ReadFile(controllersFile) if err != nil { - return nil, err - } - defer f.Close() - - subsystems := []string{} - - s := bufio.NewScanner(f) - for s.Scan() { - text := s.Text() - if text[0] != '#' { - parts := strings.Fields(text) - if len(parts) >= 4 && parts[3] != "0" { - subsystems = append(subsystems, parts[0]) - } - } + return nil, fmt.Errorf("failed while reading controllers for cgroup v2: %w", err) } - if err := s.Err(); err != nil { - return nil, err + for controllerName := range strings.FieldsSeq(string(controllersFileBytes)) { + controllers = append(controllers, controllerName) } - return subsystems, nil + return controllers, nil } func getCgroupPathForCurrentProcess() (string, error) { @@ -208,51 +112,11 @@ func getCgroupPathForCurrentProcess() (string, error) { return cgroupPath, nil } -// getCgroupv1Path is a helper function to get the cgroup v1 path. -func (c *CgroupControl) getCgroupv1Path(name string) string { - return filepath.Join(cgroupRoot, name, c.config.Path) -} - // initialize initializes the specified hierarchy. func (c *CgroupControl) initialize() (err error) { - createdSoFar := map[string]controllerHandler{} - defer func() { - if err != nil { - for name, ctr := range createdSoFar { - if err := ctr.Destroy(c); err != nil { - logrus.Warningf("error cleaning up controller %s for %s", name, c.config.Path) - } - } - } - }() - if c.cgroup2 { - if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.config.Path)); err != nil { - return fmt.Errorf("creating cgroup path %s: %w", c.config.Path, err) - } + if err := createCgroupv2Path(filepath.Join(cgroupRoot, c.config.Path)); err != nil { + return fmt.Errorf("creating cgroup path %s: %w", c.config.Path, err) } - for name, handler := range handlers { - created, err := handler.Create(c) - if err != nil { - return err - } - if created { - createdSoFar[name] = handler - } - } - - if !c.cgroup2 { - // We won't need to do this for cgroup v2 - for _, ctr := range c.additionalControllers { - if ctr.symlink { - continue - } - path := c.getCgroupv1Path(ctr.name) - if err := os.MkdirAll(path, 0o755); err != nil { - return fmt.Errorf("creating cgroup path for %s: %w", ctr.name, err) - } - } - } - return nil } @@ -297,26 +161,17 @@ func readFileByKeyAsUint64(path, key string) (uint64, error) { // New creates a new cgroup control. func New(path string, resources *cgroups.Resources) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { return nil, err } control := &CgroupControl{ - cgroup2: cgroup2, config: &cgroups.Cgroup{ Path: path, Resources: resources, }, } - if !cgroup2 { - controllers, err := getAvailableControllers(handlers, false) - if err != nil { - return nil, err - } - control.additionalControllers = controllers - } - if err := control.initialize(); err != nil { return nil, err } @@ -326,12 +181,11 @@ func New(path string, resources *cgroups.Resources) (*CgroupControl, error) { // NewSystemd creates a new cgroup control. func NewSystemd(path string, resources *cgroups.Resources) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { return nil, err } control := &CgroupControl{ - cgroup2: cgroup2, systemd: true, config: &cgroups.Cgroup{ Path: path, @@ -345,45 +199,16 @@ func NewSystemd(path string, resources *cgroups.Resources) (*CgroupControl, erro // Load loads an existing cgroup control. func Load(path string) (*CgroupControl, error) { - cgroup2, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { return nil, err } control := &CgroupControl{ - cgroup2: cgroup2, systemd: false, config: &cgroups.Cgroup{ Path: path, }, } - if !cgroup2 { - controllers, err := getAvailableControllers(handlers, false) - if err != nil { - return nil, err - } - control.additionalControllers = controllers - } - if !cgroup2 { - oneExists := false - // check that the cgroup exists at least under one controller - for name := range handlers { - p := control.getCgroupv1Path(name) - if err := fileutils.Exists(p); err == nil { - oneExists = true - break - } - } - - // if there is no controller at all, raise an error - if !oneExists { - if unshare.IsRootless() { - return nil, ErrCgroupV1Rootless - } - // compatible with the error code - // used by containerd/cgroups - return nil, ErrCgroupDeleted - } - } return control, nil } @@ -448,26 +273,7 @@ func (c *CgroupControl) DeleteByPathConn(path string, conn *systemdDbus.Conn) er if c.systemd { return systemdDestroyConn(path, conn) } - if c.cgroup2 { - return rmDirRecursively(filepath.Join(cgroupRoot, c.config.Path)) - } - var lastError error - for _, h := range handlers { - if err := h.Destroy(c); err != nil { - lastError = err - } - } - - for _, ctr := range c.additionalControllers { - if ctr.symlink { - continue - } - p := c.getCgroupv1Path(ctr.name) - if err := rmDirRecursively(p); err != nil { - lastError = fmt.Errorf("remove %s: %w", p, err) - } - } - return lastError + return rmDirRecursively(filepath.Join(cgroupRoot, c.config.Path)) } // DeleteByPath deletes the specified cgroup path. @@ -485,50 +291,25 @@ func (c *CgroupControl) DeleteByPath(path string) error { // Update updates the cgroups. func (c *CgroupControl) Update(resources *cgroups.Resources) error { - for _, h := range handlers { - if err := h.Apply(c, resources); err != nil { - return err - } + man, err := fs2.NewManager(c.config, filepath.Join(cgroupRoot, c.config.Path)) + if err != nil { + return err } - return nil + return man.Set(resources) } // AddPid moves the specified pid to the cgroup. func (c *CgroupControl) AddPid(pid int) error { - pidString := []byte(fmt.Sprintf("%d\n", pid)) - - if c.cgroup2 { - path := filepath.Join(cgroupRoot, c.config.Path) - return fs2.CreateCgroupPath(path, c.config) - } - - names := slices.Collect(maps.Keys(handlers)) - - for _, c := range c.additionalControllers { - if !c.symlink { - names = append(names, c.name) - } - } - - for _, n := range names { - // If we aren't using cgroup2, we won't write correctly to unified hierarchy - if !c.cgroup2 && n == "unified" { - continue - } - p := filepath.Join(c.getCgroupv1Path(n), "tasks") - if err := os.WriteFile(p, pidString, 0o644); err != nil { - return fmt.Errorf("write %s: %w", p, err) - } - } - return nil + path := filepath.Join(cgroupRoot, c.config.Path) + return fs2.CreateCgroupPath(path, c.config) } // Stat returns usage statistics for the cgroup. func (c *CgroupControl) Stat() (*cgroups.Stats, error) { m := cgroups.Stats{} found := false - for _, h := range handlers { - if err := h.Stat(c, &m); err != nil { + for _, statFunc := range handlers { + if err := statFunc(c, &m); err != nil { if !errors.Is(err, os.ErrNotExist) { return nil, err } @@ -573,23 +354,6 @@ func readCgroup2MapFile(ctr *CgroupControl, name string) (map[string][]string, e return readCgroupMapPath(p) } -func (c *CgroupControl) createCgroupDirectory(controller string) (bool, error) { - cPath := c.getCgroupv1Path(controller) - err := fileutils.Exists(cPath) - if err == nil { - return false, nil - } - - if !errors.Is(err, os.ErrNotExist) { - return false, err - } - - if err := os.MkdirAll(cPath, 0o755); err != nil { - return false, fmt.Errorf("creating cgroup for %s: %w", controller, err) - } - return true, nil -} - var TestMode bool func createCgroupv2Path(path string) (deferredError error) { @@ -671,83 +435,12 @@ func cleanString(s string) string { return strings.Trim(s, "\n") } -func readAcct(ctr *CgroupControl, name string) (uint64, error) { - p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name) - return readFileAsUint64(p) -} - -func readAcctList(ctr *CgroupControl, name string) ([]uint64, error) { - p := filepath.Join(ctr.getCgroupv1Path(CPUAcct), name) - data, err := os.ReadFile(p) - if err != nil { - return nil, err - } - r := []uint64{} - for s := range strings.SplitSeq(string(data), " ") { - s = cleanString(s) - if s == "" { - break - } - v, err := strconv.ParseUint(s, 10, 64) - if err != nil { - return nil, fmt.Errorf("parsing %s: %w", s, err) - } - r = append(r, v) - } - return r, nil -} - -func cpusetCopyFromParent(path string, cgroupv2 bool) error { - for _, file := range []string{"cpuset.cpus", "cpuset.mems"} { - if _, err := cpusetCopyFileFromParent(path, file, cgroupv2); err != nil { - return err - } - } - return nil -} - -func cpusetCopyFileFromParent(dir, file string, cgroupv2 bool) ([]byte, error) { - if dir == cgroupRoot { - return nil, fmt.Errorf("could not find parent to initialize cpuset %s", file) - } - path := filepath.Join(dir, file) - parentPath := path - if cgroupv2 { - parentPath += ".effective" - } - data, err := os.ReadFile(parentPath) - if err != nil { - // if the file doesn't exist, it is likely that the cpuset controller - // is not enabled in the kernel. - if os.IsNotExist(err) { - return nil, nil - } - return nil, err - } - if strings.Trim(string(data), "\n") != "" { - return data, nil - } - data, err = cpusetCopyFileFromParent(filepath.Dir(dir), file, cgroupv2) - if err != nil { - return nil, err - } - if err := os.WriteFile(path, data, 0o644); err != nil { - return nil, fmt.Errorf("write %s: %w", path, err) - } - return data, nil -} - // SystemCPUUsage returns the system usage for all the cgroups. func SystemCPUUsage() (uint64, error) { - cgroupv2, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { return 0, err } - if !cgroupv2 { - p := filepath.Join(cgroupRoot, CPUAcct, "cpuacct.usage") - return readFileAsUint64(p) - } - files, err := os.ReadDir(cgroupRoot) if err != nil { return 0, err @@ -800,7 +493,7 @@ func UserConnection(uid int) (*systemdDbus.Conn, error) { func UserOwnsCurrentSystemdCgroup() (bool, error) { uid := os.Geteuid() - cgroup2, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { return false, err } @@ -822,20 +515,11 @@ func UserOwnsCurrentSystemdCgroup() (bool, error) { // If we are on a cgroup v2 system and there are cgroup v1 controllers // mounted, ignore them when the current process is at the root cgroup. - if cgroup2 && parts[1] != "" && parts[2] == "/" { + if parts[1] != "" && parts[2] == "/" { continue } - var cgroupPath string - - if cgroup2 { - cgroupPath = filepath.Join(cgroupRoot, parts[2]) - } else { - if parts[1] != "name=systemd" { - continue - } - cgroupPath = filepath.Join(cgroupRoot, "systemd", parts[2]) - } + cgroupPath := filepath.Join(cgroupRoot, parts[2]) st, err := os.Stat(cgroupPath) if err != nil { diff --git a/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go index 899a86d5d39..ced72399875 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/cpu_linux.go @@ -3,95 +3,31 @@ package cgroups import ( - "errors" - "os" - "path/filepath" "strconv" "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fs" - "github.com/opencontainers/cgroups/fs2" ) -type linuxCPUHandler struct { - CPU fs.CpuGroup -} - -func getCPUHandler() *linuxCPUHandler { - return &linuxCPUHandler{} -} - -// Apply set the specified constraints. -func (c *linuxCPUHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) +// cpuStat fills a metrics structure with usage stats for the cpu controller. +func cpuStat(ctr *CgroupControl, m *cgroups.Stats) error { + cpu := cgroups.CpuStats{} + values, err := readCgroup2MapFile(ctr, "cpu.stat") + if err != nil { + return err + } + if val, found := values["usage_usec"]; found { + cpu.CpuUsage.TotalUsage, err = strconv.ParseUint(cleanString(val[0]), 10, 64) if err != nil { return err } - return man.Set(res) + cpu.CpuUsage.TotalUsage *= 1000 } - path := filepath.Join(cgroupRoot, CPU, ctr.config.Path) - return c.CPU.Set(path, res) -} - -// Create the cgroup. -func (c *linuxCPUHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(CPU) -} - -// Destroy the cgroup. -func (c *linuxCPUHandler) Destroy(ctr *CgroupControl) error { - return rmDirRecursively(ctr.getCgroupv1Path(CPU)) -} - -// Stat fills a metrics structure with usage stats for the controller. -func (c *linuxCPUHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { - var err error - cpu := cgroups.CpuStats{} - if ctr.cgroup2 { - values, err := readCgroup2MapFile(ctr, "cpu.stat") + if val, found := values["system_usec"]; found { + cpu.CpuUsage.UsageInKernelmode, err = strconv.ParseUint(cleanString(val[0]), 10, 64) if err != nil { return err } - if val, found := values["usage_usec"]; found { - cpu.CpuUsage.TotalUsage, err = strconv.ParseUint(cleanString(val[0]), 10, 64) - if err != nil { - return err - } - cpu.CpuUsage.UsageInKernelmode *= 1000 - } - if val, found := values["system_usec"]; found { - cpu.CpuUsage.UsageInKernelmode, err = strconv.ParseUint(cleanString(val[0]), 10, 64) - if err != nil { - return err - } - cpu.CpuUsage.TotalUsage *= 1000 - } - } else { - cpu.CpuUsage.TotalUsage, err = readAcct(ctr, "cpuacct.usage") - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.TotalUsage = 0 - } - cpu.CpuUsage.UsageInKernelmode, err = readAcct(ctr, "cpuacct.usage_sys") - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.UsageInKernelmode = 0 - } - cpu.CpuUsage.PercpuUsage, err = readAcctList(ctr, "cpuacct.usage_percpu") - if err != nil { - if !errors.Is(err, os.ErrNotExist) { - return err - } - cpu.CpuUsage.PercpuUsage = nil - } + cpu.CpuUsage.UsageInKernelmode *= 1000 } m.CpuStats = cpu return nil diff --git a/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go b/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go deleted file mode 100644 index 10b2298e12a..00000000000 --- a/vendor/go.podman.io/common/pkg/cgroups/cpuset_linux.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build linux - -package cgroups - -import ( - "path/filepath" - - "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fs" - "github.com/opencontainers/cgroups/fs2" -) - -type linuxCpusetHandler struct { - CPUSet fs.CpusetGroup -} - -func getCpusetHandler() *linuxCpusetHandler { - return &linuxCpusetHandler{} -} - -// Apply set the specified constraints. -func (c *linuxCpusetHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) - } - path := filepath.Join(cgroupRoot, CPUset, ctr.config.Path) - return c.CPUSet.Set(path, res) -} - -// Create the cgroup. -func (c *linuxCpusetHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - path := filepath.Join(cgroupRoot, ctr.config.Path) - return true, cpusetCopyFromParent(path, true) - } - created, err := ctr.createCgroupDirectory(CPUset) - if !created || err != nil { - return created, err - } - return true, cpusetCopyFromParent(ctr.getCgroupv1Path(CPUset), false) -} - -// Destroy the cgroup. -func (c *linuxCpusetHandler) Destroy(ctr *CgroupControl) error { - return rmDirRecursively(ctr.getCgroupv1Path(CPUset)) -} - -// Stat fills a metrics structure with usage stats for the controller. -func (c *linuxCpusetHandler) Stat(_ *CgroupControl, _ *cgroups.Stats) error { - return nil -} diff --git a/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go b/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go index 7f619003080..52cf606efe8 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/memory_linux.go @@ -6,94 +6,35 @@ import ( "path/filepath" "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fs" - "github.com/opencontainers/cgroups/fs2" ) -type linuxMemHandler struct { - Mem fs.MemoryGroup -} - -func getMemoryHandler() *linuxMemHandler { - return &linuxMemHandler{} -} - -// Apply set the specified constraints. -func (c *linuxMemHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) - } - path := filepath.Join(cgroupRoot, Memory, ctr.config.Path) - return c.Mem.Set(path, res) -} - -// Create the cgroup. -func (c *linuxMemHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Memory) -} - -// Destroy the cgroup. -func (c *linuxMemHandler) Destroy(ctr *CgroupControl) error { - return rmDirRecursively(ctr.getCgroupv1Path(Memory)) -} - -// Stat fills a metrics structure with usage stats for the controller. -func (c *linuxMemHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { +// memoryStat fills a metrics structure with usage stats for the memory controller. +func memoryStat(ctr *CgroupControl, m *cgroups.Stats) error { var err error memUsage := cgroups.MemoryStats{} var memoryRoot string var limitFilename string - if ctr.cgroup2 { - memoryRoot = filepath.Join(cgroupRoot, ctr.config.Path) - limitFilename = "memory.max" - - // Read memory.current - current, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.current")) - if err != nil { - return err - } - - // Read inactive_file from memory.stat - inactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "inactive_file") - if err != nil { - return err - } + memoryRoot = filepath.Join(cgroupRoot, ctr.config.Path) + limitFilename = "memory.max" - // Docker calculation: memory.current - memory.stat['inactive_file'] - memUsage.Usage.Usage = 0 - if inactiveFile < current { - memUsage.Usage.Usage = current - inactiveFile - } - } else { - memoryRoot = ctr.getCgroupv1Path(Memory) - limitFilename = "memory.limit_in_bytes" - - // Read memory.usage_in_bytes - usageInBytes, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.usage_in_bytes")) - if err != nil { - return err - } + // Read memory.current + current, err := readFileAsUint64(filepath.Join(memoryRoot, "memory.current")) + if err != nil { + return err + } - // Read total_inactive_file from memory.stat - totalInactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "total_inactive_file") - if err != nil { - return err - } + // Read inactive_file from memory.stat + inactiveFile, err := readFileByKeyAsUint64(filepath.Join(memoryRoot, "memory.stat"), "inactive_file") + if err != nil { + return err + } - // Docker calculation: memory.usage_in_bytes - memory.stat['total_inactive_file'] - memUsage.Usage.Usage = 0 - if totalInactiveFile < usageInBytes { - memUsage.Usage.Usage = usageInBytes - totalInactiveFile - } + // Docker calculation: memory.current - memory.stat['inactive_file'] + memUsage.Usage.Usage = 0 + if inactiveFile < current { + memUsage.Usage.Usage = current - inactiveFile } memUsage.Usage.Limit, err = readFileAsUint64(filepath.Join(memoryRoot, limitFilename)) diff --git a/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go b/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go index 82202830e02..4b29a34ea9f 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/pids_linux.go @@ -6,58 +6,16 @@ import ( "path/filepath" "github.com/opencontainers/cgroups" - "github.com/opencontainers/cgroups/fs" - "github.com/opencontainers/cgroups/fs2" ) -type linuxPidHandler struct { - Pid fs.PidsGroup -} - -func getPidsHandler() *linuxPidHandler { - return &linuxPidHandler{} -} - -// Apply set the specified constraints. -func (c *linuxPidHandler) Apply(ctr *CgroupControl, res *cgroups.Resources) error { - if ctr.cgroup2 { - man, err := fs2.NewManager(ctr.config, filepath.Join(cgroupRoot, ctr.config.Path)) - if err != nil { - return err - } - return man.Set(res) - } - - path := filepath.Join(cgroupRoot, Pids, ctr.config.Path) - return c.Pid.Set(path, res) -} - -// Create the cgroup. -func (c *linuxPidHandler) Create(ctr *CgroupControl) (bool, error) { - if ctr.cgroup2 { - return false, nil - } - return ctr.createCgroupDirectory(Pids) -} - -// Destroy the cgroup. -func (c *linuxPidHandler) Destroy(ctr *CgroupControl) error { - return rmDirRecursively(ctr.getCgroupv1Path(Pids)) -} - -// Stat fills a metrics structure with usage stats for the controller. -func (c *linuxPidHandler) Stat(ctr *CgroupControl, m *cgroups.Stats) error { +// pidsStat fills a metrics structure with usage stats for the pids controller. +func pidsStat(ctr *CgroupControl, m *cgroups.Stats) error { if ctr.config.Path == "" { // nothing we can do to retrieve the pids.current path return nil } - var PIDRoot string - if ctr.cgroup2 { - PIDRoot = filepath.Join(cgroupRoot, ctr.config.Path) - } else { - PIDRoot = ctr.getCgroupv1Path(Pids) - } + PIDRoot := filepath.Join(cgroupRoot, ctr.config.Path) current, err := readFileAsUint64(filepath.Join(PIDRoot, "pids.current")) if err != nil { diff --git a/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go b/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go index c0bc6d9d384..e59a0076156 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/systemd_linux.go @@ -32,18 +32,11 @@ func systemdCreate(resources *cgroups.Resources, path string, c *systemdDbus.Con systemdDbus.PropDescription("cgroup " + name), systemdDbus.PropWants(slice), } - var ioString string - v2, _ := IsCgroup2UnifiedMode() - if v2 { - ioString = "IOAccounting" - } else { - ioString = "BlockIOAccounting" - } pMap := map[string]bool{ "DefaultDependencies": false, "MemoryAccounting": true, "CPUAccounting": true, - ioString: true, + "IOAccounting": true, } if i == 0 { pMap["Delegate"] = true @@ -57,7 +50,7 @@ func systemdCreate(resources *cgroups.Resources, path string, c *systemdDbus.Con properties = append(properties, p) } - uMap, sMap, bMap, iMap, structMap, err := resourcesToProps(resources, v2) + uMap, sMap, bMap, iMap, structMap, err := resourcesToProps(resources) if err != nil { lastError = err continue @@ -150,7 +143,7 @@ func systemdDestroyConn(path string, c *systemdDbus.Conn) error { return nil } -func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[string]string, map[string][]byte, map[string]int64, map[string][]BlkioDev, error) { +func resourcesToProps(res *cgroups.Resources) (map[string]uint64, map[string]string, map[string][]byte, map[string]int64, map[string][]BlkioDev, error) { bMap := make(map[string][]byte) // this array is not used but will be once more resource limits are added sMap := make(map[string]string) @@ -176,13 +169,8 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s if res.CpuShares != 0 { // convert from shares to weight. weight only supports 1-10000 - v2, _ := IsCgroup2UnifiedMode() - if v2 { - wt := (1 + ((res.CpuShares-2)*9999)/262142) - uMap["CPUWeight"] = wt - } else { - uMap["CPUShares"] = res.CpuShares - } + wt := (1 + ((res.CpuShares-2)*9999)/262142) + uMap["CPUWeight"] = wt } // CPUSet @@ -212,21 +200,15 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s case res.Memory == -1 || res.MemorySwap == -1: swap := -1 uMap["MemorySwapMax"] = uint64(swap) - case v2: + default: // swap max = swap (limit + swap limit) - limit uMap["MemorySwapMax"] = uint64(res.MemorySwap - res.Memory) - default: - uMap["MemorySwapMax"] = uint64(res.MemorySwap) } } // Blkio if res.BlkioWeight > 0 { - if v2 { - uMap["IOWeight"] = uint64(res.BlkioWeight) - } else { - uMap["BlockIOWeight"] = uint64(res.BlkioWeight) - } + uMap["IOWeight"] = uint64(res.BlkioWeight) } // systemd requires the paths to be in the form /dev/{block, char}/major:minor @@ -238,11 +220,7 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s Device: fmt.Sprintf("/dev/block/%d:%d", entry.Major, entry.Minor), Bytes: entry.Rate, } - if v2 { - structMap["IOReadBandwidthMax"] = append(structMap["IOReadBandwidthMax"], newThrottle) - } else { - structMap["BlockIOReadBandwidth"] = append(structMap["BlockIOReadBandwidth"], newThrottle) - } + structMap["IOReadBandwidthMax"] = append(structMap["IOReadBandwidthMax"], newThrottle) } } @@ -252,11 +230,7 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s Device: fmt.Sprintf("/dev/block/%d:%d", entry.Major, entry.Minor), Bytes: entry.Rate, } - if v2 { - structMap["IOWriteBandwidthMax"] = append(structMap["IOWriteBandwidthMax"], newThrottle) - } else { - structMap["BlockIOWriteBandwidth"] = append(structMap["BlockIOWriteBandwidth"], newThrottle) - } + structMap["IOWriteBandwidthMax"] = append(structMap["IOWriteBandwidthMax"], newThrottle) } } @@ -266,11 +240,7 @@ func resourcesToProps(res *cgroups.Resources, v2 bool) (map[string]uint64, map[s Device: fmt.Sprintf("/dev/block/%d:%d", entry.Major, entry.Minor), Bytes: uint64(entry.Weight), } - if v2 { - structMap["IODeviceWeight"] = append(structMap["IODeviceWeight"], newWeight) - } else { - structMap["BlockIODeviceWeight"] = append(structMap["BlockIODeviceWeight"], newWeight) - } + structMap["IODeviceWeight"] = append(structMap["IODeviceWeight"], newWeight) } } diff --git a/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go b/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go index a1b18a96952..b1ee60a2945 100644 --- a/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go +++ b/vendor/go.podman.io/common/pkg/cgroups/utils_linux.go @@ -15,7 +15,6 @@ import ( "github.com/opencontainers/cgroups" "github.com/sirupsen/logrus" - "go.podman.io/storage/pkg/fileutils" "golang.org/x/sys/unix" ) @@ -207,7 +206,7 @@ func MoveUnderCgroup(cgroup, subtree string, processes []uint32) error { } defer f.Close() - unifiedMode, err := IsCgroup2UnifiedMode() + _, err = IsCgroup2UnifiedMode() if err != nil { return err } @@ -221,24 +220,12 @@ func MoveUnderCgroup(cgroup, subtree string, processes []uint32) error { } // root cgroup, skip it - if parts[2] == "/" && (!unifiedMode || parts[1] != "") { + if parts[2] == "/" && parts[1] != "" { continue } cgroupRoot := "/sys/fs/cgroup" - // Special case the unified mount on hybrid cgroup and named hierarchies. - // This works on Fedora 31, but we should really parse the mounts to see - // where the cgroup hierarchy is mounted. - if parts[1] == "" && !unifiedMode { - // If it is not using unified mode, the cgroup v2 hierarchy is - // usually mounted under /sys/fs/cgroup/unified - cgroupRoot = filepath.Join(cgroupRoot, "unified") - - // Ignore the unified mount if it doesn't exist - if err := fileutils.Exists(cgroupRoot); err != nil && os.IsNotExist(err) { - continue - } - } else if parts[1] != "" { + if parts[1] != "" { // Assume the controller is mounted at /sys/fs/cgroup/$CONTROLLER. controller := strings.TrimPrefix(parts[1], "name=") cgroupRoot = filepath.Join(cgroupRoot, controller) @@ -292,15 +279,11 @@ var ( // it is running in the root cgroup on a system that uses cgroupv2. func MaybeMoveToSubCgroup() error { maybeMoveToSubCgroupSync.Do(func() { - unifiedMode, err := IsCgroup2UnifiedMode() + _, err := IsCgroup2UnifiedMode() if err != nil { maybeMoveToSubCgroupSyncErr = err return } - if !unifiedMode { - maybeMoveToSubCgroupSyncErr = nil - return - } cgroup, err := GetOwnCgroup() if err != nil { maybeMoveToSubCgroupSyncErr = err diff --git a/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_linux.go b/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_linux.go deleted file mode 100644 index b7e1e6aeac8..00000000000 --- a/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_linux.go +++ /dev/null @@ -1,27 +0,0 @@ -package cgroupv2 - -import ( - "sync" - "syscall" - - "golang.org/x/sys/unix" -) - -var ( - isCgroupV2Once sync.Once - isCgroupV2 bool - isCgroupV2Err error -) - -// Enabled returns whether we are running on cgroup v2. -func Enabled() (bool, error) { - isCgroupV2Once.Do(func() { - var st syscall.Statfs_t - if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil { - isCgroupV2, isCgroupV2Err = false, err - } else { - isCgroupV2, isCgroupV2Err = st.Type == unix.CGROUP2_SUPER_MAGIC, nil - } - }) - return isCgroupV2, isCgroupV2Err -} diff --git a/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_unsupported.go b/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_unsupported.go deleted file mode 100644 index 8de8e60d809..00000000000 --- a/vendor/go.podman.io/common/pkg/cgroupv2/cgroups_unsupported.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !linux - -package cgroupv2 - -// Enabled returns whether we are running on cgroup v2. -func Enabled() (bool, error) { - return false, nil -} diff --git a/vendor/go.podman.io/common/pkg/config/containers.conf b/vendor/go.podman.io/common/pkg/config/containers.conf index a25f53f8fa6..d89827d3f58 100644 --- a/vendor/go.podman.io/common/pkg/config/containers.conf +++ b/vendor/go.podman.io/common/pkg/config/containers.conf @@ -941,9 +941,9 @@ default_sysctls = [ # wsl - Windows Subsystem for Linux (Default) # hyperv - Windows Server Virtualization # Mac: there are currently two options: -# applehv - Default Apple Hypervisor (Default) # libkrun - Launch virtual machines using the libkrun platform, optimized -# for sharing GPU with the machine. +# for sharing GPU with the machine. (Default) +# applehv - Launch virtual machines using the vfkit platform. #provider = "" # Rosetta supports running x86_64 Linux binaries on a Podman machine on Apple silicon. diff --git a/vendor/go.podman.io/common/pkg/config/default.go b/vendor/go.podman.io/common/pkg/config/default.go index 54402d1712e..ee4dd63791b 100644 --- a/vendor/go.podman.io/common/pkg/config/default.go +++ b/vendor/go.podman.io/common/pkg/config/default.go @@ -15,7 +15,6 @@ import ( "go.podman.io/common/internal/attributedstring" nettypes "go.podman.io/common/libnetwork/types" "go.podman.io/common/pkg/apparmor" - "go.podman.io/common/pkg/cgroupv2" "go.podman.io/storage/pkg/fileutils" "go.podman.io/storage/pkg/homedir" "go.podman.io/storage/pkg/unshare" @@ -231,17 +230,12 @@ func defaultConfig() (*Config, error) { } } - cgroupNS := "host" - if cgroup2, _ := cgroupv2.Enabled(); cgroup2 { - cgroupNS = "private" - } - return &Config{ Containers: ContainersConfig{ Annotations: attributedstring.Slice{}, ApparmorProfile: DefaultApparmorProfile, BaseHostsFile: "", - CgroupNS: cgroupNS, + CgroupNS: "private", Cgroups: getDefaultCgroupsMode(), DNSOptions: attributedstring.Slice{}, DNSSearches: attributedstring.Slice{}, @@ -650,12 +644,7 @@ func (c *Config) PidsLimit() int64 { if c.Engine.CgroupManager != SystemdCgroupsManager { return 0 } - cgroup2, _ := cgroupv2.Enabled() - if !cgroup2 { - return 0 - } } - return c.Containers.PidsLimit } diff --git a/vendor/go.podman.io/common/pkg/config/systemd.go b/vendor/go.podman.io/common/pkg/config/systemd.go index e7c15b59094..f8e84acece7 100644 --- a/vendor/go.podman.io/common/pkg/config/systemd.go +++ b/vendor/go.podman.io/common/pkg/config/systemd.go @@ -7,9 +7,7 @@ import ( "path/filepath" "sync" - "go.podman.io/common/pkg/cgroupv2" "go.podman.io/common/pkg/systemd" - "go.podman.io/storage/pkg/unshare" ) var ( @@ -26,11 +24,6 @@ func defaultCgroupManager() string { if !useSystemd() { return CgroupfsCgroupsManager } - enabled, err := cgroupv2.Enabled() - if err == nil && !enabled && unshare.IsRootless() { - return CgroupfsCgroupsManager - } - return SystemdCgroupsManager } diff --git a/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go b/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go index ea98d49481c..752b1bc120f 100644 --- a/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go +++ b/vendor/go.podman.io/common/pkg/sysinfo/sysinfo_linux.go @@ -9,7 +9,7 @@ import ( "github.com/opencontainers/cgroups" "github.com/sirupsen/logrus" - "go.podman.io/common/pkg/cgroupv2" + cgroupv2 "go.podman.io/common/pkg/cgroups" "go.podman.io/storage/pkg/fileutils" "golang.org/x/sys/unix" ) @@ -41,7 +41,7 @@ func New(quiet bool) *SysInfo { sysInfo.cgroupCPUInfo = checkCgroupCPU(cgMounts, quiet) sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(cgMounts, quiet) sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(cgMounts, quiet) - sysInfo.cgroupPids = checkCgroupPids(cgMounts, quiet) + sysInfo.cgroupPids = checkCgroupPids() } _, ok := cgMounts["devices"] @@ -228,22 +228,12 @@ func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetI } // checkCgroupPids reads the pids information from the pids cgroup mount point. -func checkCgroupPids(cgMounts map[string]string, quiet bool) cgroupPids { - cgroup2, err := cgroupv2.Enabled() +func checkCgroupPids() cgroupPids { + _, err := cgroupv2.IsCgroup2UnifiedMode() if err != nil { logrus.Errorf("Failed to check cgroups version: %v", err) return cgroupPids{} } - if !cgroup2 { - _, ok := cgMounts["pids"] - if !ok { - if !quiet { - logrus.Warn("Unable to find pids cgroup in mounts") - } - return cgroupPids{} - } - } - return cgroupPids{ PidsLimit: true, } diff --git a/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go b/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go index a189cfbe052..1d839636aae 100644 --- a/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go +++ b/vendor/go.podman.io/common/pkg/systemd/systemd_linux.go @@ -88,14 +88,12 @@ func MovePauseProcessToScope(pausePidPath string) { } if err != nil { - unified, err2 := cgroups.IsCgroup2UnifiedMode() + _, err2 := cgroups.IsCgroup2UnifiedMode() if err2 != nil { logrus.Warnf("Failed to detect if running with cgroup unified: %v", err) } - if RunsOnSystemd() && unified { + if RunsOnSystemd() { logrus.Warnf("Failed to add pause process to systemd sandbox cgroup: %v", err) - } else { - logrus.Debugf("Failed to add pause process to systemd sandbox cgroup: %v", err) } } } diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go deleted file mode 100644 index e6c645e7ceb..00000000000 --- a/vendor/golang.org/x/crypto/ocsp/ocsp.go +++ /dev/null @@ -1,793 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ocsp parses OCSP responses as specified in RFC 2560. OCSP responses -// are signed messages attesting to the validity of a certificate for a small -// period of time. This is used to manage revocation for X.509 certificates. -package ocsp - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" - "math/big" - "strconv" - "time" -) - -var idPKIXOCSPBasic = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 5, 5, 7, 48, 1, 1}) - -// ResponseStatus contains the result of an OCSP request. See -// https://tools.ietf.org/html/rfc6960#section-2.3 -type ResponseStatus int - -const ( - Success ResponseStatus = 0 - Malformed ResponseStatus = 1 - InternalError ResponseStatus = 2 - TryLater ResponseStatus = 3 - // Status code four is unused in OCSP. See - // https://tools.ietf.org/html/rfc6960#section-4.2.1 - SignatureRequired ResponseStatus = 5 - Unauthorized ResponseStatus = 6 -) - -func (r ResponseStatus) String() string { - switch r { - case Success: - return "success" - case Malformed: - return "malformed" - case InternalError: - return "internal error" - case TryLater: - return "try later" - case SignatureRequired: - return "signature required" - case Unauthorized: - return "unauthorized" - default: - return "unknown OCSP status: " + strconv.Itoa(int(r)) - } -} - -// ResponseError is an error that may be returned by ParseResponse to indicate -// that the response itself is an error, not just that it's indicating that a -// certificate is revoked, unknown, etc. -type ResponseError struct { - Status ResponseStatus -} - -func (r ResponseError) Error() string { - return "ocsp: error from server: " + r.Status.String() -} - -// These are internal structures that reflect the ASN.1 structure of an OCSP -// response. See RFC 2560, section 4.2. - -type certID struct { - HashAlgorithm pkix.AlgorithmIdentifier - NameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -// https://tools.ietf.org/html/rfc2560#section-4.1.1 -type ocspRequest struct { - TBSRequest tbsRequest -} - -type tbsRequest struct { - Version int `asn1:"explicit,tag:0,default:0,optional"` - RequestorName pkix.RDNSequence `asn1:"explicit,tag:1,optional"` - RequestList []request -} - -type request struct { - Cert certID -} - -type responseASN1 struct { - Status asn1.Enumerated - Response responseBytes `asn1:"explicit,tag:0,optional"` -} - -type responseBytes struct { - ResponseType asn1.ObjectIdentifier - Response []byte -} - -type basicResponse struct { - TBSResponseData responseData - SignatureAlgorithm pkix.AlgorithmIdentifier - Signature asn1.BitString - Certificates []asn1.RawValue `asn1:"explicit,tag:0,optional"` -} - -type responseData struct { - Raw asn1.RawContent - Version int `asn1:"optional,default:0,explicit,tag:0"` - RawResponderID asn1.RawValue - ProducedAt time.Time `asn1:"generalized"` - Responses []singleResponse -} - -type singleResponse struct { - CertID certID - Good asn1.Flag `asn1:"tag:0,optional"` - Revoked revokedInfo `asn1:"tag:1,optional"` - Unknown asn1.Flag `asn1:"tag:2,optional"` - ThisUpdate time.Time `asn1:"generalized"` - NextUpdate time.Time `asn1:"generalized,explicit,tag:0,optional"` - SingleExtensions []pkix.Extension `asn1:"explicit,tag:1,optional"` -} - -type revokedInfo struct { - RevocationTime time.Time `asn1:"generalized"` - Reason asn1.Enumerated `asn1:"explicit,tag:0,optional"` -} - -var ( - oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} - oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} - oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} - oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} - oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} - oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} - oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} - oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} - oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} - oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} - oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} - oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} -) - -var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{ - crypto.SHA1: asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}), - crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}), - crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}), - crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}), -} - -// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below -var signatureAlgorithmDetails = []struct { - algo x509.SignatureAlgorithm - oid asn1.ObjectIdentifier - pubKeyAlgo x509.PublicKeyAlgorithm - hash crypto.Hash -}{ - {x509.MD2WithRSA, oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, - {x509.MD5WithRSA, oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, - {x509.SHA1WithRSA, oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, - {x509.SHA256WithRSA, oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, - {x509.SHA384WithRSA, oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, - {x509.SHA512WithRSA, oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, - {x509.DSAWithSHA1, oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, - {x509.DSAWithSHA256, oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, - {x509.ECDSAWithSHA1, oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, - {x509.ECDSAWithSHA256, oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, - {x509.ECDSAWithSHA384, oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, - {x509.ECDSAWithSHA512, oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, -} - -// TODO(rlb): This is also from crypto/x509, so same comment as AGL's below -func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { - var pubType x509.PublicKeyAlgorithm - - switch pub := pub.(type) { - case *rsa.PublicKey: - pubType = x509.RSA - hashFunc = crypto.SHA256 - sigAlgo.Algorithm = oidSignatureSHA256WithRSA - sigAlgo.Parameters = asn1.RawValue{ - Tag: 5, - } - - case *ecdsa.PublicKey: - pubType = x509.ECDSA - - switch pub.Curve { - case elliptic.P224(), elliptic.P256(): - hashFunc = crypto.SHA256 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA256 - case elliptic.P384(): - hashFunc = crypto.SHA384 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA384 - case elliptic.P521(): - hashFunc = crypto.SHA512 - sigAlgo.Algorithm = oidSignatureECDSAWithSHA512 - default: - err = errors.New("x509: unknown elliptic curve") - } - - default: - err = errors.New("x509: only RSA and ECDSA keys supported") - } - - if err != nil { - return - } - - if requestedSigAlgo == 0 { - return - } - - found := false - for _, details := range signatureAlgorithmDetails { - if details.algo == requestedSigAlgo { - if details.pubKeyAlgo != pubType { - err = errors.New("x509: requested SignatureAlgorithm does not match private key type") - return - } - sigAlgo.Algorithm, hashFunc = details.oid, details.hash - if hashFunc == 0 { - err = errors.New("x509: cannot sign with hash function requested") - return - } - found = true - break - } - } - - if !found { - err = errors.New("x509: unknown SignatureAlgorithm") - } - - return -} - -// TODO(agl): this is taken from crypto/x509 and so should probably be exported -// from crypto/x509 or crypto/x509/pkix. -func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.SignatureAlgorithm { - for _, details := range signatureAlgorithmDetails { - if oid.Equal(details.oid) { - return details.algo - } - } - return x509.UnknownSignatureAlgorithm -} - -// TODO(rlb): This is not taken from crypto/x509, but it's of the same general form. -func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash { - for hash, oid := range hashOIDs { - if oid.Equal(target) { - return hash - } - } - return crypto.Hash(0) -} - -func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier { - for hash, oid := range hashOIDs { - if hash == target { - return oid - } - } - return nil -} - -// This is the exposed reflection of the internal OCSP structures. - -// The status values that can be expressed in OCSP. See RFC 6960. -// These are used for the Response.Status field. -const ( - // Good means that the certificate is valid. - Good = 0 - // Revoked means that the certificate has been deliberately revoked. - Revoked = 1 - // Unknown means that the OCSP responder doesn't know about the certificate. - Unknown = 2 - // ServerFailed is unused and was never used (see - // https://go-review.googlesource.com/#/c/18944). ParseResponse will - // return a ResponseError when an error response is parsed. - ServerFailed = 3 -) - -// The enumerated reasons for revoking a certificate. See RFC 5280. -const ( - Unspecified = 0 - KeyCompromise = 1 - CACompromise = 2 - AffiliationChanged = 3 - Superseded = 4 - CessationOfOperation = 5 - CertificateHold = 6 - - RemoveFromCRL = 8 - PrivilegeWithdrawn = 9 - AACompromise = 10 -) - -// Request represents an OCSP request. See RFC 6960. -type Request struct { - HashAlgorithm crypto.Hash - IssuerNameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -// Marshal marshals the OCSP request to ASN.1 DER encoded form. -func (req *Request) Marshal() ([]byte, error) { - hashAlg := getOIDFromHashAlgorithm(req.HashAlgorithm) - if hashAlg == nil { - return nil, errors.New("Unknown hash algorithm") - } - return asn1.Marshal(ocspRequest{ - tbsRequest{ - Version: 0, - RequestList: []request{ - { - Cert: certID{ - pkix.AlgorithmIdentifier{ - Algorithm: hashAlg, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - req.IssuerNameHash, - req.IssuerKeyHash, - req.SerialNumber, - }, - }, - }, - }, - }) -} - -// Response represents an OCSP response containing a single SingleResponse. See -// RFC 6960. -type Response struct { - Raw []byte - - // Status is one of {Good, Revoked, Unknown} - Status int - SerialNumber *big.Int - ProducedAt, ThisUpdate, NextUpdate, RevokedAt time.Time - RevocationReason int - Certificate *x509.Certificate - // TBSResponseData contains the raw bytes of the signed response. If - // Certificate is nil then this can be used to verify Signature. - TBSResponseData []byte - Signature []byte - SignatureAlgorithm x509.SignatureAlgorithm - - // IssuerHash is the hash used to compute the IssuerNameHash and IssuerKeyHash. - // Valid values are crypto.SHA1, crypto.SHA256, crypto.SHA384, and crypto.SHA512. - // If zero, the default is crypto.SHA1. - IssuerHash crypto.Hash - - // RawResponderName optionally contains the DER-encoded subject of the - // responder certificate. Exactly one of RawResponderName and - // ResponderKeyHash is set. - RawResponderName []byte - // ResponderKeyHash optionally contains the SHA-1 hash of the - // responder's public key. Exactly one of RawResponderName and - // ResponderKeyHash is set. - ResponderKeyHash []byte - - // Extensions contains raw X.509 extensions from the singleExtensions field - // of the OCSP response. When parsing certificates, this can be used to - // extract non-critical extensions that are not parsed by this package. When - // marshaling OCSP responses, the Extensions field is ignored, see - // ExtraExtensions. - Extensions []pkix.Extension - - // ExtraExtensions contains extensions to be copied, raw, into any marshaled - // OCSP response (in the singleExtensions field). Values override any - // extensions that would otherwise be produced based on the other fields. The - // ExtraExtensions field is not populated when parsing certificates, see - // Extensions. - ExtraExtensions []pkix.Extension -} - -// These are pre-serialized error responses for the various non-success codes -// defined by OCSP. The Unauthorized code in particular can be used by an OCSP -// responder that supports only pre-signed responses as a response to requests -// for certificates with unknown status. See RFC 5019. -var ( - MalformedRequestErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x01} - InternalErrorErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x02} - TryLaterErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x03} - SigRequredErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x05} - UnauthorizedErrorResponse = []byte{0x30, 0x03, 0x0A, 0x01, 0x06} -) - -// CheckSignatureFrom checks that the signature in resp is a valid signature -// from issuer. This should only be used if resp.Certificate is nil. Otherwise, -// the OCSP response contained an intermediate certificate that created the -// signature. That signature is checked by ParseResponse and only -// resp.Certificate remains to be validated. -func (resp *Response) CheckSignatureFrom(issuer *x509.Certificate) error { - return issuer.CheckSignature(resp.SignatureAlgorithm, resp.TBSResponseData, resp.Signature) -} - -// ParseError results from an invalid OCSP response. -type ParseError string - -func (p ParseError) Error() string { - return string(p) -} - -// ParseRequest parses an OCSP request in DER form. It only supports -// requests for a single certificate. Signed requests are not supported. -// If a request includes a signature, it will result in a ParseError. -func ParseRequest(bytes []byte) (*Request, error) { - var req ocspRequest - rest, err := asn1.Unmarshal(bytes, &req) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, ParseError("trailing data in OCSP request") - } - - if len(req.TBSRequest.RequestList) == 0 { - return nil, ParseError("OCSP request contains no request body") - } - innerRequest := req.TBSRequest.RequestList[0] - - hashFunc := getHashAlgorithmFromOID(innerRequest.Cert.HashAlgorithm.Algorithm) - if hashFunc == crypto.Hash(0) { - return nil, ParseError("OCSP request uses unknown hash function") - } - - return &Request{ - HashAlgorithm: hashFunc, - IssuerNameHash: innerRequest.Cert.NameHash, - IssuerKeyHash: innerRequest.Cert.IssuerKeyHash, - SerialNumber: innerRequest.Cert.SerialNumber, - }, nil -} - -// ParseResponse parses an OCSP response in DER form. The response must contain -// only one certificate status. To parse the status of a specific certificate -// from a response which may contain multiple statuses, use ParseResponseForCert -// instead. -// -// If the response contains an embedded certificate, then that certificate will -// be used to verify the response signature. If the response contains an -// embedded certificate and issuer is not nil, then issuer will be used to verify -// the signature on the embedded certificate. -// -// If the response does not contain an embedded certificate and issuer is not -// nil, then issuer will be used to verify the response signature. -// -// Invalid responses and parse failures will result in a ParseError. -// Error responses will result in a ResponseError. -func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) { - return ParseResponseForCert(bytes, nil, issuer) -} - -// ParseResponseForCert acts identically to ParseResponse, except it supports -// parsing responses that contain multiple statuses. If the response contains -// multiple statuses and cert is not nil, then ParseResponseForCert will return -// the first status which contains a matching serial, otherwise it will return an -// error. If cert is nil, then the first status in the response will be returned. -func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) { - var resp responseASN1 - rest, err := asn1.Unmarshal(bytes, &resp) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, ParseError("trailing data in OCSP response") - } - - if status := ResponseStatus(resp.Status); status != Success { - return nil, ResponseError{status} - } - - if !resp.Response.ResponseType.Equal(idPKIXOCSPBasic) { - return nil, ParseError("bad OCSP response type") - } - - var basicResp basicResponse - rest, err = asn1.Unmarshal(resp.Response.Response, &basicResp) - if err != nil { - return nil, err - } - if len(rest) > 0 { - return nil, ParseError("trailing data in OCSP response") - } - - if n := len(basicResp.TBSResponseData.Responses); n == 0 || cert == nil && n > 1 { - return nil, ParseError("OCSP response contains bad number of responses") - } - - var singleResp singleResponse - if cert == nil { - singleResp = basicResp.TBSResponseData.Responses[0] - } else { - match := false - for _, resp := range basicResp.TBSResponseData.Responses { - if cert.SerialNumber.Cmp(resp.CertID.SerialNumber) == 0 { - singleResp = resp - match = true - break - } - } - if !match { - return nil, ParseError("no response matching the supplied certificate") - } - } - - ret := &Response{ - Raw: bytes, - TBSResponseData: basicResp.TBSResponseData.Raw, - Signature: basicResp.Signature.RightAlign(), - SignatureAlgorithm: getSignatureAlgorithmFromOID(basicResp.SignatureAlgorithm.Algorithm), - Extensions: singleResp.SingleExtensions, - SerialNumber: singleResp.CertID.SerialNumber, - ProducedAt: basicResp.TBSResponseData.ProducedAt, - ThisUpdate: singleResp.ThisUpdate, - NextUpdate: singleResp.NextUpdate, - } - - // Handle the ResponderID CHOICE tag. ResponderID can be flattened into - // TBSResponseData once https://go-review.googlesource.com/34503 has been - // released. - rawResponderID := basicResp.TBSResponseData.RawResponderID - switch rawResponderID.Tag { - case 1: // Name - var rdn pkix.RDNSequence - if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &rdn); err != nil || len(rest) != 0 { - return nil, ParseError("invalid responder name") - } - ret.RawResponderName = rawResponderID.Bytes - case 2: // KeyHash - if rest, err := asn1.Unmarshal(rawResponderID.Bytes, &ret.ResponderKeyHash); err != nil || len(rest) != 0 { - return nil, ParseError("invalid responder key hash") - } - default: - return nil, ParseError("invalid responder id tag") - } - - if len(basicResp.Certificates) > 0 { - // Responders should only send a single certificate (if they - // send any) that connects the responder's certificate to the - // original issuer. We accept responses with multiple - // certificates due to a number responders sending them[1], but - // ignore all but the first. - // - // [1] https://github.com/golang/go/issues/21527 - ret.Certificate, err = x509.ParseCertificate(basicResp.Certificates[0].FullBytes) - if err != nil { - return nil, err - } - - if err := ret.CheckSignatureFrom(ret.Certificate); err != nil { - return nil, ParseError("bad signature on embedded certificate: " + err.Error()) - } - - if issuer != nil { - if err := issuer.CheckSignature(ret.Certificate.SignatureAlgorithm, ret.Certificate.RawTBSCertificate, ret.Certificate.Signature); err != nil { - return nil, ParseError("bad OCSP signature: " + err.Error()) - } - } - } else if issuer != nil { - if err := ret.CheckSignatureFrom(issuer); err != nil { - return nil, ParseError("bad OCSP signature: " + err.Error()) - } - } - - for _, ext := range singleResp.SingleExtensions { - if ext.Critical { - return nil, ParseError("unsupported critical extension") - } - } - - for h, oid := range hashOIDs { - if singleResp.CertID.HashAlgorithm.Algorithm.Equal(oid) { - ret.IssuerHash = h - break - } - } - if ret.IssuerHash == 0 { - return nil, ParseError("unsupported issuer hash algorithm") - } - - switch { - case bool(singleResp.Good): - ret.Status = Good - case bool(singleResp.Unknown): - ret.Status = Unknown - default: - ret.Status = Revoked - ret.RevokedAt = singleResp.Revoked.RevocationTime - ret.RevocationReason = int(singleResp.Revoked.Reason) - } - - return ret, nil -} - -// RequestOptions contains options for constructing OCSP requests. -type RequestOptions struct { - // Hash contains the hash function that should be used when - // constructing the OCSP request. If zero, SHA-1 will be used. - Hash crypto.Hash -} - -func (opts *RequestOptions) hash() crypto.Hash { - if opts == nil || opts.Hash == 0 { - // SHA-1 is nearly universally used in OCSP. - return crypto.SHA1 - } - return opts.Hash -} - -// CreateRequest returns a DER-encoded, OCSP request for the status of cert. If -// opts is nil then sensible defaults are used. -func CreateRequest(cert, issuer *x509.Certificate, opts *RequestOptions) ([]byte, error) { - hashFunc := opts.hash() - - // OCSP seems to be the only place where these raw hash identifiers are - // used. I took the following from - // http://msdn.microsoft.com/en-us/library/ff635603.aspx - _, ok := hashOIDs[hashFunc] - if !ok { - return nil, x509.ErrUnsupportedAlgorithm - } - - if !hashFunc.Available() { - return nil, x509.ErrUnsupportedAlgorithm - } - h := opts.hash().New() - - var publicKeyInfo struct { - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString - } - if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { - return nil, err - } - - h.Write(publicKeyInfo.PublicKey.RightAlign()) - issuerKeyHash := h.Sum(nil) - - h.Reset() - h.Write(issuer.RawSubject) - issuerNameHash := h.Sum(nil) - - req := &Request{ - HashAlgorithm: hashFunc, - IssuerNameHash: issuerNameHash, - IssuerKeyHash: issuerKeyHash, - SerialNumber: cert.SerialNumber, - } - return req.Marshal() -} - -// CreateResponse returns a DER-encoded OCSP response with the specified contents. -// The fields in the response are populated as follows: -// -// The responder cert is used to populate the responder's name field, and the -// certificate itself is provided alongside the OCSP response signature. -// -// The issuer cert is used to populate the IssuerNameHash and IssuerKeyHash fields. -// -// The template is used to populate the SerialNumber, Status, RevokedAt, -// RevocationReason, ThisUpdate, and NextUpdate fields. -// -// If template.IssuerHash is not set, SHA1 will be used. -// -// The ProducedAt date is automatically set to the current date, to the nearest minute. -func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv crypto.Signer) ([]byte, error) { - var publicKeyInfo struct { - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString - } - if _, err := asn1.Unmarshal(issuer.RawSubjectPublicKeyInfo, &publicKeyInfo); err != nil { - return nil, err - } - - if template.IssuerHash == 0 { - template.IssuerHash = crypto.SHA1 - } - hashOID := getOIDFromHashAlgorithm(template.IssuerHash) - if hashOID == nil { - return nil, errors.New("unsupported issuer hash algorithm") - } - - if !template.IssuerHash.Available() { - return nil, fmt.Errorf("issuer hash algorithm %v not linked into binary", template.IssuerHash) - } - h := template.IssuerHash.New() - h.Write(publicKeyInfo.PublicKey.RightAlign()) - issuerKeyHash := h.Sum(nil) - - h.Reset() - h.Write(issuer.RawSubject) - issuerNameHash := h.Sum(nil) - - innerResponse := singleResponse{ - CertID: certID{ - HashAlgorithm: pkix.AlgorithmIdentifier{ - Algorithm: hashOID, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - NameHash: issuerNameHash, - IssuerKeyHash: issuerKeyHash, - SerialNumber: template.SerialNumber, - }, - ThisUpdate: template.ThisUpdate.UTC(), - NextUpdate: template.NextUpdate.UTC(), - SingleExtensions: template.ExtraExtensions, - } - - switch template.Status { - case Good: - innerResponse.Good = true - case Unknown: - innerResponse.Unknown = true - case Revoked: - innerResponse.Revoked = revokedInfo{ - RevocationTime: template.RevokedAt.UTC(), - Reason: asn1.Enumerated(template.RevocationReason), - } - } - - rawResponderID := asn1.RawValue{ - Class: 2, // context-specific - Tag: 1, // Name (explicit tag) - IsCompound: true, - Bytes: responderCert.RawSubject, - } - tbsResponseData := responseData{ - Version: 0, - RawResponderID: rawResponderID, - ProducedAt: time.Now().Truncate(time.Minute).UTC(), - Responses: []singleResponse{innerResponse}, - } - - tbsResponseDataDER, err := asn1.Marshal(tbsResponseData) - if err != nil { - return nil, err - } - - hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) - if err != nil { - return nil, err - } - - responseHash := hashFunc.New() - responseHash.Write(tbsResponseDataDER) - signature, err := priv.Sign(rand.Reader, responseHash.Sum(nil), hashFunc) - if err != nil { - return nil, err - } - - response := basicResponse{ - TBSResponseData: tbsResponseData, - SignatureAlgorithm: signatureAlgorithm, - Signature: asn1.BitString{ - Bytes: signature, - BitLength: 8 * len(signature), - }, - } - if template.Certificate != nil { - response.Certificates = []asn1.RawValue{ - {FullBytes: template.Certificate.Raw}, - } - } - responseDER, err := asn1.Marshal(response) - if err != nil { - return nil, err - } - - return asn1.Marshal(responseASN1{ - Status: asn1.Enumerated(Success), - Response: responseBytes{ - ResponseType: idPKIXOCSPBasic, - Response: responseDER, - }, - }) -} diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go index 794b2e32bfa..563270c1549 100644 --- a/vendor/golang.org/x/time/rate/rate.go +++ b/vendor/golang.org/x/time/rate/rate.go @@ -195,7 +195,7 @@ func (r *Reservation) CancelAt(t time.Time) { // update state r.lim.last = t r.lim.tokens = tokens - if r.timeToAct == r.lim.lastEvent { + if r.timeToAct.Equal(r.lim.lastEvent) { prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens))) if !prevEvent.Before(t) { r.lim.lastEvent = prevEvent diff --git a/vendor/golang.org/x/time/rate/sometimes.go b/vendor/golang.org/x/time/rate/sometimes.go index 6ba99ddb67b..9b83932692f 100644 --- a/vendor/golang.org/x/time/rate/sometimes.go +++ b/vendor/golang.org/x/time/rate/sometimes.go @@ -61,7 +61,9 @@ func (s *Sometimes) Do(f func()) { (s.Every > 0 && s.count%s.Every == 0) || (s.Interval > 0 && time.Since(s.last) >= s.Interval) { f() - s.last = time.Now() + if s.Interval > 0 { + s.last = time.Now() + } } s.count++ } diff --git a/vendor/modules.txt b/vendor/modules.txt index a9c633cd995..b6ded1ddaaa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -175,8 +175,8 @@ github.com/containers/psgo/internal/process ## explicit; go 1.19 github.com/containers/winquit/pkg/winquit github.com/containers/winquit/pkg/winquit/win32 -# github.com/coreos/go-oidc/v3 v3.14.1 -## explicit; go 1.23.0 +# github.com/coreos/go-oidc/v3 v3.16.0 +## explicit; go 1.24.0 github.com/coreos/go-oidc/v3/oidc # github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f ## explicit @@ -410,14 +410,6 @@ github.com/klauspost/pgzip # github.com/kr/fs v0.1.0 ## explicit github.com/kr/fs -# github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec -## explicit; go 1.22.0 -github.com/letsencrypt/boulder/core -github.com/letsencrypt/boulder/goodkey -github.com/letsencrypt/boulder/identifier -github.com/letsencrypt/boulder/probs -github.com/letsencrypt/boulder/revocation -github.com/letsencrypt/boulder/strictyaml # github.com/linuxkit/virtsock v0.0.0-20241009230534-cb6a20cc0422 ## explicit; go 1.17 github.com/linuxkit/virtsock/pkg/hvsock @@ -514,7 +506,7 @@ github.com/moby/term/windows # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent -# github.com/modern-go/reflect2 v1.0.2 +# github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee ## explicit; go 1.12 github.com/modern-go/reflect2 # github.com/morikuni/aec v1.0.0 @@ -572,7 +564,6 @@ github.com/onsi/gomega/types ## explicit; go 1.23.0 github.com/opencontainers/cgroups github.com/opencontainers/cgroups/devices/config -github.com/opencontainers/cgroups/fs github.com/opencontainers/cgroups/fs2 github.com/opencontainers/cgroups/fscommon github.com/opencontainers/cgroups/internal/path @@ -610,6 +601,9 @@ github.com/openshift/imagebuilder/dockerfile/parser github.com/openshift/imagebuilder/internal github.com/openshift/imagebuilder/signal github.com/openshift/imagebuilder/strslice +# github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c +## explicit; go 1.14 +github.com/pkg/browser # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors @@ -627,7 +621,7 @@ github.com/pmezard/go-difflib/difflib # github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 ## explicit; go 1.14 github.com/power-devops/perfstat -# github.com/proglottis/gpgme v0.1.5 +# github.com/proglottis/gpgme v0.1.6 ## explicit; go 1.17 github.com/proglottis/gpgme # github.com/rootless-containers/rootlesskit/v2 v2.3.5 @@ -650,9 +644,6 @@ github.com/seccomp/libseccomp-golang # github.com/secure-systems-lab/go-securesystemslib v0.9.1 ## explicit; go 1.23.0 github.com/secure-systems-lab/go-securesystemslib/encrypted -# github.com/segmentio/ksuid v1.0.4 -## explicit; go 1.12 -github.com/segmentio/ksuid # github.com/shirou/gopsutil/v4 v4.25.10 ## explicit; go 1.24.0 github.com/shirou/gopsutil/v4/common @@ -661,31 +652,28 @@ github.com/shirou/gopsutil/v4/internal/common github.com/shirou/gopsutil/v4/mem github.com/shirou/gopsutil/v4/net github.com/shirou/gopsutil/v4/process -# github.com/sigstore/fulcio v1.7.1 -## explicit; go 1.24.0 +# github.com/sigstore/fulcio v1.8.1 +## explicit; go 1.24.6 github.com/sigstore/fulcio/pkg/api github.com/sigstore/fulcio/pkg/certificate -# github.com/sigstore/protobuf-specs v0.4.1 +# github.com/sigstore/protobuf-specs v0.5.0 ## explicit; go 1.22.0 github.com/sigstore/protobuf-specs/gen/pb-go/common/v1 -# github.com/sigstore/sigstore v1.9.5 -## explicit; go 1.23.0 +# github.com/sigstore/sigstore v1.9.6-0.20251111174640-d8ab8afb1326 +## explicit; go 1.24.0 github.com/sigstore/sigstore/pkg/cryptoutils github.com/sigstore/sigstore/pkg/oauth github.com/sigstore/sigstore/pkg/oauthflow github.com/sigstore/sigstore/pkg/signature github.com/sigstore/sigstore/pkg/signature/options github.com/sigstore/sigstore/pkg/signature/payload -# github.com/sirupsen/logrus v1.9.3 +# github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af ## explicit; go 1.13 github.com/sirupsen/logrus github.com/sirupsen/logrus/hooks/syslog # github.com/skeema/knownhosts v1.3.2 ## explicit; go 1.24.0 github.com/skeema/knownhosts -# github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 -## explicit -github.com/skratchdot/open-golang/open # github.com/smallstep/pkcs7 v0.1.1 ## explicit; go 1.14 github.com/smallstep/pkcs7 @@ -710,9 +698,6 @@ github.com/sylabs/sif/v2/pkg/sif # github.com/tchap/go-patricia/v2 v2.3.3 ## explicit; go 1.16 github.com/tchap/go-patricia/v2/patricia -# github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 -## explicit -github.com/titanous/rocacheck # github.com/tklauser/go-sysconf v0.3.15 ## explicit; go 1.23.0 github.com/tklauser/go-sysconf @@ -787,8 +772,8 @@ go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# go.podman.io/common v0.66.1-0.20251122023359-22d50c57903c -## explicit; go 1.24.2 +# go.podman.io/common v0.66.1-0.20251122023359-22d50c57903c => github.com/lsm5/container-libs/common v0.0.0-20251125184859-3ed278e8d0ca +## explicit; go 1.24.6 go.podman.io/common/internal go.podman.io/common/internal/attributedstring go.podman.io/common/libimage @@ -812,7 +797,6 @@ go.podman.io/common/pkg/apparmor/internal/supported go.podman.io/common/pkg/auth go.podman.io/common/pkg/capabilities go.podman.io/common/pkg/cgroups -go.podman.io/common/pkg/cgroupv2 go.podman.io/common/pkg/chown go.podman.io/common/pkg/completion go.podman.io/common/pkg/config @@ -980,7 +964,7 @@ go.podman.io/storage/pkg/tarlog go.podman.io/storage/pkg/truncindex go.podman.io/storage/pkg/unshare go.podman.io/storage/types -# go.yaml.in/yaml/v2 v2.4.2 +# go.yaml.in/yaml/v2 v2.4.3 ## explicit; go 1.15 go.yaml.in/yaml/v2 # go.yaml.in/yaml/v3 v3.0.4 @@ -999,7 +983,6 @@ golang.org/x/crypto/curve25519 golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 golang.org/x/crypto/nacl/secretbox -golang.org/x/crypto/ocsp golang.org/x/crypto/openpgp golang.org/x/crypto/openpgp/armor golang.org/x/crypto/openpgp/elgamal @@ -1076,8 +1059,8 @@ golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm -# golang.org/x/time v0.11.0 -## explicit; go 1.23.0 +# golang.org/x/time v0.14.0 +## explicit; go 1.24.0 golang.org/x/time/rate # golang.org/x/tools v0.38.0 ## explicit; go 1.24.0 @@ -1234,3 +1217,4 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.0.1-0.20251120202831-139ffec09210 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go +# go.podman.io/common => github.com/lsm5/container-libs/common v0.0.0-20251125184859-3ed278e8d0ca