yamine 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73e497200efd0723559dff2f57e920e3d126d3caecf302770c37bec613d7998e
4
- data.tar.gz: 2203cabc149df919703fb1182fb9ad76e9c6729d4ed105455c749dbfa7611593
3
+ metadata.gz: 06f020588bc63954dd44b5a99b598995ec3e6f562c03756b867d26ff44178af8
4
+ data.tar.gz: 97f1613f7ad01d1362e4098651048addd3a4a738912c6bd83427e3ea9453ad8d
5
5
  SHA512:
6
- metadata.gz: d30e26aec61c7036e349a84f6f241291756c7ee3207f6e1de210cb47465ccc94279619cc9657d3ecbc477b8983be8027ae2303d43456b4891762f79dec7bd885
7
- data.tar.gz: 1a6a7e1b4e402b822a3d6f70ed6b19881c8927563c131875b322a7b750c9ec9368ba8a7f45ff99badfe55d23c54a964f163a80b8d10d6c45aa6a5a3ae5d9abc9
6
+ metadata.gz: 3f03809157db470e905542751e16d8a6cb6edd6b91a78637f20e85fb5670e6b30e15f717d1bbaed714c70b077a756fe97744bfb27521304606b2d661dea57eab
7
+ data.tar.gz: 83bb42d5eb49f6ee4007d04fa3e1b13024a46044d1afc7756a126f43384f60cb9c6ca57d7440d77ffcbacd37b9d95b04dbf8eb933bbf1676a10440e4951bdba7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.2] — 2026-09-10
4
+
5
+ ### Added
6
+
7
+ - `doctor` reports trusted CAs that are no longer the one on disk
8
+ (`[warn] ca: CA trusted, but N superseded CA(s) are still trusted —
9
+ run: yamine trust`). Pruning only runs inside `trust`, so after a CA
10
+ regeneration (including the rename) a superseded root would sit in the
11
+ keychain waiting for the next missing-CA event — possibly forever.
12
+ Unrelated trusted roots are never counted, and an unreadable keychain
13
+ stays silent: doctor is a read-only probe and must not fail.
14
+
15
+
3
16
  ## [0.10.1] — 2026-09-10
4
17
 
5
18
  ### Fixed
data/lib/yamine/doctor.rb CHANGED
@@ -174,11 +174,45 @@ module Yamine
174
174
  unless File.file?(paths[:cert])
175
175
  return Check.new(name: "ca", ok: false, message: "no CA yet — run: yamine trust")
176
176
  end
177
- if Certs.trusted?(dir)
178
- Check.new(name: "ca", ok: true, message: "CA trusted")
177
+ unless Certs.trusted?(dir)
178
+ return Check.new(name: "ca", ok: false, message: "CA not trusted — run: yamine trust")
179
+ end
180
+
181
+ # Trusted CAs that are not the one now on disk. They accumulate from
182
+ # CA regeneration (missing, expiring, or renamed — the ask-local
183
+ # rename regenerates every machine's CA), and a trusted root whose
184
+ # superseded private key is still on disk is a liability. Pruning
185
+ # only happens when `trust` runs, so after a rename it would wait
186
+ # for the next missing-CA event — i.e. possibly forever. Surface it
187
+ # here with the one command that clears it.
188
+ stale = stale_ca_count(dir)
189
+ if stale.positive?
190
+ Check.new(name: "ca", ok: true, warn: true,
191
+ message: "CA trusted, but #{stale} superseded CA(s) are still trusted" \
192
+ " — run: yamine trust")
179
193
  else
180
- Check.new(name: "ca", ok: false, message: "CA not trusted — run: yamine trust")
194
+ Check.new(name: "ca", ok: true, message: "CA trusted")
195
+ end
196
+ end
197
+
198
+ # How many trusted certificates carry one of our CA names without
199
+ # being the CA currently on disk. Best-effort: 0 when the keychain
200
+ # cannot be read (doctor must never fail on a read-only probe).
201
+ def stale_ca_count(dir = Certs.state_dir)
202
+ return 0 unless Trust.respond_to?(:keychain_certs)
203
+
204
+ current = Trust.fingerprint_of(Certs.ca_paths(dir)[:cert])
205
+ return 0 unless current
206
+
207
+ names = Certs.ca_common_names
208
+ Trust.keychains.sum do |keychain|
209
+ Trust.keychain_certs(keychain).count do |entry|
210
+ entry[:fingerprint] != current &&
211
+ names.any? { |n| entry[:subject].include?(n) }
212
+ end
181
213
  end
214
+ rescue StandardError
215
+ 0
182
216
  end
183
217
 
184
218
  def print(checks, out: $stdout, json: false)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yamine
4
- VERSION = "0.10.1"
4
+ VERSION = "0.10.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yamine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto