Commit Graph

12743 Commits

Author SHA1 Message Date
Feng Ruohang ca1f11b708 Merge remote-tracking branch 'origin/main' into codex/issue-77-status-accounting 2026-08-29 19:50:27 +08:00
Feng Ruohang 514a041f4a Merge pull request #90 from pgsty/codex/issue-78-preserve-bucket-config
fix: preserve bucket configs during site adoption
2026-08-29 19:50:04 +08:00
Feng Ruohang f8106cd693 Merge remote-tracking branch 'origin/main' into codex/issue-78-preserve-bucket-config 2026-08-29 19:39:50 +08:00
Feng Ruohang b1ba685ac5 Merge pull request #89 from pgsty/codex/issue-76-object-lock-wire
fix: replicate object lock config in its own field
2026-08-29 19:39:22 +08:00
Feng Ruohang bc7658f035 Merge pull request #93 from pgsty/codex/issue-50-after-checksum-contract
fix: reject composite CRC64NVME checksums
2026-08-29 19:38:48 +08:00
Feng Ruohang f377b5c95b Merge remote-tracking branch 'origin/main' into codex/issue-50-after-checksum-contract
# Conflicts:
#	cmd/erasure-multipart-fullobject_test.go
2026-08-29 19:28:06 +08:00
Feng Ruohang 45381222b7 Merge pull request #92 from pgsty/codex/reject-unsupported-checksums
fix: reject unsupported checksum assertions
2026-08-29 19:25:39 +08:00
Feng Ruohang 20aaefa89c Merge remote-tracking branch 'origin/main' into codex/reject-unsupported-checksums 2026-08-29 19:14:51 +08:00
Feng Ruohang 82509ddc0a Merge pull request #95 from pgsty/codex/get-object-attributes-ssec
fix: authenticate SSE-C for object attributes
2026-08-29 19:14:34 +08:00
Feng Ruohang f2ba439022 Merge remote-tracking branch 'origin/main' into codex/get-object-attributes-ssec 2026-08-29 19:04:14 +08:00
Feng Ruohang 2ba1f38503 Merge pull request #87 from pgsty/codex/issue-82-after-83
fix: authenticate SSE-C keys on zero-byte reads
2026-08-29 19:03:57 +08:00
Feng Ruohang 8d58343263 Merge pull request #96 from pgsty/codex/crc64-completion-after-foundation
fix: reject composite CRC64NVME completion
2026-08-29 18:51:09 +08:00
Feng Ruohang 2b2e0d2a5d Merge pull request #86 from pgsty/codex/issue-83-copy-null-version-release
fix: keep rewritten CopyObject data and metadata consistent
2026-08-29 18:49:25 +08:00
Feng Ruohang e407dc58eb Merge pull request #85 from pgsty/codex/server-prerelease-foundation
fix: restore pre-release server corrections
2026-08-29 18:40:26 +08:00
Feng Ruohang 32b2aa49f1 fix: reject composite CRC64NVME completion
Remove the remaining type-only canonicalization at CompleteMultipartUpload while preserving legacy uploads stored as FULL_OBJECT.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 18:36:02 +08:00
Feng Ruohang 8448512a1f docs: clarify layered SSE-C key authentication
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 18:21:13 +08:00
Feng Ruohang 21870fa2e7 fix: preserve replicated object attributes reads
Keep the existing trusted replication carve-out while authenticating ordinary SSE-C GetObjectAttributes requests.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 18:18:01 +08:00
Feng Ruohang d4c8da162b fix: reject composite CRC64NVME trailers
Apply the full-object-only rule to declared streaming checksum trailers and cover the HTTP mutation path.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 18:15:51 +08:00
Feng Ruohang d28885d0e5 fix: reject composite CRC64NVME checksums
Return InvalidArgument for CRC64NVME with COMPOSITE at multipart initiation and PutObject instead of silently canonicalizing the request to FULL_OBJECT.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:32:36 +08:00
Feng Ruohang c4fd97d0bf test: align zero-byte rotation key errors
After zero-byte reads authenticate SSE-C at the object layer, equal invalid rotation keys match non-empty reads and return AccessDenied before the rotation-specific distinction.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:32:25 +08:00
Feng Ruohang b73581b05d fix: authenticate SSE-C keys on zero-byte reads
Unseal supplied SSE-C and copy-source keys after range and request preconditions when a zero-byte read cannot build a decryptor. Preserve internal no-decryption, replication, restore, and absent-header reads.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:32:25 +08:00
Feng Ruohang 474cd5801e fix: authenticate SSE-C for object attributes
Unseal the supplied customer key after request preconditions before returning object size, ETag, checksum, or part attributes. Cover zero-byte and non-empty objects with correct, wrong, and missing keys.\n\nRefs #84.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:26:37 +08:00
Feng Ruohang fb406fdc94 fix: report site replication metadata per site
Count only each site own valid bucket metadata, populate quota totals, and keep malformed fields from suppressing unrelated bucket statistics. Emit bounded diagnostics for invalid payloads.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:25:11 +08:00
Feng Ruohang dd3bdb8086 fix: preserve bucket configs during site adoption
Keep existing Object Lock and enabled versioning documents and timestamps when adopting a same-name bucket. Bootstrap missing configs, enable suspended versioning, and retain custom excluded-prefix settings.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:24:27 +08:00
Feng Ruohang 7c103389f5 fix: reject unsupported checksum assertions
Reject unimplemented x-amz-checksum value and trailer names instead of accepting uploads without verification. Apply the same contract to PutObject, multipart initiation and parts, CopyObject, and UploadPartCopy while preserving the five supported algorithms.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 17:23:26 +08:00
Feng Ruohang 3861f33cba fix: replicate object lock config in its own field
Populate ObjectLockConfig for live, initial-sync, and heal events, while accepting the legacy Tags field during rolling upgrades. Exercise signed admin dispatch and remote-heal transport on both object-layer backends.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:54:00 +08:00
Feng Ruohang 5732930102 test: cover null-version copy rewrite directions
Exercise the silent compression-on-copy path, compressed SSE-C re-encryption, and the equal-invalid-key error contract on both object-layer backends.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:28:42 +08:00
Feng Ruohang 2aea7fe9c4 fix: preserve named targets in config environment files
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang ffb70eb373 fix: re-encrypt a key rotation the object layer has to rewrite
A key rotation rewraps the object key held in metadata; it never re-encrypts
the stored bytes. CopyObjectHandler took that shortcut whenever the request
looked like a same-object SSE-C rotation, on the assumption that the object
layer would then leave the stored bytes alone. That is the same assumption
copyRewritesObjectData() was added to stop making.

When the source is a null version on a bucket that gained versioning after the
object was written, the object layer cannot reference that version and falls
back to PutObject. The reader at that point holds plaintext decrypted with the
old key and no EncryptFn is set, so the destination ends up storing plaintext
under metadata that claims the object is SSE-C encrypted. A subsequent GET
failed with "sio: unsupported version".

Gate the rotation shortcut on the same prediction the compression metadata
already uses. When the object layer stores new object data the rotation falls
through to the regular re-encrypting copy, which decrypts with the old key and
re-encrypts with the new one. The source version selection moves next to the
gate because both decisions need it.

That fallback authenticates the source key through the source decryptor, which
GetObjectNInfo does not build for a zero byte object. Check the key explicitly
before the destination is written, so the gate cannot turn a rotation that the
shortcut rejected with AccessDenied into one that succeeds. The re-encrypting
copy regenerates the encrypted ETag, unlike an in-place rotation; the test
records that difference.

The other three object layer CopyObject callers that set metadataOnly -
PostRestoreObjectHandler, updateRestoreMetadata and batchKeyRotate - address
the same version on both sides and never set Versioned, so they only reach the
two in-place cases already covered by the copyRewritesObjectData table.

Signed-off-by: Feng Ruohang <rh@vonng.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fk3PAD7DHCYzcyegYWqAmt
2026-08-29 16:00:21 +08:00
Feng Ruohang e73436c99d fix: decrypt CopyObject checksums with destination key
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 0b0ae2423a fix: keep copy metadata consistent with a rewritten null version
CopyObjectHandler recorded the source compression metadata whenever the copy
was metadata-only, on the assumption that the object layer would then leave
the stored bytes alone. That assumption does not hold. Both
erasureServerPools.CopyObject and erasureSets.CopyObject only skip a data
rewrite in three cases, and otherwise fall back to a full PutObject.

The reachable gap is a copy whose source is a null version on a bucket that
gained versioning after the object was written. Neither version ID is set, so
the self-referential version branch is skipped, the data is rewritten as
plaintext, and the preserved compression metadata then described bytes that
no longer exist. A subsequent GET failed with "s2: corrupt input".

Mirror the object layer's decision in copyRewritesObjectData and record the
compression metadata from it, so the metadata always describes whichever
bytes are finally stored. The source version selection that lets a versioned
metadata-only copy add a self-referential version moves next to the same
decision, since both depend on the effective metadata-only value.

Signed-off-by: Feng Ruohang <rh@vonng.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 7e079ff05c fix: validate explicit multipart checksum type
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 229fe2b3c3 fix: authorize group status changes by target status
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 38ed9d1e1f docs(security): record inherited upstream advisory
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 47cd7807d3 test: align federated client version
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 16:00:21 +08:00
Feng Ruohang 04d3d316d2 Merge pull request #81 from pgsty/codex/issue-75-closeout-tests
test: cover asymmetric CORS site counts
2026-08-29 10:13:38 +08:00
Feng Ruohang 4bb8c813ac test: cover asymmetric CORS site counts
Exercise no-site, local-only, remote-only, and both-site CORS summary accounting through the real siteReplicationStatus seam.

Refs #75

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 10:03:01 +08:00
Feng Ruohang b6ef7e430c Merge pull request #80 from pgsty/codex/issue-75-cors-hardening
fix: complete per-bucket CORS release hardening
2026-08-29 09:44:16 +08:00
Feng Ruohang 91d9091758 docs: record final bucket CORS acceptance
Record the frozen B2+B3 commit, combined local gates, raw SigV4 validation, real two-site offline/delete/heal/restart evidence, and the separate public documentation QA boundary.

Refs #75

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 09:29:34 +08:00
Feng Ruohang 0eebc928f7 fix: complete bucket CORS protocol validation
Integrate the strict B3 XML, validation, checksum, wildcard, MaxAge, and Origin-null response contract with the C-prime site-replication register from #75.

Preserve fail-closed metadata behavior and rejected-preflight cache variation while keeping legacy-invalid development metadata readable and repairable through a valid CORS PUT or DELETE.

Add combined parser, handler, browser-response, namespace, replication, restart, and legacy-repair regressions, and update the internal design contract.

Refs #75

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 09:10:58 +08:00
Feng Ruohang 724f8703d8 fix: make bucket CORS replication converge
Define a deterministic CORS replication register with durable tombstones, strict source timestamps, equal-time conflict ordering, full-state status, and heal convergence.

Serialize local and peer CORS transitions with a distributed namespace lock, validate canonical transport payloads, preserve initial-sync deletes, and fail closed on metadata errors.

Add adversarial, concurrent, restart, status, heal, signed admin-dispatch, protocol, and middleware coverage together with the reviewed site-replication design record.

Refs #75

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-29 01:33:24 +08:00
Feng Ruohang e4e3007da6 Merge pull request #71 from h5vx/feature/per-bucket-cors
feat: per-bucket CORS configuration with S3 ?cors enforcement\n\nRelease hardening and site-replication convergence follow-up: #75.
2026-08-28 10:34:52 +08:00
h5vx 13e6458d90 feat: replicate per-bucket CORS across sites and harden the protocol path
Site replication emitted SRBucketMetaTypeCorsConfig on PutBucketCors, but
the peer receive/apply, initial-sync, status, and heal paths did not carry
the CORS metadata. Replicated sites could therefore diverge on CORS config
even though the originating request succeeded.

Complete every site-replication path for CORS, mirroring the SSEConfig
pattern:
  - peer apply: PeerBucketCorsConfigHandler + item.Cors handling in
    PeerBucketMetadataUpdateHandler, with an updatedAt staleness guard
  - initial sync: push existing CorsConfigXML via BucketMetaHook
  - status: parse per-site CorsConfig, count/compare, surface
    CorsCfgMismatch/HasCorsCfgSet/ReplicatedCorsConfig, and include CORS in
    the bucket-stats aggregation filter
  - heal: healCORSMetadata, including nil -> delete propagation

Also harden the request/config path:
  - PutBucketCors validates the supplied Content-MD5/checksum via
    validateLengthAndChecksum
  - CORS validation rejects more than one wildcard per AllowedOrigin/
    AllowedHeader and enforces the 255-char rule ID limit
  - preflight responses Vary on Origin, Access-Control-Request-Method, and
    Access-Control-Request-Headers

Add focused tests for the CORS SR transport round-trip, the metadata
equality helper, and the new validation constraints.

Signed-off-by: h5vx <h5v@protonmail.com>
2026-08-27 12:46:47 +05:00
Feng Ruohang 590aeaa7d1 Merge pull request #74 from pgsty/codex/issue-48-baddigest
fix: align multipart completion checksum errors
2026-08-27 09:53:41 +08:00
Feng Ruohang 5d152416de fix: align multipart completion checksum errors
Return AWS-compatible errors for CompleteMultipartUpload checksum failures without changing the global streaming checksum mapping. Compare explicit multipart checksum types symmetrically, distinguish missing composite part checksums, and preserve the CRC64NVME canonicalization pending a direct AWS probe.

Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-27 09:05:49 +08:00
Feng Ruohang edc8be6ed1 deps: adopt Silo Go v7.3.1 stack
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-27 02:40:19 +08:00
Feng Ruohang 49c8aeac40 Merge pull request #37 from ycjlin/fix/listobjects-nosuchbucket-prefix
fix: ListObjects should return NoSuchBucket for prefix on missing bucket
2026-08-26 19:13:42 +08:00
Feng Ruohang e9c5340be9 fix: return NoSuchBucket from listing shortcuts
ListObjects shortcuts can return EOF before consulting storage, causing missing buckets to appear as empty listings. Verify bucket existence only on those shortcuts so the normal listing path retains the upstream fan-out optimization.

Cover ListObjects, ListObjectsV2, and ListObjectVersions at the object layer and verify HTTP 404 NoSuchBucket responses.

Fixes #32

Co-authored-by: Jason Lin <jason@JasondeMacBook-Air.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-26 19:02:25 +08:00
Feng Ruohang 2e2377d1c6 Merge pull request #73 from pgsty/codex/issue-21478
fix: authorize user status changes by target status
2026-08-26 14:28:04 +08:00
Feng Ruohang 58735ee382 fix: authorize user status changes by target status
Signed-off-by: Feng Ruohang <rh@vonng.com>
2026-08-26 14:19:39 +08:00