Skip to content

Commit

Permalink
Make it run on Catalina
Browse files Browse the repository at this point in the history
closes #158, closes #77
  • Loading branch information
grishka committed May 22, 2024
1 parent 10d63f1 commit 5e69970
Show file tree
Hide file tree
Showing 11 changed files with 102 additions and 59 deletions.
24 changes: 12 additions & 12 deletions NearDrop.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -688,7 +688,7 @@
"@executable_path/../Frameworks",
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0.2;
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down Expand Up @@ -749,7 +749,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -804,7 +804,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
Expand All @@ -823,7 +823,7 @@
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_LSUIElement = YES;
Expand All @@ -834,8 +834,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 2.0.3;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0.4;
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -855,7 +855,7 @@
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 8;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_LSUIElement = YES;
Expand All @@ -866,8 +866,8 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 2.0.3;
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 2.0.4;
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
Expand All @@ -885,7 +885,7 @@
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
EXECUTABLE_PREFIX = lib;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
Expand All @@ -901,7 +901,7 @@
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
EXECUTABLE_PREFIX = lib;
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
Expand Down
21 changes: 13 additions & 8 deletions NearDrop/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
}
}
nc.delegate=self
let incomingTransfersCategory=NDNotificationCenterHackery.hackedNotificationCategory()
let incomingTransfersCategory=UNNotificationCategory(identifier: "INCOMING_TRANSFERS", actions: [
UNNotificationAction(identifier: "ACCEPT", title: NSLocalizedString("Accept", comment: ""), options: UNNotificationActionOptions.authenticationRequired),
UNNotificationAction(identifier: "DECLINE", title: NSLocalizedString("Decline", comment: ""))
], intentIdentifiers: [])
let errorsCategory=UNNotificationCategory(identifier: "ERRORS", actions: [], intentIdentifiers: [])
nc.setNotificationCategories([incomingTransfersCategory, errorsCategory])
NearbyConnectionManager.shared.mainAppDelegate=self
Expand Down Expand Up @@ -79,9 +82,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
}

func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo) {
let notificationContent=UNMutableNotificationContent()
notificationContent.title="NearDrop"
notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!])
let fileStr:String
if let textTitle=transfer.textDescription{
fileStr=textTitle
Expand All @@ -90,14 +90,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
}else{
fileStr=String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), transfer.files.count)
}
let notificationContent=UNMutableNotificationContent()
notificationContent.title="NearDrop"
notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!])
notificationContent.body=String(format: NSLocalizedString("DeviceSendingFiles", value: "%1$@ is sending you %2$@", comment: ""), arguments: [device.name, fileStr])
notificationContent.sound = .default
notificationContent.categoryIdentifier="INCOMING_TRANSFERS"
notificationContent.userInfo=["transferID": transfer.id]
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
if #available(macOS 11.0, *){
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
}
let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil)
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
UNUserNotificationCenter.current().add(notificationReq)
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
}

func incomingTransfer(id: String, didFinishWith error: Error?) {
Expand All @@ -107,8 +112,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
notificationContent.title=String(format: NSLocalizedString("TransferError", value: "Failed to receive files from %@", comment: ""), arguments: [transfer.device.name])
if let ne=(error as? NearbyError){
switch ne{
case .inputOutput(let er):
notificationContent.body=er.localizedDescription
case .inputOutput:
notificationContent.body="I/O Error";
case .protocolError(_):
notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "")
case .requiredFieldMissing:
Expand Down
4 changes: 2 additions & 2 deletions NearDrop/MainMenu.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22505" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
Expand Down
1 change: 0 additions & 1 deletion NearDrop/NDNotificationCenterHackery.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface NDNotificationCenterHackery : NSObject

+ (UNNotificationCategory*)hackedNotificationCategory;
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content;

@end
Expand Down
7 changes: 0 additions & 7 deletions NearDrop/NDNotificationCenterHackery.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ @interface UNMutableNotificationContent (NDPrivateAPIs)

@implementation NDNotificationCenterHackery

+ (UNNotificationCategory*)hackedNotificationCategory{
UNNotificationAction *accept=[UNNotificationAction actionWithIdentifier:@"ACCEPT" title:NSLocalizedString(@"Accept", nil) options:0];
UNNotificationAction *decline=[UNNotificationAction actionWithIdentifier:@"DECLINE" title:NSLocalizedString(@"Decline", nil) options:0];
UNMutableNotificationCategory *category=[UNMutableNotificationCategory categoryWithIdentifier:@"INCOMING_TRANSFERS" actions:@[accept, decline] intentIdentifiers:@[] hiddenPreviewsBodyPlaceholder:@"" options: UNNotificationCategoryOptionCustomDismissAction];
return category;
}

+ (void)removeDefaultAction:(UNMutableNotificationContent*) content{
content.hasDefaultAction=false;
}
Expand Down
2 changes: 1 addition & 1 deletion NearbyShare/InboundNearbyConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class InboundNearbyConnection: NearbyConnection{
guard frame.payloadChunk.offset==currentOffset else { throw NearbyError.protocolError("Invalid offset into file \(frame.payloadChunk.offset), expected \(currentOffset)") }
guard currentOffset+Int64(frame.payloadChunk.body.count)<=fileInfo.meta.size else { throw NearbyError.protocolError("Transferred file size exceeds previously specified value") }
if frame.payloadChunk.body.count>0{
try fileInfo.fileHandle?.write(contentsOf: frame.payloadChunk.body)
fileInfo.fileHandle?.write(frame.payloadChunk.body)
transferredFiles[id]!.bytesTransferred+=Int64(frame.payloadChunk.body.count)
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
}else if (frame.payloadChunk.flags & 1)==1{
Expand Down
41 changes: 33 additions & 8 deletions NearbyShare/NearbyConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,31 @@ class NearbyConnection{
return String(format: "%04d", abs(hash))
}

internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{
return HMAC<SHA256>.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
}

internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{
var okm=Data()
var t=Data()
var i=0
while okm.count<length{
i=i+1
let toDigest=t+info+Data([UInt8(truncatingIfNeeded: i)])
t=HMAC<SHA256>.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})
okm=okm+t
}
return okm.subdata(in: 0..<length)
}

internal static func hkdf(inputKeyMaterial:SymmetricKey, salt:Data, info:Data, outputByteCount:Int) -> SymmetricKey{
if #available(macOS 11.0, *){
return HKDF<SHA256>.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount)
}else{
return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount))
}
}

internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }

Expand All @@ -341,26 +366,26 @@ class NearbyConnection{
var ukeyInfo=Data()
ukeyInfo.append(ukeyClientInitMsgData!)
ukeyInfo.append(ukeyServerInitMsgData!)
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let nextSecret=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)

pinCode=NearbyConnection.pinCodeFromAuthKey(authString)

let salt:Data=Data([0x82, 0xAA, 0x55, 0xA0, 0xD3, 0x97, 0xF8, 0x83, 0x46, 0xCA, 0x1C,
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])

let d2dClientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
let d2dServerKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)

sha=SHA256()
sha.update(data: "SecureMessage".data(using: .utf8)!)
let smsgSalt=Data(sha.finalize())

let clientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let clientHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let serverKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let serverHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)

if isServer(){
decryptKey=clientKey
Expand Down
2 changes: 1 addition & 1 deletion NearbyShare/NearbyConnectionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public enum NearbyError:Error{
case protocolError(_ message:String)
case requiredFieldMissing(_ message:String)
case ukey2
case inputOutput(cause:Errno)
case inputOutput
case canceled(reason:CancellationReason)

public enum CancellationReason{
Expand Down
22 changes: 17 additions & 5 deletions NearbyShare/OutboundNearbyConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,15 @@ class OutboundNearbyConnection:NearbyConnection{
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
meta.mimeType="application/octet-stream"
if let typeID=typeID{
let type=UTType(typeID)
if let type=type, let mimeType=type.preferredMIMEType{
meta.mimeType=mimeType
if #available(macOS 11.0, *){
let type=UTType(typeID)
if let type=type, let mimeType=type.preferredMIMEType{
meta.mimeType=mimeType
}
}else{
if let mimeType=UTTypeCopyPreferredTagWithClass(typeID as CFString, kUTTagClassMIMEType){
meta.mimeType=(mimeType.takeRetainedValue() as NSString) as String
}
}
}
if meta.mimeType.starts(with: "image/"){
Expand Down Expand Up @@ -358,8 +364,14 @@ class OutboundNearbyConnection:NearbyConnection{
currentTransfer=queue.removeFirst()
}

guard let fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
throw NearbyError.inputOutput(cause: Errno.ioError)
let fileBuffer:Data
if #available(macOS 10.15.4, *) {
guard let _fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
throw NearbyError.inputOutput
}
fileBuffer=_fileBuffer
} else {
fileBuffer=currentTransfer!.handle!.readData(ofLength: 512*1024)
}

var transfer=Location_Nearby_Connections_PayloadTransferFrame()
Expand Down
Loading

0 comments on commit 5e69970

Please sign in to comment.