Skip to content

Commit e4de038

Browse files
authored
This is a continuation of #3879. (#3890)
Wire up fingerprint storage such that it is used for integrity checks of package downloads. Fingerprint must match previously recorded value (if any) or else it would result in an error.
1 parent b325031 commit e4de038

21 files changed

+791
-127
lines changed

Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ let package = Package(
155155
name: "PackageRegistry",
156156
dependencies: [
157157
"Basics",
158+
"PackageFingerprint",
158159
"PackageLoading",
159160
"PackageModel"
160161
],
@@ -309,6 +310,7 @@ let package = Package(
309310
name: "Workspace",
310311
dependencies: [
311312
"Basics",
313+
"PackageFingerprint",
312314
"PackageGraph",
313315
"PackageModel",
314316
"SourceControl",
@@ -328,6 +330,7 @@ let package = Package(
328330
"Basics",
329331
"Build",
330332
"PackageCollections",
333+
"PackageFingerprint",
331334
"PackageGraph",
332335
"SourceControl",
333336
"Workspace",
@@ -388,6 +391,7 @@ let package = Package(
388391
name: "SPMTestSupport",
389392
dependencies: [
390393
"Basics",
394+
"PackageFingerprint",
391395
"PackageGraph",
392396
"PackageLoading",
393397
"PackageRegistry",

Sources/Basics/FileSystem+Extensions.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift project authors
4+
Copyright (c) 2020-2021 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -18,7 +18,12 @@ import TSCBasic
1818
extension FileSystem {
1919
/// SwiftPM directory under user's home directory (~/.swiftpm)
2020
public var dotSwiftPM: AbsolutePath {
21-
return self.homeDirectory.appending(component: ".swiftpm")
21+
self.homeDirectory.appending(component: ".swiftpm")
22+
}
23+
24+
/// SwiftPM security directory
25+
public var swiftPMSecurityDirectory: AbsolutePath {
26+
self.dotSwiftPM.appending(component: "security")
2227
}
2328
}
2429

Sources/Commands/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ target_link_libraries(Commands PUBLIC
3434
Basics
3535
Build
3636
PackageCollections
37+
PackageFingerprint
3738
PackageGraph
3839
SourceControl
3940
TSCBasic

Sources/Commands/Options.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
4+
Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See http://swift.org/LICENSE.txt for license information
@@ -11,6 +11,7 @@
1111
import ArgumentParser
1212
import TSCBasic
1313
import TSCUtility
14+
import PackageFingerprint
1415
import PackageModel
1516
import SPMBuildCore
1617
import Build
@@ -90,6 +91,12 @@ enum BuildSystemKind: String, ExpressibleByArgument, CaseIterable {
9091
case xcode
9192
}
9293

94+
extension FingerprintCheckingMode: ExpressibleByArgument {
95+
public init?(argument: String) {
96+
self.init(rawValue: argument)
97+
}
98+
}
99+
93100
public extension Sanitizer {
94101
init(argument: String) throws {
95102
if let sanitizer = Sanitizer(rawValue: argument) {
@@ -348,6 +355,9 @@ public struct SwiftToolOptions: ParsableArguments {
348355
help: .hidden)
349356
var keychain: Bool = false
350357
#endif
358+
359+
@Option(name: .customLong("resolver-fingerprint-checking"))
360+
var resolverFingerprintCheckingMode: FingerprintCheckingMode = .warn
351361

352362
@Flag(name: .customLong("netrc"), help: .hidden)
353363
var _deprecated_netrc: Bool = false

Sources/Commands/SwiftTool.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ public class SwiftTool {
658658
workingDirectory: buildPath,
659659
editsDirectory: self.editsDirectory(),
660660
resolvedVersionsFile: self.resolvedVersionsFile(),
661+
sharedSecurityDirectory: localFileSystem.swiftPMSecurityDirectory,
661662
sharedCacheDirectory: sharedCacheDirectory,
662663
sharedConfigurationDirectory: sharedConfigurationDirectory
663664
),
@@ -669,6 +670,7 @@ public class SwiftTool {
669670
additionalFileRules: isXcodeBuildSystemEnabled ? FileRuleDescription.xcbuildFileTypes : FileRuleDescription.swiftpmFileTypes,
670671
resolverUpdateEnabled: !options.skipDependencyUpdate,
671672
resolverPrefetchingEnabled: options.shouldEnableResolverPrefetching,
673+
resolverFingerprintCheckingMode: self.options.resolverFingerprintCheckingMode,
672674
sharedRepositoriesCacheEnabled: self.options.useRepositoriesCache,
673675
delegate: delegate
674676
)

Sources/PackageFingerprint/FilePackageFingerprintStorage.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public struct FilePackageFingerprintStorage: PackageFingerprintStorage {
2222
private let encoder: JSONEncoder
2323
private let decoder: JSONDecoder
2424

25-
init(fileSystem: FileSystem, directoryPath: AbsolutePath) {
25+
public init(fileSystem: FileSystem, directoryPath: AbsolutePath) {
2626
self.fileSystem = fileSystem
2727
self.directoryPath = directoryPath
2828

Sources/PackageFingerprint/Model.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ import TSCUtility
1414
public struct Fingerprint: Equatable {
1515
public let origin: Origin
1616
public let value: String
17+
18+
public init(origin: Origin, value: String) {
19+
self.origin = origin
20+
self.value = value
21+
}
1722
}
1823

1924
public extension Fingerprint {
@@ -26,7 +31,7 @@ public extension Fingerprint {
2631
case sourceControl(Foundation.URL)
2732
case registry(Foundation.URL)
2833

29-
var kind: Fingerprint.Kind {
34+
public var kind: Fingerprint.Kind {
3035
switch self {
3136
case .sourceControl:
3237
return .sourceControl
@@ -35,7 +40,7 @@ public extension Fingerprint {
3540
}
3641
}
3742

38-
var url: Foundation.URL? {
43+
public var url: Foundation.URL? {
3944
switch self {
4045
case .sourceControl(let url):
4146
return url
@@ -56,3 +61,9 @@ public extension Fingerprint {
5661
}
5762

5863
public typealias PackageFingerprints = [Version: [Fingerprint.Kind: Fingerprint]]
64+
65+
public enum FingerprintCheckingMode: String {
66+
case strict
67+
case warn
68+
case none
69+
}

Sources/PackageFingerprint/PackageFingerprintStorage.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@ public protocol PackageFingerprintStorage {
2828
callback: @escaping (Result<Void, Error>) -> Void)
2929
}
3030

31+
public extension PackageFingerprintStorage {
32+
func get(package: PackageIdentity,
33+
version: Version,
34+
kind: Fingerprint.Kind,
35+
observabilityScope: ObservabilityScope,
36+
callbackQueue: DispatchQueue,
37+
callback: @escaping (Result<Fingerprint, Error>) -> Void) {
38+
self.get(package: package, version: version, observabilityScope: observabilityScope, callbackQueue: callbackQueue) { result in
39+
callback(result.tryMap { fingerprints in
40+
guard let fingerprint = fingerprints[kind] else {
41+
throw PackageFingerprintStorageError.notFound
42+
}
43+
return fingerprint
44+
})
45+
}
46+
}
47+
}
48+
3149
public enum PackageFingerprintStorageError: Error, Equatable {
3250
case conflict(given: Fingerprint, existing: Fingerprint)
3351
case notFound

Sources/PackageRegistry/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_library(PackageRegistry
1212
RegistryClient.swift)
1313
target_link_libraries(PackageRegistry PUBLIC
1414
Basics
15+
PackageFingerprint
1516
PackageLoading
1617
PackageModel
1718
TSCBasic

0 commit comments

Comments
 (0)