mirror of
https://github.com/grishka/NearDrop.git
synced 2026-04-03 01:36:15 +02:00
@@ -662,7 +662,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 2.0.2;
|
MARKETING_VERSION = 2.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -688,7 +688,7 @@
|
|||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
"@executable_path/../../../../Frameworks",
|
"@executable_path/../../../../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 2.0.2;
|
MARKETING_VERSION = 2.0.2;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -749,7 +749,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
@@ -804,7 +804,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@@ -823,7 +823,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 7;
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
INFOPLIST_KEY_LSUIElement = YES;
|
INFOPLIST_KEY_LSUIElement = YES;
|
||||||
@@ -834,8 +834,8 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 2.0.3;
|
MARKETING_VERSION = 2.0.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -855,7 +855,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NearDrop/NearDrop.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 7;
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||||
INFOPLIST_KEY_LSUIElement = YES;
|
INFOPLIST_KEY_LSUIElement = YES;
|
||||||
@@ -866,8 +866,8 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/../Frameworks",
|
"@executable_path/../Frameworks",
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||||
MARKETING_VERSION = 2.0.3;
|
MARKETING_VERSION = 2.0.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
@@ -885,7 +885,7 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
||||||
EXECUTABLE_PREFIX = lib;
|
EXECUTABLE_PREFIX = lib;
|
||||||
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
|
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)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -901,7 +901,7 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
DYLIB_INSTALL_NAME_BASE = "@executable_path/../Frameworks";
|
||||||
EXECUTABLE_PREFIX = lib;
|
EXECUTABLE_PREFIX = lib;
|
||||||
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
|
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)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
@@ -34,7 +34,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nc.delegate=self
|
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: [])
|
let errorsCategory=UNNotificationCategory(identifier: "ERRORS", actions: [], intentIdentifiers: [])
|
||||||
nc.setNotificationCategories([incomingTransfersCategory, errorsCategory])
|
nc.setNotificationCategories([incomingTransfersCategory, errorsCategory])
|
||||||
NearbyConnectionManager.shared.mainAppDelegate=self
|
NearbyConnectionManager.shared.mainAppDelegate=self
|
||||||
@@ -79,9 +82,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo) {
|
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
|
let fileStr:String
|
||||||
if let textTitle=transfer.textDescription{
|
if let textTitle=transfer.textDescription{
|
||||||
fileStr=textTitle
|
fileStr=textTitle
|
||||||
@@ -90,14 +90,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
|||||||
}else{
|
}else{
|
||||||
fileStr=String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), transfer.files.count)
|
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.body=String(format: NSLocalizedString("DeviceSendingFiles", value: "%1$@ is sending you %2$@", comment: ""), arguments: [device.name, fileStr])
|
||||||
notificationContent.sound = .default
|
notificationContent.sound = .default
|
||||||
notificationContent.categoryIdentifier="INCOMING_TRANSFERS"
|
notificationContent.categoryIdentifier="INCOMING_TRANSFERS"
|
||||||
notificationContent.userInfo=["transferID": transfer.id]
|
notificationContent.userInfo=["transferID": transfer.id]
|
||||||
|
if #available(macOS 11.0, *){
|
||||||
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
|
NDNotificationCenterHackery.removeDefaultAction(notificationContent)
|
||||||
|
}
|
||||||
let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil)
|
let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil)
|
||||||
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
|
|
||||||
UNUserNotificationCenter.current().add(notificationReq)
|
UNUserNotificationCenter.current().add(notificationReq)
|
||||||
|
self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func incomingTransfer(id: String, didFinishWith error: Error?) {
|
func incomingTransfer(id: String, didFinishWith error: Error?) {
|
||||||
@@ -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])
|
notificationContent.title=String(format: NSLocalizedString("TransferError", value: "Failed to receive files from %@", comment: ""), arguments: [transfer.device.name])
|
||||||
if let ne=(error as? NearbyError){
|
if let ne=(error as? NearbyError){
|
||||||
switch ne{
|
switch ne{
|
||||||
case .inputOutput(let er):
|
case .inputOutput:
|
||||||
notificationContent.body=er.localizedDescription
|
notificationContent.body="I/O Error";
|
||||||
case .protocolError(_):
|
case .protocolError(_):
|
||||||
notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "")
|
notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "")
|
||||||
case .requiredFieldMissing:
|
case .requiredFieldMissing:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-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>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@interface NDNotificationCenterHackery : NSObject
|
@interface NDNotificationCenterHackery : NSObject
|
||||||
|
|
||||||
+ (UNNotificationCategory*)hackedNotificationCategory;
|
|
||||||
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content;
|
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -35,13 +35,6 @@
|
|||||||
|
|
||||||
@implementation NDNotificationCenterHackery
|
@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{
|
+ (void)removeDefaultAction:(UNMutableNotificationContent*) content{
|
||||||
content.hasDefaultAction=false;
|
content.hasDefaultAction=false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 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") }
|
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{
|
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)
|
transferredFiles[id]!.bytesTransferred+=Int64(frame.payloadChunk.body.count)
|
||||||
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
|
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
|
||||||
}else if (frame.payloadChunk.flags & 1)==1{
|
}else if (frame.payloadChunk.flags & 1)==1{
|
||||||
|
|||||||
@@ -319,6 +319,31 @@ class NearbyConnection{
|
|||||||
return String(format: "%04d", abs(hash))
|
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{
|
internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
|
||||||
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
|
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") }
|
||||||
|
|
||||||
@@ -341,8 +366,8 @@ class NearbyConnection{
|
|||||||
var ukeyInfo=Data()
|
var ukeyInfo=Data()
|
||||||
ukeyInfo.append(ukeyClientInitMsgData!)
|
ukeyInfo.append(ukeyClientInitMsgData!)
|
||||||
ukeyInfo.append(ukeyServerInitMsgData!)
|
ukeyInfo.append(ukeyServerInitMsgData!)
|
||||||
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".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=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".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)
|
pinCode=NearbyConnection.pinCodeFromAuthKey(authString)
|
||||||
|
|
||||||
@@ -350,17 +375,17 @@ class NearbyConnection{
|
|||||||
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
|
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
|
||||||
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])
|
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 d2dClientKey=NearbyConnection.hkdf(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 d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
||||||
|
|
||||||
sha=SHA256()
|
sha=SHA256()
|
||||||
sha.update(data: "SecureMessage".data(using: .utf8)!)
|
sha.update(data: "SecureMessage".data(using: .utf8)!)
|
||||||
let smsgSalt=Data(sha.finalize())
|
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 clientKey=NearbyConnection.hkdf(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 clientHmacKey=NearbyConnection.hkdf(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 serverKey=NearbyConnection.hkdf(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 serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||||
|
|
||||||
if isServer(){
|
if isServer(){
|
||||||
decryptKey=clientKey
|
decryptKey=clientKey
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public enum NearbyError:Error{
|
|||||||
case protocolError(_ message:String)
|
case protocolError(_ message:String)
|
||||||
case requiredFieldMissing(_ message:String)
|
case requiredFieldMissing(_ message:String)
|
||||||
case ukey2
|
case ukey2
|
||||||
case inputOutput(cause:Errno)
|
case inputOutput
|
||||||
case canceled(reason:CancellationReason)
|
case canceled(reason:CancellationReason)
|
||||||
|
|
||||||
public enum CancellationReason{
|
public enum CancellationReason{
|
||||||
|
|||||||
@@ -277,10 +277,16 @@ class OutboundNearbyConnection:NearbyConnection{
|
|||||||
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
|
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
|
||||||
meta.mimeType="application/octet-stream"
|
meta.mimeType="application/octet-stream"
|
||||||
if let typeID=typeID{
|
if let typeID=typeID{
|
||||||
|
if #available(macOS 11.0, *){
|
||||||
let type=UTType(typeID)
|
let type=UTType(typeID)
|
||||||
if let type=type, let mimeType=type.preferredMIMEType{
|
if let type=type, let mimeType=type.preferredMIMEType{
|
||||||
meta.mimeType=mimeType
|
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/"){
|
if meta.mimeType.starts(with: "image/"){
|
||||||
meta.type = .image
|
meta.type = .image
|
||||||
@@ -358,8 +364,14 @@ class OutboundNearbyConnection:NearbyConnection{
|
|||||||
currentTransfer=queue.removeFirst()
|
currentTransfer=queue.removeFirst()
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
|
let fileBuffer:Data
|
||||||
throw NearbyError.inputOutput(cause: Errno.ioError)
|
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()
|
var transfer=Location_Nearby_Connections_PayloadTransferFrame()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-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>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22505"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@@ -32,9 +32,6 @@
|
|||||||
<subviews>
|
<subviews>
|
||||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NVE-vN-dkz">
|
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NVE-vN-dkz">
|
||||||
<rect key="frame" x="325" y="3" width="76" height="32"/>
|
<rect key="frame" x="325" y="3" width="76" height="32"/>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cP1-hK-9ZX"/>
|
|
||||||
</constraints>
|
|
||||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Up-t3-mwm">
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6Up-t3-mwm">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -42,6 +39,9 @@
|
|||||||
Gw
|
Gw
|
||||||
</string>
|
</string>
|
||||||
</buttonCell>
|
</buttonCell>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="60" id="cP1-hK-9ZX"/>
|
||||||
|
</constraints>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="cancel:" target="-2" id="Qav-AK-DGt"/>
|
<action selector="cancel:" target="-2" id="Qav-AK-DGt"/>
|
||||||
</connections>
|
</connections>
|
||||||
@@ -57,7 +57,7 @@ Gw
|
|||||||
</constraints>
|
</constraints>
|
||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NearDropIcon" id="q3u-Am-ZIA"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NearDropIcon" id="q3u-Am-ZIA"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aNc-0i-CWK">
|
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aNc-0i-CWK">
|
||||||
<rect key="frame" x="19" y="0.0" width="67" height="16"/>
|
<rect key="frame" x="19" y="0.0" width="67" height="16"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="NearDrop" allowsEditingTextAttributes="YES" id="0xp-rC-2gr">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="left" title="NearDrop" allowsEditingTextAttributes="YES" id="0xp-rC-2gr">
|
||||||
<font key="font" metaFont="systemBold"/>
|
<font key="font" metaFont="systemBold"/>
|
||||||
@@ -83,7 +83,7 @@ Gw
|
|||||||
</constraints>
|
</constraints>
|
||||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="jOq-9r-V1W"/>
|
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="jOq-9r-V1W"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OEz-QK-nem">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OEz-QK-nem">
|
||||||
<rect key="frame" x="29" y="196" width="367" height="16"/>
|
<rect key="frame" x="29" y="196" width="367" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" id="opy-Bj-x6u">
|
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" id="opy-Bj-x6u">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -116,10 +116,10 @@ Gw
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="521" height="100"/>
|
<rect key="frame" x="0.0" y="0.0" width="521" height="100"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<progressIndicator maxValue="100" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fCj-wF-rEj">
|
<progressIndicator wantsLayer="YES" maxValue="100" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fCj-wF-rEj">
|
||||||
<rect key="frame" x="245" y="68" width="32" height="32"/>
|
<rect key="frame" x="245" y="68" width="32" height="32"/>
|
||||||
</progressIndicator>
|
</progressIndicator>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="27P-yf-gUd">
|
<textField wantsLayer="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="27P-yf-gUd">
|
||||||
<rect key="frame" x="189" y="42" width="144" height="16"/>
|
<rect key="frame" x="189" y="42" width="144" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" title="Looking for devices..." id="NaJ-Wx-Pim">
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Looking for devices..." id="NaJ-Wx-Pim">
|
||||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||||
@@ -127,7 +127,7 @@ Gw
|
|||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V5W-Rm-YVM">
|
<textField wantsLayer="YES" focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V5W-Rm-YVM">
|
||||||
<rect key="frame" x="-2" y="0.0" width="525" height="32"/>
|
<rect key="frame" x="-2" y="0.0" width="525" height="32"/>
|
||||||
<textFieldCell key="cell" alignment="center" title="If you don't see your device, open "Google Files" app and tap "Receive" on the Nearby Share tab." id="vla-gF-eJo">
|
<textFieldCell key="cell" alignment="center" title="If you don't see your device, open "Google Files" app and tap "Receive" on the Nearby Share tab." id="vla-gF-eJo">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -185,7 +185,7 @@ Gw
|
|||||||
<constraint firstAttribute="bottom" secondItem="84U-lB-SRB" secondAttribute="bottom" id="uh8-T1-Vd8"/>
|
<constraint firstAttribute="bottom" secondItem="84U-lB-SRB" secondAttribute="bottom" id="uh8-T1-Vd8"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</customView>
|
</customView>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dJc-gw-4ux">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dJc-gw-4ux">
|
||||||
<rect key="frame" x="-2" y="56" width="388" height="16"/>
|
<rect key="frame" x="-2" y="56" width="388" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" id="QzI-qQ-OBb">
|
<textFieldCell key="cell" lineBreakMode="truncatingTail" alignment="center" id="QzI-qQ-OBb">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@@ -199,7 +199,7 @@ Gw
|
|||||||
<constraint firstAttribute="width" constant="200" id="bM2-Ih-2UC"/>
|
<constraint firstAttribute="width" constant="200" id="bM2-Ih-2UC"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</progressIndicator>
|
</progressIndicator>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y8I-D3-scQ">
|
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="y8I-D3-scQ">
|
||||||
<rect key="frame" x="165" y="0.0" width="54" height="16"/>
|
<rect key="frame" x="165" y="0.0" width="54" height="16"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" id="Iin-UY-IE5">
|
<textFieldCell key="cell" lineBreakMode="clipping" id="Iin-UY-IE5">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
|
|||||||
for attachment in attachments as NSArray{
|
for attachment in attachments as NSArray{
|
||||||
let provider=attachment as! NSItemProvider
|
let provider=attachment as! NSItemProvider
|
||||||
provider.loadItem(forTypeIdentifier: kUTTypeURL as String) { data, err in
|
provider.loadItem(forTypeIdentifier: kUTTypeURL as String) { data, err in
|
||||||
if let url=URL(dataRepresentation: data as! Data, relativeTo: nil, isAbsolute: false){
|
if let urlData=data as? Data{
|
||||||
|
if let url=URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: false){
|
||||||
self.urls.append(url)
|
self.urls.append(url)
|
||||||
if self.urls.count==attachments.count{
|
if self.urls.count==attachments.count{
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@@ -52,6 +53,14 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}else if let url=data as? NSURL{
|
||||||
|
self.urls.append(url as URL)
|
||||||
|
if self.urls.count==attachments.count{
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.urlsReady()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user