NCNetworkingSync.m 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. //
  2. // NCNetworkingSync.m
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 29/10/17.
  6. // Copyright © 2017 TWS. All rights reserved.
  7. //
  8. #import "NCNetworkingSync.h"
  9. #import "CCUtility.h"
  10. #import "CCCertificate.h"
  11. #import "NCBridgeSwift.h"
  12. /*********************************************************************************
  13. Netwok call synchronous mode, use this only from :
  14. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  15. });
  16. *********************************************************************************/
  17. @implementation NCNetworkingSync
  18. + (NCNetworkingSync *)sharedManager {
  19. static NCNetworkingSync *sharedManager;
  20. @synchronized(self)
  21. {
  22. if (!sharedManager) {
  23. sharedManager = [NCNetworkingSync new];
  24. }
  25. return sharedManager;
  26. }
  27. }
  28. #pragma --------------------------------------------------------------------------------------------
  29. #pragma mark ============================
  30. #pragma --------------------------------------------------------------------------------------------
  31. - (NSError *)createFolder:(NSString *)folderPathName user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url encrypted:(BOOL)encrypted fileID:(NSString **)fileID
  32. {
  33. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  34. __block NSError *returnError = nil;
  35. __block NSString *returnFileID = nil;
  36. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  37. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  38. [communication setUserAgent:[CCUtility getUserAgent]];
  39. [communication readFile:folderPathName onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer) {
  40. dispatch_semaphore_signal(semaphore);
  41. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  42. [communication createFolder:folderPathName onCommunication:communication withForbiddenCharactersSupported:YES successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  43. NSDictionary *fields = [response allHeaderFields];
  44. returnFileID = [CCUtility removeForbiddenCharactersFileSystem:[fields objectForKey:@"OC-FileId"]];
  45. if (encrypted) {
  46. // MARK
  47. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:returnFileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  48. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] directoryID:nil];
  49. dispatch_semaphore_signal(semaphore);
  50. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  51. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  52. dispatch_semaphore_signal(semaphore);
  53. }];
  54. } else {
  55. [[NCManageDatabase sharedInstance] clearDateReadWithServerUrl:[CCUtility deletingLastPathComponentFromServerUrl:folderPathName] directoryID:nil];
  56. dispatch_semaphore_signal(semaphore);
  57. }
  58. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  59. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  60. dispatch_semaphore_signal(semaphore);
  61. } errorBeforeRequest:^(NSError *error) {
  62. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:response.statusCode userInfo:[NSDictionary dictionaryWithObject:response.description forKey:NSLocalizedDescriptionKey]];
  63. dispatch_semaphore_signal(semaphore);
  64. }];
  65. }];
  66. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  67. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  68. *fileID = returnFileID;
  69. return returnError;
  70. }
  71. #pragma --------------------------------------------------------------------------------------------
  72. #pragma mark ===== E2EE End-to-End Encryption =====
  73. #pragma --------------------------------------------------------------------------------------------
  74. // E2EE
  75. - (NSError *)markEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl
  76. {
  77. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  78. __block NSError *returnError = nil;
  79. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  80. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  81. [communication setUserAgent:[CCUtility getUserAgent]];
  82. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  83. // Read Folder
  84. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  85. if (items.count > 1) {
  86. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  87. dispatch_semaphore_signal(semaphore);
  88. return;
  89. }
  90. // LOCK
  91. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  92. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  93. // REMOVE METADATA
  94. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  95. NSLog(@"[LOG] Found metadata and delete");
  96. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  97. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  98. }];
  99. // MARK
  100. [communication markEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  101. // UNLOCK
  102. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  103. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  104. dispatch_semaphore_signal(semaphore);
  105. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  106. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  107. dispatch_semaphore_signal(semaphore);
  108. }];
  109. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  110. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_mark_folder_"];
  111. // UNLOCK
  112. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  113. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  114. dispatch_semaphore_signal(semaphore);
  115. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  116. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  117. dispatch_semaphore_signal(semaphore);
  118. }];
  119. }];
  120. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  121. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  122. dispatch_semaphore_signal(semaphore);
  123. }];
  124. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  125. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  126. dispatch_semaphore_signal(semaphore);
  127. }];
  128. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  129. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  130. return returnError;
  131. }
  132. - (NSError *)deletemarkEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID serverUrl:(NSString *)serverUrl
  133. {
  134. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  135. __block NSError *returnError = nil;
  136. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  137. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  138. [communication setUserAgent:[CCUtility getUserAgent]];
  139. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  140. // Read Folder
  141. [communication readFolder:serverUrl depth:@"1" withUserSessionToken:nil onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSArray *items, NSString *redirectedServer, NSString *tokenReadFolder) {
  142. if (items.count > 1) {
  143. returnError = [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:999 userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_directory_not_empty_", nil) forKey:NSLocalizedDescriptionKey]];
  144. dispatch_semaphore_signal(semaphore);
  145. return;
  146. }
  147. // LOCK
  148. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  149. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  150. // DELETE METADATA
  151. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  152. NSLog(@"[LOG] Found metadata and delete");
  153. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  154. NSLog(@"[LOG] %@", [NSString stringWithFormat:@"Remove metadata error %d", (int)response.statusCode]);
  155. }];
  156. // DELETE MARK
  157. [communication deletemarkEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  158. // UNLOCK
  159. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  160. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  161. dispatch_semaphore_signal(semaphore);
  162. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  163. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  164. dispatch_semaphore_signal(semaphore);
  165. }];
  166. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  167. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_mark_folder_"];
  168. // UNLOCK
  169. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  170. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  171. dispatch_semaphore_signal(semaphore);
  172. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  173. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  174. dispatch_semaphore_signal(semaphore);
  175. }];
  176. }];
  177. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  178. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  179. dispatch_semaphore_signal(semaphore);
  180. }];
  181. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *token, NSString *redirectedServer) {
  182. returnError = [self getError:response error:error descriptionDefault:@"_error_"];
  183. dispatch_semaphore_signal(semaphore);
  184. }];
  185. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  186. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  187. return returnError;
  188. }
  189. - (NSError *)getEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileID:(NSString *)fileID metadata:(NSString **)metadata
  190. {
  191. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  192. __block NSError *returnError = nil;
  193. __block NSString *returnMetadata = nil;
  194. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  195. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  196. [communication setUserAgent:[CCUtility getUserAgent]];
  197. [communication getEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  198. returnMetadata = encryptedMetadata;
  199. dispatch_semaphore_signal(semaphore);
  200. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  201. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_get_metadata_"];
  202. dispatch_semaphore_signal(semaphore);
  203. }];
  204. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  205. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  206. *metadata = returnMetadata;
  207. return returnError;
  208. }
  209. - (NSError *)deleteEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID unlock:(BOOL)unlock
  210. {
  211. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  212. __block NSError *returnError = nil;
  213. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  214. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  215. [communication setUserAgent:[CCUtility getUserAgent]];
  216. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  217. // LOCK
  218. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  219. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  220. // DELETE METADATA
  221. [communication deleteEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  222. // UNLOCK
  223. if (unlock) {
  224. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  225. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  226. dispatch_semaphore_signal(semaphore);
  227. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  228. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  229. dispatch_semaphore_signal(semaphore);
  230. }];
  231. } else {
  232. dispatch_semaphore_signal(semaphore);
  233. }
  234. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  235. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_delete_metadata_"];
  236. // UNLOCK
  237. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  238. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  239. dispatch_semaphore_signal(semaphore);
  240. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  241. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  242. dispatch_semaphore_signal(semaphore);
  243. }];
  244. }];
  245. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  246. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  247. dispatch_semaphore_signal(semaphore);
  248. }];
  249. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  250. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  251. return returnError;
  252. }
  253. - (NSError *)storeEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID metadata:(NSString *)metadata unlock:(BOOL)unlock
  254. {
  255. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  256. __block NSError *returnError = nil;
  257. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  258. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  259. [communication setUserAgent:[CCUtility getUserAgent]];
  260. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  261. // LOCK
  262. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  263. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  264. // STORE METADATA
  265. [communication storeEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  266. // UNLOCK
  267. if (unlock) {
  268. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  269. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  270. dispatch_semaphore_signal(semaphore);
  271. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  272. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  273. dispatch_semaphore_signal(semaphore);
  274. }];
  275. } else {
  276. dispatch_semaphore_signal(semaphore);
  277. }
  278. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  279. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_store_metadata_"];
  280. // UNLOCK
  281. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  282. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  283. dispatch_semaphore_signal(semaphore);
  284. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  285. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  286. dispatch_semaphore_signal(semaphore);
  287. }];
  288. }];
  289. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  290. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  291. dispatch_semaphore_signal(semaphore);
  292. }];
  293. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  294. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  295. return returnError;
  296. }
  297. - (NSError *)updateEndToEndMetadata:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID metadata:(NSString *)metadata unlock:(BOOL)unlock
  298. {
  299. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  300. __block NSError *returnError = nil;
  301. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  302. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  303. [communication setUserAgent:[CCUtility getUserAgent]];
  304. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  305. // LOCK
  306. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  307. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  308. // UPDATA METADATA
  309. [communication updateEndToEndMetadata:[url stringByAppendingString:@"/"] fileID:fileID encryptedMetadata:metadata token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *encryptedMetadata, NSString *redirectedServer) {
  310. // UNLOCK
  311. if (unlock) {
  312. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  313. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  314. dispatch_semaphore_signal(semaphore);
  315. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  316. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  317. dispatch_semaphore_signal(semaphore);
  318. }];
  319. } else {
  320. dispatch_semaphore_signal(semaphore);
  321. }
  322. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  323. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_update_metadata_"];
  324. // UNLOCK
  325. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  326. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  327. dispatch_semaphore_signal(semaphore);
  328. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  329. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  330. dispatch_semaphore_signal(semaphore);
  331. }];
  332. }];
  333. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  334. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  335. dispatch_semaphore_signal(semaphore);
  336. }];
  337. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  338. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  339. return returnError;
  340. }
  341. - (NSError *)lockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID
  342. {
  343. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  344. __block NSError *returnError = nil;
  345. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  346. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  347. [communication setUserAgent:[CCUtility getUserAgent]];
  348. tableE2eEncryptionLock *tableLock = [[NCManageDatabase sharedInstance] getE2ETokenLockWithServerUrl:serverUrl];
  349. // LOCK
  350. [communication lockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:tableLock.token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *token, NSString *redirectedServer) {
  351. [[NCManageDatabase sharedInstance] setE2ETokenLockWithServerUrl:serverUrl fileID:fileID token:token];
  352. dispatch_semaphore_signal(semaphore);
  353. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  354. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_lock_"];
  355. dispatch_semaphore_signal(semaphore);
  356. }];
  357. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  358. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  359. return returnError;
  360. }
  361. - (NSError *)unlockEndToEndFolderEncrypted:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url serverUrl:(NSString *)serverUrl fileID:(NSString *)fileID token:(NSString *)token
  362. {
  363. OCCommunication *communication = [CCNetworking sharedNetworking].sharedOCCommunication;
  364. __block NSError *returnError = nil;
  365. dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
  366. [communication setCredentialsWithUser:user andUserID:userID andPassword:password];
  367. [communication setUserAgent:[CCUtility getUserAgent]];
  368. // UNLOCK
  369. [communication unlockEndToEndFolderEncrypted:[url stringByAppendingString:@"/"] fileID:fileID token:token onCommunication:communication successRequest:^(NSHTTPURLResponse *response, NSString *redirectedServer) {
  370. [[NCManageDatabase sharedInstance] deteleE2ETokenLockWithServerUrl:serverUrl];
  371. dispatch_semaphore_signal(semaphore);
  372. } failureRequest:^(NSHTTPURLResponse *response, NSError *error, NSString *redirectedServer) {
  373. returnError = [self getError:response error:error descriptionDefault:@"_e2e_error_unlock_"];
  374. dispatch_semaphore_signal(semaphore);
  375. }];
  376. while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER))
  377. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:k_timeout_webdav]];
  378. return returnError;
  379. }
  380. - (NSError *)sendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url fileNameRename:(NSString *)fileName fileNameNewRename:(NSString *)fileNameNew
  381. {
  382. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  383. NSString *metadata;
  384. NSError *error;
  385. // Enabled E2E
  386. if ([CCUtility isEndToEndEnabled:account] == NO)
  387. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_not_enabled_", nil) forKey:NSLocalizedDescriptionKey]];
  388. // get Metadata for select updateEndToEndMetadata or storeEndToEndMetadata
  389. error = [[NCNetworkingSync sharedManager] getEndToEndMetadata:user userID:userID password:password url:url fileID:directory.fileID metadata:&metadata];
  390. if (error.code != 404 && error != nil) {
  391. return error;
  392. }
  393. // Rename
  394. if (fileName && fileNameNew)
  395. [[NCManageDatabase sharedInstance] renameFileE2eEncryptionWithServerUrl:serverUrl fileNameIdentifier:fileName newFileName:fileNameNew newFileNamePath:[CCUtility returnFileNamePathFromFileName:fileNameNew serverUrl:serverUrl activeUrl:url]];
  396. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  397. if (!tableE2eEncryption)
  398. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_record_not_found_", nil) forKey:NSLocalizedDescriptionKey]];
  399. NSString *e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  400. if (!e2eMetadataJSON)
  401. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  402. // send Metadata
  403. if (error == nil)
  404. error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:NO];
  405. else if (error.code == 404)
  406. error = [[NCNetworkingSync sharedManager] storeEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:NO];
  407. return error;
  408. }
  409. - (NSError *)rebuildAndSendEndToEndMetadataOnServerUrl:(NSString *)serverUrl account:(NSString *)account user:(NSString *)user userID:(NSString *)userID password:(NSString *)password url:(NSString *)url
  410. {
  411. NSError *error;
  412. NSString *e2eMetadataJSON;
  413. tableDirectory *directory = [[NCManageDatabase sharedInstance] getTableDirectoryWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  414. if (directory.e2eEncrypted == NO)
  415. return nil;
  416. NSArray *tableE2eEncryption = [[NCManageDatabase sharedInstance] getE2eEncryptionsWithPredicate:[NSPredicate predicateWithFormat:@"account = %@ AND serverUrl = %@", account, serverUrl]];
  417. if (tableE2eEncryption) {
  418. e2eMetadataJSON = [[NCEndToEndMetadata sharedInstance] encoderMetadata:tableE2eEncryption privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:serverUrl];
  419. if (!e2eMetadataJSON)
  420. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:k_CCErrorInternalError userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"_e2e_error_encode_metadata_", nil) forKey:NSLocalizedDescriptionKey]];
  421. error = [[NCNetworkingSync sharedManager] updateEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID metadata:e2eMetadataJSON unlock:YES];
  422. } else {
  423. [[NCNetworkingSync sharedManager] deleteEndToEndMetadata:user userID:userID password:password url:url serverUrl:serverUrl fileID:directory.fileID unlock:YES];
  424. }
  425. return error;
  426. }
  427. - (NSError *)getError:(NSHTTPURLResponse *)response error:(NSError *)error descriptionDefault:(NSString *)descriptionDefault
  428. {
  429. NSInteger errorCode = response.statusCode;
  430. NSString *errorDescription = response.description;
  431. if (errorDescription == nil || errorCode == 0) {
  432. errorCode = error.code;
  433. errorDescription = error.description;
  434. if (errorDescription == nil) errorDescription = NSLocalizedString(descriptionDefault, @"");
  435. }
  436. errorDescription = [NSString stringWithFormat:@"%@ [%ld] - %@", NSLocalizedString(descriptionDefault, @""), (long)errorCode, errorDescription];
  437. if (errorDescription.length >= 250) {
  438. errorDescription = [errorDescription substringToIndex:250];
  439. errorDescription = [errorDescription stringByAppendingString:@" ..."];
  440. }
  441. return [NSError errorWithDomain:@"com.nextcloud.nextcloud" code:errorCode userInfo:[NSDictionary dictionaryWithObject:errorDescription forKey:NSLocalizedDescriptionKey]];
  442. }
  443. @end