MESSENGER-3416 login hashes

This commit is contained in:
Frank Rotermund
2022-09-19 13:03:18 +02:00
parent 5c2bc8dc4b
commit 28200d5cb4
7 changed files with 134 additions and 0 deletions

View File

@@ -95,6 +95,9 @@
"bum_authetication_title" = "Einloggen mit Matrix-ID";
"bum_authetication_description" = "Wenn du einen Account auf einem Homeserver eingerichtet hast, benutze deine Matrix-ID (z.B. @benutzer:domain.com) und Passwort";
// MARK: - bum authentication protection
"bum_authentication_protection_error" = "Der angegebene Server ist nicht für die Nutzung mit %@ zugelassen.";
// MARK: - Onboarding

View File

@@ -96,6 +96,8 @@
"bum_authetication_title" = "Sign in with Matrix ID";
"bum_authetication_description" = "If you set up an account on a homeserver, use your Matrix ID (e.g. @user:domain.com) and password below.";
// MARK: - bum authentication protection
"bum_authentication_protection_error" = "This server is not available for usage with %@.";
// MARK: - Titles

View File

@@ -31,6 +31,10 @@ public class BWIL10n: NSObject {
public static var biometricsModeCantUnlockButtonTitle: String {
return BWIL10n.tr("Bwi", "biometrics_mode_cant_unlock_button_title")
}
/// Der angegebene Server ist nicht für die Nutzung mit %@ zugelassen.
public static func bumAuthenticationProtectionError(_ p1: String) -> String {
return BWIL10n.tr("Bwi", "bum_authentication_protection_error", p1)
}
/// Wenn du einen Account auf einem Homeserver eingerichtet hast, benutze deine Matrix-ID (z.B. @benutzer:domain.com) und Passwort
public static var bumAutheticationDescription: String {
return BWIL10n.tr("Bwi", "bum_authetication_description")

View File

@@ -978,6 +978,17 @@
if (sender == _submitButton)
{
if (BwiBuildSettings.bwiEnableLoginProtection) {
LoginProtectionService* service = [[LoginProtectionService alloc] init];
service.hashes = BwiBuildSettings.bwiHashes;
if (![service isValid:self->mxRestClient.homeserver]) {
NSError *error = [[NSError alloc] initWithDomain:@"LoginProtectionError" code:0 userInfo:@{
NSLocalizedDescriptionKey: }];
[self onFailureDuringAuthRequest:error];
return;
}
}
// Disable user interaction to prevent multiple requests
self.userInteractionEnabled = NO;

View File

@@ -103,4 +103,12 @@ final class BwiBuildSettings: NSObject {
// clear media cache every time when leaving a room vc: no media should be saved on device for security purposes
static let bwiClearMediaCacheOnRoomExit = true
static let bwiEnableLoginProtection = true
static let bwiHashes = [ "a3f65e35a7476799afe8d80282fb3c45b39dab06d1d8c70dc98e45ab7d8e93a9",
"2fda1a831655c22a5e6096d7cfbff4429fbf27891141e191b46adbf168142a11",
"4f8cbb3fef885f7284d0477d797d7007f0e1ba76221834132752f4d645796e28",
"24c2ec541e61e8e68944b96dc45ed5df12f6bdbda283cb0b3a522742aa970256",
"1be0b314a6c915d4475290522baef5b642db1b6d68937792b8e0eb5b7b0d6666" ]
}

View File

@@ -0,0 +1,47 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Foundation
import CryptoKit
@objcMembers class LoginProtectionService : NSObject {
var hashes: [String]?
@objc func isValid(_ urlString: String) -> Bool {
guard let hashes = hashes else {
return false
}
let string = self.normalizeLoginUrl(urlString)
let hashedString = self.hashedString(string)
return hashes.contains(hashedString)
}
private func normalizeLoginUrl(_ urlString: String) -> String {
var tmpString = urlString.replacingOccurrences(of: "https://", with: "")
tmpString = tmpString.replacingOccurrences(of: "http://", with: "")
return tmpString
}
private func hashedString(_ string: String) -> String {
let data = Data(string.utf8)
let hash = SHA256.hash(data: data)
return hash.compactMap { String(format: "%02x", $0) }.joined()
}
}

View File

@@ -0,0 +1,59 @@
//
/*
* Copyright (c) 2022 BWI GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import XCTest
class LoginProtectionTests: XCTestCase {
let hashes = ["34f2dfdb69edeef64ae9f53cea21c7e27db19566d440174c5bc3949d87ae90f6",
"04feebbb6cc530f26db673ee7d781c57870cfc7c6d1814d63dc703a3da522619"
]
func testValidURL() throws {
let service = LoginProtectionService()
service.hashes = hashes
XCTAssertTrue(service.isValid("https://www.wellbehaved.de"))
}
func testInvalidURL() throws {
let service = LoginProtectionService()
service.hashes = hashes
XCTAssertFalse(service.isValid("https://www.unknown.org"))
}
func testSimpleURL() throws {
let service = LoginProtectionService()
service.hashes = hashes
XCTAssertTrue(service.isValid("www.simple.com"))
}
func testMalformatedURL() throws {
let service = LoginProtectionService()
service.hashes = hashes
XCTAssertFalse(service.isValid("ur%%l@blalalal"))
}
func testNoHashlist() throws {
let service = LoginProtectionService()
XCTAssertFalse(service.isValid("https://www.wellbehaved.de"))
}
}