Module: VagrantDockerCertificatesManager::OS
- Defined in:
- lib/vagrant-docker-certificates-manager/util/os.rb
Constant Summary collapse
- FIREFOX_ENTERPRISE_ROOTS_PREF =
Firefox on Windows does not ship with NSS certutil, so we enable security.enterprise_roots.enabled in each profile's user.js instead. This makes Firefox delegate trust to the Windows system cert store, which already contains the CA installed by win_install_cert.
'user_pref("security.enterprise_roots.enabled", true);'- FIREFOX_ENTERPRISE_ROOTS_KEY =
"security.enterprise_roots.enabled"
Class Method Summary collapse
- .detect ⇒ Object
- .linux_firefox_install(path, name) ⇒ Object
- .linux_firefox_profiles ⇒ Object
- .linux_firefox_uninstall(name) ⇒ Object
- .linux_has_cert_file?(name) ⇒ Boolean
-
.linux_install_cert(path, name, nss: true, firefox: false) ⇒ Object
── Linux ─────────────────────────────────────────────────────────────────.
- .linux_nss_install(path, name) ⇒ Object
- .linux_nss_uninstall(name) ⇒ Object
- .linux_uninstall_cert(name, nss: true, firefox: false) ⇒ Object
-
.mac_add_trusted_cert(path, _name) ⇒ Object
── macOS ─────────────────────────────────────────────────────────────────.
- .mac_has_cert_fingerprint?(fp) ⇒ Boolean
- .mac_remove_by_fp(fp) ⇒ Object
-
.run(*args) ⇒ Object
Runs an external command safely using the array form (no shell interpolation).
- .win_firefox_disable_enterprise_roots ⇒ Object
- .win_firefox_enable_enterprise_roots ⇒ Object
- .win_firefox_profiles ⇒ Object
- .win_has_cert_fingerprint?(fp) ⇒ Boolean
- .win_install_cert(path, name) ⇒ Object
- .win_remove_by_fp(fp) ⇒ Object
Class Method Details
.detect ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 11 def detect if defined?(Vagrant) && Vagrant.const_defined?(:Util) && Vagrant::Util.const_defined?(:Platform) return :mac if Vagrant::Util::Platform.darwin? return :windows if Vagrant::Util::Platform.windows? return :linux if Vagrant::Util::Platform.linux? else plat = RbConfig::CONFIG["host_os"].downcase return :mac if plat.include?("darwin") return :windows if plat =~ /mswin|mingw|windows/ return :linux if plat.include?("linux") end :unknown end |
.linux_firefox_install(path, name) ⇒ Object
102 103 104 105 106 107 108 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 102 def linux_firefox_install(path, name) linux_firefox_profiles.all? do |profile| run("certutil", "-A", "-n", Cert.nickname_for(name), "-t", "C,,", "-i", path.to_s, "-d", "sql:#{profile}").first end end |
.linux_firefox_profiles ⇒ Object
92 93 94 95 96 97 98 99 100 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 92 def linux_firefox_profiles home = Dir.home [ "#{home}/.mozilla/firefox", "#{home}/.var/app/org.mozilla.firefox/.mozilla/firefox", "#{home}/snap/firefox/common/.mozilla/firefox" ].select { |d| File.directory?(d) } .flat_map { |base| Dir.glob(File.join(base, "*.default*")) } end |
.linux_firefox_uninstall(name) ⇒ Object
110 111 112 113 114 115 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 110 def linux_firefox_uninstall(name) linux_firefox_profiles.each do |profile| run("certutil", "-D", "-n", Cert.nickname_for(name), "-d", "sql:#{profile}") end true end |
.linux_has_cert_file?(name) ⇒ Boolean
67 68 69 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 67 def linux_has_cert_file?(name) File.exist?("/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt") end |
.linux_install_cert(path, name, nss: true, firefox: false) ⇒ Object
── Linux ─────────────────────────────────────────────────────────────────
58 59 60 61 62 63 64 65 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 58 def linux_install_cert(path, name, nss: true, firefox: false) dest = "/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt" ok1, = run("sudo", "cp", path.to_s, dest) ok2, = run("sudo", "update-ca-certificates") okn = nss ? linux_nss_install(path, name) : true okf = firefox ? linux_firefox_install(path, name) : true ok1 && ok2 && okn && okf end |
.linux_nss_install(path, name) ⇒ Object
80 81 82 83 84 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 80 def linux_nss_install(path, name) db = "sql:#{File.join(Dir.home, '.pki', 'nssdb')}" run("certutil", "-d", db, "-A", "-t", "C,,", "-n", Cert.nickname_for(name), "-i", path.to_s).first end |
.linux_nss_uninstall(name) ⇒ Object
86 87 88 89 90 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 86 def linux_nss_uninstall(name) db = "sql:#{File.join(Dir.home, '.pki', 'nssdb')}" run("certutil", "-d", db, "-D", "-n", Cert.nickname_for(name)) true end |
.linux_uninstall_cert(name, nss: true, firefox: false) ⇒ Object
71 72 73 74 75 76 77 78 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 71 def linux_uninstall_cert(name, nss: true, firefox: false) dest = "/usr/local/share/ca-certificates/#{Cert::MARKER.downcase}-#{name}.crt" run("sudo", "rm", "-f", dest) run("sudo", "update-ca-certificates") linux_nss_uninstall(name) if nss linux_firefox_uninstall(name) if firefox true end |
.mac_add_trusted_cert(path, _name) ⇒ Object
── macOS ─────────────────────────────────────────────────────────────────
33 34 35 36 37 38 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 33 def mac_add_trusted_cert(path, _name) run("sudo", "security", "add-trusted-cert", "-d", "-r", "trustRoot", "-k", "/Library/Keychains/System.keychain", path.to_s).first end |
.mac_has_cert_fingerprint?(fp) ⇒ Boolean
40 41 42 43 44 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 40 def mac_has_cert_fingerprint?(fp) ok, out, = run("security", "find-certificate", "-a", "-Z", "/Library/Keychains/System.keychain") ok && out.include?(fp.to_s) end |
.mac_remove_by_fp(fp) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 46 def mac_remove_by_fp(fp) ok, out, = run("security", "find-certificate", "-a", "-Z", "/Library/Keychains/System.keychain") return true unless ok hash = out.lines.find { |l| l =~ /SHA-1 hash:\s*#{Regexp.escape(fp)}/i } ? fp : nil return true unless hash run("sudo", "security", "delete-certificate", "-Z", hash.to_s, "/Library/Keychains/System.keychain").first end |
.run(*args) ⇒ Object
Runs an external command safely using the array form (no shell interpolation).
26 27 28 29 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 26 def run(*args) out, err, st = Open3.capture3(*args) [st.success?, out, err] end |
.win_firefox_disable_enterprise_roots ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 146 def win_firefox_disable_enterprise_roots win_firefox_profiles.each do |profile| user_js = File.join(profile, "user.js") next unless File.exist?(user_js) updated = File.read(user_js) .lines .reject { |l| l.include?(FIREFOX_ENTERPRISE_ROOTS_KEY) } .join File.write(user_js, updated) end true rescue StandardError false end |
.win_firefox_enable_enterprise_roots ⇒ Object
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 134 def win_firefox_enable_enterprise_roots win_firefox_profiles.each do |profile| user_js = File.join(profile, "user.js") content = File.exist?(user_js) ? File.read(user_js) : "" next if content.include?(FIREFOX_ENTERPRISE_ROOTS_KEY) File.open(user_js, "a") { |f| f.puts FIREFOX_ENTERPRISE_ROOTS_PREF } end true rescue StandardError false end |
.win_firefox_profiles ⇒ Object
127 128 129 130 131 132 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 127 def win_firefox_profiles appdata = (ENV["APPDATA"] || File.join(Dir.home, "AppData", "Roaming")).tr("\\", "/") base = "#{appdata}/Mozilla/Firefox/Profiles" return [] unless File.directory?(base) Dir.glob("#{base}/*").select { |d| File.directory?(d) } end |
.win_has_cert_fingerprint?(fp) ⇒ Boolean
190 191 192 193 194 195 196 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 190 def win_has_cert_fingerprint?(fp) ps = "if (Get-ChildItem Cert:\\LocalMachine\\Root | " \ "Where-Object { $_.Thumbprint -eq '#{fp}' }) { 'YES' } else { 'NO' }" ok, out, = run("powershell", "-NoProfile", "-NonInteractive", "-EncodedCommand", Base64.strict_encode64(ps.encode("UTF-16LE"))) ok && out.to_s.strip == "YES" end |
.win_install_cert(path, name) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 161 def win_install_cert(path, name) fp = Cert.sha1(path) nick = Cert.nickname_for(name).gsub("'", "''") abs = File.(path).tr("/", "\\").gsub("'", "''") ps = <<~PS $ErrorActionPreference = 'Stop' Import-Certificate -FilePath '#{abs}' -CertStoreLocation Cert:\\LocalMachine\\Root | Out-Null $cert = Get-ChildItem Cert:\\LocalMachine\\Root | Where-Object { $_.Thumbprint -eq '#{fp}' } if ($cert) { $cert.FriendlyName = '#{nick}' } PS encoded = Base64.strict_encode64(ps.encode("UTF-16LE")) # Try non-elevated first (works if already admin) ok, = run("powershell", "-NoProfile", "-NonInteractive", "-EncodedCommand", encoded) unless ok # Elevate via UAC elev = "Start-Process PowerShell -Verb RunAs -Wait " \ "-ArgumentList '-NonInteractive','-NoProfile','-EncodedCommand','#{encoded}'" elev_encoded = Base64.strict_encode64(elev.encode("UTF-16LE")) ok, = run("powershell", "-NoProfile", "-NonInteractive", "-EncodedCommand", elev_encoded) return false unless ok end win_firefox_enable_enterprise_roots true end |
.win_remove_by_fp(fp) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/vagrant-docker-certificates-manager/util/os.rb', line 198 def win_remove_by_fp(fp) ps = <<~PS $ErrorActionPreference = 'Stop' Get-ChildItem Cert:\\LocalMachine\\Root | Where-Object { $_.Thumbprint -eq '#{fp}' } | Remove-Item PS encoded = Base64.strict_encode64(ps.encode("UTF-16LE")) ok, = run("powershell", "-NoProfile", "-NonInteractive", "-EncodedCommand", encoded) return true if ok elev = "Start-Process PowerShell -Verb RunAs -Wait " \ "-ArgumentList '-NonInteractive','-NoProfile','-EncodedCommand','#{encoded}'" elev_encoded = Base64.strict_encode64(elev.encode("UTF-16LE")) ok = run("powershell", "-NoProfile", "-NonInteractive", "-EncodedCommand", elev_encoded).first win_firefox_disable_enterprise_roots if ok ok end |