| ... | @@ -68,29 +68,93 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) !void { | ... | @@ -68,29 +68,93 @@ pub fn rescan(cb: *Bundle, gpa: Allocator) !void { |
| 68 | } | 68 | } |
| 69 | | 69 | |
| 70 | pub fn rescanLinux(cb: *Bundle, gpa: Allocator) !void { | 70 | pub fn rescanLinux(cb: *Bundle, gpa: Allocator) !void { |
| 71 | var dir = fs.openIterableDirAbsolute("/etc/ssl/certs", .{}) catch |err| switch (err) { | 71 | // Possible certificate files; stop after finding one. |
| 72 | error.FileNotFound => return, | 72 | const cert_file_paths = [_][]const u8{ |
| 73 | else => |e| return e, | 73 | "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. |
| | 74 | "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 |
| | 75 | "/etc/ssl/ca-bundle.pem", // OpenSUSE |
| | 76 | "/etc/pki/tls/cacert.pem", // OpenELEC |
| | 77 | "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 |
| | 78 | "/etc/ssl/cert.pem", // Alpine Linux |
| | 79 | }; |
| | 80 | |
| | 81 | // Possible directories with certificate files; all will be read. |
| | 82 | const cert_dir_paths = [_][]const u8{ |
| | 83 | "/etc/ssl/certs", // SLES10/SLES11 |
| | 84 | "/etc/pki/tls/certs", // Fedora/RHEL |
| | 85 | "/system/etc/security/cacerts", // Android |
| 74 | }; | 86 | }; |
| 75 | defer dir.close(); | | |
| 76 | | 87 | |
| 77 | cb.bytes.clearRetainingCapacity(); | 88 | cb.bytes.clearRetainingCapacity(); |
| 78 | cb.map.clearRetainingCapacity(); | 89 | cb.map.clearRetainingCapacity(); |
| 79 | | 90 | |
| 80 | var it = dir.iterate(); | 91 | scan: { |
| | 92 | for (cert_file_paths) |cert_file_path| { |
| | 93 | if (addCertsFromFilePathAbsolute(cb, gpa, cert_file_path)) |_| { |
| | 94 | break :scan; |
| | 95 | } else |err| switch (err) { |
| | 96 | error.FileNotFound => continue, |
| | 97 | else => |e| return e, |
| | 98 | } |
| | 99 | } |
| | 100 | |
| | 101 | for (cert_dir_paths) |cert_dir_path| { |
| | 102 | addCertsFromDirPathAbsolute(cb, gpa, cert_dir_path) catch |err| switch (err) { |
| | 103 | error.FileNotFound => continue, |
| | 104 | else => |e| return e, |
| | 105 | }; |
| | 106 | } |
| | 107 | } |
| | 108 | |
| | 109 | cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); |
| | 110 | } |
| | 111 | |
| | 112 | pub fn addCertsFromDirPath( |
| | 113 | cb: *Bundle, |
| | 114 | gpa: Allocator, |
| | 115 | dir: fs.Dir, |
| | 116 | sub_dir_path: []const u8, |
| | 117 | ) !void { |
| | 118 | var iterable_dir = try dir.openIterableDir(sub_dir_path, .{}); |
| | 119 | defer iterable_dir.close(); |
| | 120 | return addCertsFromDir(cb, gpa, iterable_dir); |
| | 121 | } |
| | 122 | |
| | 123 | pub fn addCertsFromDirPathAbsolute( |
| | 124 | cb: *Bundle, |
| | 125 | gpa: Allocator, |
| | 126 | abs_dir_path: []const u8, |
| | 127 | ) !void { |
| | 128 | assert(fs.path.isAbsolute(abs_dir_path)); |
| | 129 | var iterable_dir = try fs.openIterableDirAbsolute(abs_dir_path, .{}); |
| | 130 | defer iterable_dir.close(); |
| | 131 | return addCertsFromDir(cb, gpa, iterable_dir); |
| | 132 | } |
| | 133 | |
| | 134 | pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, iterable_dir: fs.IterableDir) !void { |
| | 135 | var it = iterable_dir.iterate(); |
| 81 | while (try it.next()) |entry| { | 136 | while (try it.next()) |entry| { |
| 82 | switch (entry.kind) { | 137 | switch (entry.kind) { |
| 83 | .File, .SymLink => {}, | 138 | .File, .SymLink => {}, |
| 84 | else => continue, | 139 | else => continue, |
| 85 | } | 140 | } |
| 86 | | 141 | |
| 87 | try addCertsFromFile(cb, gpa, dir.dir, entry.name); | 142 | try addCertsFromFilePath(cb, gpa, iterable_dir.dir, entry.name); |
| 88 | } | 143 | } |
| | 144 | } |
| 89 | | 145 | |
| 90 | cb.bytes.shrinkAndFree(gpa, cb.bytes.items.len); | 146 | pub fn addCertsFromFilePathAbsolute( |
| | 147 | cb: *Bundle, |
| | 148 | gpa: Allocator, |
| | 149 | abs_file_path: []const u8, |
| | 150 | ) !void { |
| | 151 | assert(fs.path.isAbsolute(abs_file_path)); |
| | 152 | var file = try fs.openFileAbsolute(abs_file_path, .{}); |
| | 153 | defer file.close(); |
| | 154 | return addCertsFromFile(cb, gpa, file); |
| 91 | } | 155 | } |
| 92 | | 156 | |
| 93 | pub fn addCertsFromFile( | 157 | pub fn addCertsFromFilePath( |
| 94 | cb: *Bundle, | 158 | cb: *Bundle, |
| 95 | gpa: Allocator, | 159 | gpa: Allocator, |
| 96 | dir: fs.Dir, | 160 | dir: fs.Dir, |
| ... | @@ -98,7 +162,10 @@ pub fn addCertsFromFile( | ... | @@ -98,7 +162,10 @@ pub fn addCertsFromFile( |
| 98 | ) !void { | 162 | ) !void { |
| 99 | var file = try dir.openFile(sub_file_path, .{}); | 163 | var file = try dir.openFile(sub_file_path, .{}); |
| 100 | defer file.close(); | 164 | defer file.close(); |
| | 165 | return addCertsFromFile(cb, gpa, file); |
| | 166 | } |
| 101 | | 167 | |
| | 168 | pub fn addCertsFromFile(cb: *Bundle, gpa: Allocator, file: fs.File) !void { |
| 102 | const size = try file.getEndPos(); | 169 | const size = try file.getEndPos(); |
| 103 | | 170 | |
| 104 | // We borrow `bytes` as a temporary buffer for the base64-encoded data. | 171 | // We borrow `bytes` as a temporary buffer for the base64-encoded data. |
| ... | @@ -152,6 +219,7 @@ pub fn addCertsFromFile( | ... | @@ -152,6 +219,7 @@ pub fn addCertsFromFile( |
| 152 | | 219 | |
| 153 | const builtin = @import("builtin"); | 220 | const builtin = @import("builtin"); |
| 154 | const std = @import("../../std.zig"); | 221 | const std = @import("../../std.zig"); |
| | 222 | const assert = std.debug.assert; |
| 155 | const fs = std.fs; | 223 | const fs = std.fs; |
| 156 | const mem = std.mem; | 224 | const mem = std.mem; |
| 157 | const crypto = std.crypto; | 225 | const crypto = std.crypto; |