فهرست منبع

update security shield

alqindiirsyam 1 سال پیش
والد
کامیت
747eaebf26

+ 10 - 8
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -551,11 +551,11 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 Nexilis.showLoader()
                 DispatchQueue.global().async {
                     let apiKey = Nexilis.sAPIKey
-                    var id = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
+                    var id = Utils.getConnectionID()
                     if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
                         id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         if(!id.isEmpty){
-                            Nexilis.changeUser(f_pin: id)
+//                            Nexilis.changeUser(f_pin: id)
                             UserDefaults.standard.setValue(id, forKey: "me")
                             Utils.setProfile(value: false)
                             UserDefaults.standard.synchronize()
@@ -601,12 +601,14 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                                 })
                             }
                         } else {
-                            Nexilis.hideLoader(completion: {
-                                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                                imageView.tintColor = .white
-                                let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                                banner.show()
-                            })
+                            DispatchQueue.main.async {
+                                Nexilis.hideLoader(completion: {
+                                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                                    imageView.tintColor = .white
+                                    let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                                    banner.show()
+                                })
+                            }
                         }
                     } else {
                         DispatchQueue.main.async {

+ 12 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/APIS.swift

@@ -734,6 +734,18 @@ public class APIS: NSObject {
     public static func openMail() {
         Nexilis.openmailAction()
     }
+    
+    public static func setCheckEmulator(isActive: Bool) {
+        Utils.bCheckEmulator = isActive
+    }
+    
+    public static func setCheckRootedDevice(isActive: Bool) {
+        Utils.bCheckRooted = isActive
+    }
+    
+    public static func setPreventScreenCapture(isActive: Bool) {
+        Utils.bPreventScreenCapture = isActive
+    }
 }
 
 extension UINavigationController {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/IncomingThread.swift

@@ -641,7 +641,7 @@ class IncomingThread {
     private func blockBuddy(message: TMessage) -> Void {
         let l_pin = message.getBody(key: CoreMessage_TMessageKey.L_PIN)
         let block = message.getBody(key: CoreMessage_TMessageKey.BLOCK)
-        print ("BLOCK INCOMING \(block)")
+        //print ("BLOCK INCOMING \(block)")
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             _ = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: [
                 "ex_block" : block
@@ -1206,7 +1206,7 @@ class IncomingThread {
         }
         if (!thumb_id.isEmpty) {
             Download().startHTTP(forKey: thumb_id) { (file, progress) in
-                print ("masuk download \(progress)")
+                //print ("masuk download \(progress)")
                 if(progress == 100) {
                     Nexilis.saveMessage(message: message, withStatus: false)
                     //print("save message incoming")

+ 134 - 16
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -14,6 +14,7 @@ import UIKit
 import FMDB
 import QuickLook
 import NotificationBannerSwift
+import CallKit
 
 public class Nexilis: NSObject {
     public static var sAPIKey = ""
@@ -169,29 +170,34 @@ public class Nexilis: NSObject {
                 Nexilis.ADDRESS = address.components(separatedBy: ":")[0]
                 Nexilis.PORT = Int(address.components(separatedBy: ":")[1]) ?? 0
     //            //print("IP PORT \(Nexilis.ADDRESS) <> \(Nexilis.PORT)")
-                var id = ""
-                if let device_id = UserDefaults.standard.string(forKey: "device_id") {
-                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: device_id, sStartWH: "09:00")
-                } else if let me = UserDefaults.standard.string(forKey: "me") {
-                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: me, sStartWH: "09:00")
-                } else {
-                    let uuid = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
-                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: uuid, sStartWH: "09:00")
-                    id = uuid
+                var id = Utils.getConnectionID()
+//                if let device_id = UserDefaults.standard.string(forKey: "device_id") {
+//                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: device_id, sStartWH: "09:00")
+//                } else if let me = UserDefaults.standard.string(forKey: "me") {
+//                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: me, sStartWH: "09:00")
+//                } else {
+//                    let uuid = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
+//                    try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: uuid, sStartWH: "09:00")
+//                    id = uuid
+//                }
+                if id.isEmpty {
+                    id = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
+                    Utils.setConnectionID(value: id)
                 }
+                try API.initConnection(bSwitchIP: false, sAPIK: apiKey, aAppMain: nil, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: id, sStartWH: "09:00")
                 
                 // wait until connection true
                 Nexilis.dispatch?.wait()
                 Nexilis.dispatch = nil
                 
     //            Nexilis.initiateAudio()
-                if(!id.isEmpty && (UserDefaults.standard.string(forKey: "me") == nil)){
+                if(UserDefaults.standard.string(forKey: "me") == nil){
                     if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000){
                         id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         let enable_signup = (response.getBody(key: CoreMessage_TMessageKey.IS_ENABLED_ANONYMOUS, default_value: "0")) == "1"
                         Utils.setForceAnonymous(value: enable_signup)
                         if(!id.isEmpty) {
-                            Nexilis.changeUser(f_pin: id)
+//                            Nexilis.changeUser(f_pin: id)
                             UserDefaults.standard.setValue(id, forKey: "me")
                         }
                     }
@@ -201,6 +207,8 @@ public class Nexilis: NSObject {
                     UserDefaults.standard.setValue(apiKey, forKey: "apiKey")
                 }
                 
+                getFeatureAccess()
+                
                 if let me = UserDefaults.standard.string(forKey: "me") {
                     if Utils.getForceAnonymous() || (!Utils.getForceAnonymous() && Utils.getSetProfile()) {
                         Database.shared.database?.inTransaction({ (fmdb, rollback) in
@@ -224,7 +232,6 @@ public class Nexilis: NSObject {
                             }
                         })
                     }
-                    getFeatureAccess()
                     getServiceBank()
                     getPullWorkingArea()
                     getPullGroupNoMember()
@@ -265,6 +272,87 @@ public class Nexilis: NSObject {
         //print("MANIA \(UIFont.systemFont(ofSize: 12)) <> \(UIFont.italicSystemFont(ofSize: 12)) <> \(UIFont.boldSystemFont(ofSize: 12))")
     }
     
+    private static func checkingEmulator() -> Bool {
+        if Utils.getCheckEmulator() {
+            #if arch(i386) || arch(x86_64)
+                UIApplication.shared.visibleViewController?.view.makeToast("121:Emulator detected".localized(), duration: 2)
+                return true
+            #else
+            #endif
+        }
+        return false
+    }
+    
+    private static func checkingRooted() -> Bool {
+        if Utils.getCheckRooted() {
+            #if arch(i386) || arch(x86_64)
+            return false
+            #else
+            let fileManager = FileManager.default
+            if fileManager.fileExists(atPath: "/Applications/Cydia.app") ||
+                fileManager.fileExists(atPath: "/Library/MobileSubstrate/MobileSubstrate.dylib") ||
+                fileManager.fileExists(atPath: "/bin/bash") ||
+                fileManager.fileExists(atPath: "/usr/sbin/sshd") ||
+                fileManager.fileExists(atPath: "/etc/apt") ||
+                fileManager.fileExists(atPath: "/private/var/lib/apt/") ||
+                fileManager.fileExists(atPath: "/Applications/FakeApp.app") {
+                UIApplication.shared.visibleViewController?.view.makeToast("126:Device is jailbroken".localized(), duration: 2)
+                return true
+            }
+            #endif
+        }
+        return false
+    }
+    
+    private static var screen: UIView!
+    @objc static func preventScreenRecording() {
+        let isCaptured = UIScreen.main.isCaptured
+        //print("isCaptured: \(isCaptured)")
+        if isCaptured {
+            blurScreen()
+        }
+        else {
+            removeBlurScreen()
+        }
+    }
+
+    private static func blurScreen(style: UIBlurEffect.Style = UIBlurEffect.Style.regular) {
+        screen = UIScreen.main.snapshotView(afterScreenUpdates: false)
+        let blurEffect = UIBlurEffect(style: style)
+        let blurBackground = UIVisualEffectView(effect: blurEffect)
+        screen.addSubview(blurBackground)
+        blurBackground.frame = (screen.frame)
+        if let window = UIApplication.shared.windows.first {
+            window.addSubview(screen)
+        } else {
+            //print("window nil")
+        }
+    }
+
+    private static func removeBlurScreen() {
+        screen?.removeFromSuperview()
+    }
+    
+    private static func makeSecure(window: UIWindow) {
+        let field = UITextField()
+
+        let view = UIView(frame: CGRect(x: 0, y: 0, width: field.frame.self.width, height: field.frame.self.height))
+
+        let image = UIImageView(image: UIImage.imageWithColor(color: .black, size: CGSize(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)))
+        image.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
+
+        field.isSecureTextEntry = true
+
+        window.addSubview(field)
+        view.addSubview(image)
+
+        window.layer.superlayer?.addSublayer(field.layer)
+        field.layer.sublayers?.last!.addSublayer(window.layer)
+
+        field.leftView = view
+        field.leftViewMode = .always
+    }
+    
     public static func addFB(viewController: UIViewController, fromMAB: Bool) {
         if let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {
             keyWindow.addSubview(floatingButton)
@@ -355,23 +443,53 @@ public class Nexilis: NSObject {
     
     private static func getFeatureAccess() {
         DispatchQueue.global().asyncAfter(deadline: .now(), execute: {
-            if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getFeatureAccessAll(), timeout: 10 * 1000), response.isOk() {
-                let data = response.getBody(key: CoreMessage_TMessageKey.DATA)
-                if !data.isEmpty {
-                    if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
+            Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "get_feature_access")!) { data, response, error in
+                if let data = data, let responseString = String(data: data, encoding: .utf8) {
+                    if let jsonArray = try! JSONSerialization.jsonObject(with: responseString.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                         do {
                             let umr = jsonArray[0]["upload_max_retry"] as? Int
                             let umt = jsonArray[0]["upload_max_time"] as? Int64
+                            let checkEmu = jsonArray[0]["check_emulator"] as? String
+                            let checkRooted = jsonArray[0]["check_rooted_device"] as? String
+                            let checkScreenCapt = jsonArray[0]["check_screen_capture"] as? String
                             if umr != nil {
                                 Utils.setMaxRetryUpload(value: "\(umr ?? 0)")
                             }
                             if umt != nil {
                                 Utils.setMaxRetryTimeUpload(value: "\(umt ?? 0)")
                             }
+                            if checkEmu != nil {
+                                Utils.setCheckEmulator(b: checkEmu == "1")
+                            }
+                            if checkRooted != nil {
+                                Utils.setCheckRooted(b: checkRooted == "1")
+                            }
+                            if checkScreenCapt != nil {
+                                Utils.setCheckScreenCapture(b: checkScreenCapt == "1")
+                            }
                         } catch {
                         }
                     }
                 }
+                if Utils.getCheckScreenCapture() {
+                    NotificationCenter.default.addObserver(self, selector: #selector(preventScreenRecording), name: UIScreen.capturedDidChangeNotification, object: nil)
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
+                        if let window = UIApplication.shared.windows.first {
+                            makeSecure(window: window)
+                        }
+                    })
+                }
+                if checkingEmulator() {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
+                        exit(0)
+                    })
+                }
+                
+                if checkingRooted() {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
+                        exit(0)
+                    })
+                }
             }
         })
     }

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/TMessage.swift

@@ -34,7 +34,7 @@ public class TMessage {
     public static let TYPE_NEED_ACK    =  "3"
     
     public init() {
-        mVersion = "1.0.109"
+        mVersion = "1.0.111"
         mBodies[CoreMessage_TMessageKey.IMEI] = Nexilis.getCLMUserId()
 //        mBodies[CoreMessage_TMessageKey.VERCOD] = UIApplication.appVersion
         mBodies[CoreMessage_TMessageKey.VERCOD] = "2.2.157"

+ 58 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Utils.swift

@@ -355,6 +355,29 @@ public final class Utils {
         task.resume()
     }
     
+    public static func postDataWithCookiesAndUserAgent(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
+        let parameters = [
+            "apikey": UserDefaults.standard.string(forKey: "apiKey") ?? "",
+            "f_pin": UserDefaults.standard.string(forKey: "me") ?? ""
+        ]
+        var jsonArray: [[String: Any]] = []
+        jsonArray.append(parameters)
+        guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonArray, options: []) else {
+            //print("Error: Unable to convert JSON array to data")
+            return
+        }
+        var request = URLRequest(url: url)
+        request.httpMethod = "POST"
+        request.setValue(Utils.getUserAgent(), forHTTPHeaderField: "User-Agent")
+        request.setValue(Utils.getCookiesMobile(), forHTTPHeaderField: "Cookie")
+        request.setValue("application/json;charset=UTF-8", forHTTPHeaderField: "Content-Type")
+        request.setValue("application/json", forHTTPHeaderField: "Accept")
+        request.httpBody = jsonData
+        //print("DATA SEND MOBILE \(Utils.getUserAgent()) <> \(Utils.getCookiesMobile())")
+        let task = URLSession.shared.dataTask(with: request, completionHandler: completion)
+        task.resume()
+    }
+    
     public static var inTabChats = false
     
     private static let I_BB = 48   // 0
@@ -556,6 +579,41 @@ public final class Utils {
             
         }
     }
+    
+    public static var bCheckEmulator = false
+    public static var bCheckRooted = false
+    public static var bPreventScreenCapture = false
+    
+    public static func setCheckEmulator(b: Bool) {
+        UserDefaults.standard.set(b, forKey: "pb_check_emulator")
+    }
+
+    public static func getCheckEmulator() -> Bool {
+        UserDefaults.standard.object(forKey: "pb_check_emulator") as? Bool ?? bCheckEmulator
+    }
+    
+    public static func setCheckRooted(b: Bool) {
+        UserDefaults.standard.set(b, forKey: "pb_check_rooted")
+    }
+
+    public static func getCheckRooted() -> Bool {
+        UserDefaults.standard.object(forKey: "pb_check_rooted") as? Bool ?? bCheckRooted
+    }
+    public static func setCheckScreenCapture(b: Bool) {
+        UserDefaults.standard.set(b, forKey: "pb_prevent_screen_capture")
+    }
+
+    public static func getCheckScreenCapture() -> Bool {
+        UserDefaults.standard.object(forKey: "pb_prevent_screen_capture") as? Bool ?? bPreventScreenCapture
+    }
+    
+    public static func setConnectionID(value: String) {
+        UserDefaults.standard.set(value, forKey: "connection_id")
+    }
+
+    public static func getConnectionID() -> String {
+        UserDefaults.standard.string(forKey: "connection_id") ?? ""
+    }
 }
 public extension UIImage {
     var jpeg: Data? { jpegData(compressionQuality: 1) }  // QUALITY min = 0 / max = 1

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/AudioViewController.swift

@@ -196,7 +196,7 @@ extension UIImageView {
                 self.backgroundColor = .clear
             } else {
                 Download().startHTTP(forKey: url) { (name, progress) in
-                    print ("masuk download \(progress)")
+                    //print ("masuk download \(progress)")
                     guard progress == 100 else {
                         return
                     }

+ 4 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeDeviceViewController.swift

@@ -134,7 +134,7 @@ public class ChangeDeviceViewController: UIViewController {
                         let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         let thumb = response.getBody(key: CoreMessage_TMessageKey.THUMB_ID, default_value: "")
                         if(!id.isEmpty) {
-                            Nexilis.changeUser(f_pin: id)
+//                            Nexilis.changeUser(f_pin: id)
                             Utils.setProfile(value: true)
                             UserDefaults.standard.synchronize()
                             // pos registration
@@ -252,8 +252,10 @@ public class ChangeDeviceViewController: UIViewController {
                     let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                     let thumb = response.getBody(key: CoreMessage_TMessageKey.THUMB_ID, default_value: "")
                     let device_id = response.getBody(key: CoreMessage_TMessageKey.IMEI, default_value: id)
+                    let last_sign = response.getBody(key: CoreMessage_TMessageKey.LAST_SIGN, default_value: "0")
+                    //print("last sign: \(last_sign)")
                     if(!id.isEmpty) {
-                        Nexilis.changeUser(f_pin: device_id)
+//                        Nexilis.changeUser(f_pin: device_id)
                         UserDefaults.standard.setValue(device_id, forKey: "device_id")
                         Utils.setProfile(value: true)
                         UserDefaults.standard.synchronize()

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift

@@ -466,11 +466,11 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                 Nexilis.showLoader()
                 DispatchQueue.global().async {
                     let apiKey = Nexilis.sAPIKey
-                    var id = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
+                    var id = Utils.getConnectionID()
                     if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
                         id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         if(!id.isEmpty){
-                            Nexilis.changeUser(f_pin: id)
+//                            Nexilis.changeUser(f_pin: id)
                             UserDefaults.standard.setValue(id, forKey: "me")
                             Utils.setProfile(value: false)
                             UserDefaults.standard.synchronize()

+ 4 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift

@@ -144,7 +144,7 @@ public class SignUpSignIn: UIViewController {
                         let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         let thumb = response.getBody(key: CoreMessage_TMessageKey.THUMB_ID, default_value: "")
                         if(!id.isEmpty) {
-                            Nexilis.changeUser(f_pin: id)
+//                            Nexilis.changeUser(f_pin: id)
                             Utils.setProfile(value: true)
                             UserDefaults.standard.synchronize()
                             // pos registration
@@ -286,8 +286,10 @@ public class SignUpSignIn: UIViewController {
                         let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
                         let thumb = response.getBody(key: CoreMessage_TMessageKey.THUMB_ID, default_value: "")
                         let device_id = response.getBody(key: CoreMessage_TMessageKey.IMEI, default_value: id)
+                        let last_sign = response.getBody(key: CoreMessage_TMessageKey.LAST_SIGN, default_value: "0")
+                        //print("last sign: \(last_sign)")
                         if(!id.isEmpty) {
-                            Nexilis.changeUser(f_pin: device_id)
+//                            Nexilis.changeUser(f_pin: device_id)
                             UserDefaults.standard.setValue(device_id, forKey: "device_id")
                             Utils.setProfile(value: true)
                             UserDefaults.standard.synchronize()