Support SMB3 encrypted connection

This commit is contained in:
Amir Abbas 2019-10-27 23:42:18 +03:30
parent 1a22bded08
commit b1c8588108
4 changed files with 37 additions and 13 deletions

View File

@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode10.2
osx_image: xcode11
xcode_project: $PROJECTNAME.xcodeproj
env:
global:

View File

@ -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)

View File

@ -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)
}
}
}

View File

@ -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)