Support SMB3 encrypted connection
This commit is contained in:
parent
1a22bded08
commit
b1c8588108
|
@ -1,5 +1,5 @@
|
|||
language: objective-c
|
||||
osx_image: xcode10.2
|
||||
osx_image: xcode11
|
||||
xcode_project: $PROJECTNAME.xcodeproj
|
||||
env:
|
||||
global:
|
||||
|
|
|
@ -195,21 +195,27 @@ public class AMSMB2: NSObject, NSSecureCoding, Codable, NSCopying, CustomReflect
|
|||
|
||||
/**
|
||||
Connects to a share.
|
||||
|
||||
- Parameters:
|
||||
- gracefully: share name to connect.
|
||||
- encrypted: uses SMB3 encryption if `true`, it fails with error in case server does not support encryption.
|
||||
- completionHandler: closure will be run after enumerating is completed.
|
||||
|
||||
*/
|
||||
@objc(connectShareWithName:completionHandler:)
|
||||
open func connectShare(name: String, completionHandler: @escaping (_ error: Error?) -> Void) {
|
||||
@objc(connectShareWithName:encrypted:completionHandler:)
|
||||
open func connectShare(name: String, encrypted: Bool = false, completionHandler: @escaping (_ error: Error?) -> Void) {
|
||||
with(completionHandler: completionHandler) {
|
||||
self.connectLock.lock()
|
||||
defer { self.connectLock.unlock() }
|
||||
if self.context == nil || self.context?.fileDescriptor == -1 || self.context?.share != name {
|
||||
self.context = try self.connnect(shareName: name)
|
||||
self.context = try self.connnect(shareName: name, encrypted: encrypted)
|
||||
}
|
||||
|
||||
// Workaround disgraceful disconnect issue (e.g. server timeout)
|
||||
do {
|
||||
try self.context!.echo()
|
||||
} catch {
|
||||
self.context = try self.connnect(shareName: name)
|
||||
self.context = try self.connnect(shareName: name, encrypted: encrypted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -263,7 +269,7 @@ public class AMSMB2: NSObject, NSSecureCoding, Codable, NSCopying, CustomReflect
|
|||
open func listShares(enumerateHidden: Bool = false,
|
||||
completionHandler: @escaping (_ result: Result<[(name: String, comment: String)], Error>) -> Void) {
|
||||
// Connecting to Interprocess Communication share
|
||||
with(shareName: "IPC$", completionHandler: completionHandler) { context in
|
||||
with(shareName: "IPC$", encrypted: false, completionHandler: completionHandler) { context in
|
||||
return try context.shareEnum().map(enumerateHidden: enumerateHidden)
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +277,7 @@ public class AMSMB2: NSObject, NSSecureCoding, Codable, NSCopying, CustomReflect
|
|||
/// Only for test case coverage
|
||||
func _swift_listShares(enumerateHidden: Bool = false,
|
||||
completionHandler: @escaping (_ result: Result<[(name: String, comment: String)], Error>) -> Void) {
|
||||
with(shareName: "IPC$", completionHandler: completionHandler) { context in
|
||||
with(shareName: "IPC$", encrypted: false, completionHandler: completionHandler) { context in
|
||||
return try context.shareEnumSwift().map(enumerateHidden: enumerateHidden)
|
||||
}
|
||||
}
|
||||
|
@ -720,9 +726,10 @@ extension AMSMB2 {
|
|||
}
|
||||
}
|
||||
|
||||
private func initContext(_ context: SMB2Context) {
|
||||
private func initContext(_ context: SMB2Context, encrypted: Bool) {
|
||||
context.securityMode = [.enabled]
|
||||
context.authentication = .ntlmSsp
|
||||
context.seal = encrypted
|
||||
|
||||
context.domain = _domain
|
||||
context.workstation = _workstation
|
||||
|
@ -731,10 +738,10 @@ extension AMSMB2 {
|
|||
context.timeout = _timeout
|
||||
}
|
||||
|
||||
fileprivate func connnect(shareName: String) throws -> SMB2Context {
|
||||
fileprivate func connnect(shareName: String, encrypted: Bool) throws -> SMB2Context {
|
||||
let context = try SMB2Context(timeout: self._timeout)
|
||||
self.context = context
|
||||
self.initContext(context)
|
||||
self.initContext(context, encrypted: encrypted)
|
||||
let server = url.host! + (url.port.map { ":\($0)" } ?? "")
|
||||
try context.connect(server: server, share: shareName, user: self._user)
|
||||
return context
|
||||
|
@ -782,11 +789,11 @@ extension AMSMB2 {
|
|||
}
|
||||
|
||||
|
||||
fileprivate func with<T>(shareName: String, completionHandler: @escaping (Result<T, Error>) -> Void,
|
||||
fileprivate func with<T>(shareName: String, encrypted: Bool, completionHandler: @escaping (Result<T, Error>) -> Void,
|
||||
handler: @escaping (_ context: SMB2Context) throws -> T) {
|
||||
queue {
|
||||
do {
|
||||
let context = try self.connnect(shareName: shareName)
|
||||
let context = try self.connnect(shareName: shareName, encrypted: encrypted)
|
||||
defer { try? context.disconnect() }
|
||||
|
||||
let result = try handler(context)
|
||||
|
|
|
@ -145,7 +145,7 @@ extension SMB2Context {
|
|||
}
|
||||
set {
|
||||
try? withThreadSafeContext { (context) in
|
||||
smb2_set_seal(context, newValue ? -1 : 0)
|
||||
smb2_set_seal(context, newValue ? 1 : 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,27 @@
|
|||
import Foundation
|
||||
|
||||
extension AMSMB2 {
|
||||
/**
|
||||
Connects to a share.
|
||||
|
||||
- Parameters:
|
||||
- gracefully: share name to connect.
|
||||
- encrypted: uses SMB3 encryption if `true`, it fails with error in case server does not support encryption.
|
||||
- completionHandler: closure will be run after enumerating is completed.
|
||||
|
||||
*/
|
||||
@available(swift, obsoleted: 1.0)
|
||||
@objc(connectShareWithName:completionHandler:)
|
||||
open func __connectShare(name: String, completionHandler: @escaping (_ error: Error?) -> Void) {
|
||||
self.connectShare(name: name, completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
/**
|
||||
Disconnects from a share.
|
||||
|
||||
- Important: Disconnecting when an operation is in progress may cause disgraceful termination of operation.
|
||||
*/
|
||||
@available(swift, obsoleted: 1.0)
|
||||
@objc(disconnectShare)
|
||||
open func __disconnectShare() {
|
||||
self.disconnectShare()
|
||||
|
@ -27,6 +43,7 @@ extension AMSMB2 {
|
|||
|
||||
- Important: Disconnecting when an operation is in progress may cause disgraceful termination of operation.
|
||||
*/
|
||||
@available(swift, obsoleted: 1.0)
|
||||
@objc(disconnectShareWithCompletionHandler:)
|
||||
open func __disconnectShare(completionHandler: SimpleCompletionHandler) {
|
||||
self.disconnectShare(completionHandler: completionHandler)
|
||||
|
|
Loading…
Reference in New Issue