use of swift-crypto for linux, passwords hashed with SHA512, NSImage for macOS only

main 1.1.20
mr-elbe5 2021-04-16 12:43:09 +02:00
parent e0137f3948
commit 70ea2934f0
10 changed files with 176 additions and 28 deletions

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BandikaSwiftBase_BandikaSwiftBase"
BuildableName = "BandikaSwiftBase_BandikaSwiftBase"
BlueprintName = "BandikaSwiftBase_BandikaSwiftBase"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BandikaSwiftBase"
BuildableName = "BandikaSwiftBase"
BlueprintName = "BandikaSwiftBase"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BandikaSwiftBaseTests"
BuildableName = "BandikaSwiftBaseTests"
BlueprintName = "BandikaSwiftBaseTests"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BandikaSwiftBaseTests"
BuildableName = "BandikaSwiftBaseTests"
BlueprintName = "BandikaSwiftBaseTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "BandikaSwiftBase_BandikaSwiftBase"
BuildableName = "BandikaSwiftBase_BandikaSwiftBase"
BlueprintName = "BandikaSwiftBase_BandikaSwiftBase"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,6 +1,15 @@
{
"object": {
"pins": [
{
"package": "swift-crypto",
"repositoryURL": "https://github.com/apple/swift-crypto",
"state": {
"branch": null,
"revision": "3bea268b223651c4ab7b7b9ad62ef9b2d4143eb6",
"version": "1.1.6"
}
},
{
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio",
@ -24,8 +33,8 @@
"repositoryURL": "https://github.com/mr-elbe5/SwiftyHttpServer",
"state": {
"branch": null,
"revision": "4fda28adcc5999aa018f91796b19bb92b22adcd5",
"version": "1.1.12"
"revision": "7e809798b9bdfed52501c0180a17206c87749c1c",
"version": "1.1.13"
}
},
{

View File

@ -13,7 +13,8 @@ let package = Package(
targets: ["BandikaSwiftBase"]),
],
dependencies: [
.package(url: "https://github.com/mr-elbe5/SwiftyHttpServer", from: "1.1.12"),
.package(url: "https://github.com/mr-elbe5/SwiftyHttpServer", from: "1.1.13"),
.package(url: "https://github.com/apple/swift-crypto", from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@ -21,7 +22,8 @@ let package = Package(
.target(
name: "BandikaSwiftBase",
dependencies: [
"SwiftyHttpServer"
"SwiftyHttpServer",
.product(name: "Crypto", package: "swift-crypto")
],
resources: [
.copy("Resources")

View File

@ -31,7 +31,9 @@ public class ActionQueue{
if timer == nil{
stop()
}
timer = Timer.scheduledTimer(timeInterval: 30.0, target: self, selector: #selector(checkActions), userInfo: nil, repeats: true)
timer = Timer.scheduledTimer(withTimeInterval: 30.0, repeats: true) { timer in
self.checkActions()
}
}
public func stop(){
@ -49,7 +51,7 @@ public class ActionQueue{
}
}
@objc public func checkActions() {
public func checkActions() {
lock()
defer{unlock()}
for action in regularActions{

View File

@ -7,8 +7,9 @@
You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
import Foundation
import Foundation
#if os(macOS)
import Cocoa
extension NSImage {
@ -40,3 +41,5 @@ extension NSImage {
}
}
#endif

View File

@ -79,7 +79,7 @@ public class Statics: Codable{
public func initDefaults(){
salt = Statics.generateSaltString()
defaultPassword = UserSecurity.encryptPassword(password: "pass", salt: salt)
defaultPassword = UserSecurity.encryptPassword(password: "pass")
defaultLocale = Locale(identifier: "en")
shutdownCode = Statics.generateShutdownCode()
}
@ -94,27 +94,14 @@ public class Statics: Codable{
return true
}
private static func generateSalt() -> [UInt8] {
var bytes = [UInt8](repeating: 0, count: 8)
_ = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
return bytes
}
private static func generateSaltString() -> String {
let salt = Data(bytes: generateSalt(), count: 8).base64EncodedString()
let salt = String.generateRandomString(length: 8)
Log.debug("generated salt string '\(salt)'")
return salt
}
private static func generateShutdownCode() -> String {
var bytes = [UInt8](repeating: 0, count: 8)
_ = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
var code = Data(bytes: bytes, count: 8).base64EncodedString()
// replace leading "/" as it destroys valid shutdown url
if code.hasPrefix("/"){
code.remove(at: code.startIndex)
code = "#" + code
}
let code = String.generateRandomString(length: 8)
Log.debug("generated shutdown code '\(code)'")
return code
}

View File

@ -3,12 +3,16 @@
//
import Foundation
import Cocoa
import SwiftyHttpServer
#if os(macOS)
import Cocoa
#endif
extension MemoryFile{
public func createPreview(fileName: String, maxSize: Int) -> MemoryFile?{
#if os(macOS)
if let src = NSImage(data: data){
if let previewImage : NSImage = src.resizeMaintainingAspectRatio(withSize: NSSize(width: FileData.MAX_PREVIEW_SIDE, height: FileData.MAX_PREVIEW_SIDE)){
if let tiff = previewImage.tiffRepresentation, let tiffData = NSBitmapImageRep(data: tiff) {
@ -21,6 +25,9 @@ extension MemoryFile{
}
}
return nil
#else
return nil
#endif
}
}
}

View File

@ -175,8 +175,7 @@ public class UserContainer : DataContainer{
public func getUser(login: String, pwd: String) -> UserData?{
if let data = userLoginMap[login]{
let passwordHash : String = UserSecurity.encryptPassword(password: pwd, salt: Statics.instance.salt)
if data.passwordHash == passwordHash {
if UserSecurity.verifyPassword(savedHash: data.passwordHash, password: pwd){
return data
}
}

View File

@ -139,7 +139,7 @@ public class UserData: BaseData {
if password.isEmpty {
passwordHash = ""
} else {
passwordHash = UserSecurity.encryptPassword(password: password, salt: Statics.instance.salt)
passwordHash = UserSecurity.encryptPassword(password: password)
}
}

View File

@ -8,13 +8,35 @@
*/
import Foundation
import SwiftyLog
#if os(macOS)
// not available on linux, so no PBKDF2
import CommonCrypto
#endif
import Crypto
public class UserSecurity{
private static var rounds : UInt32 = 2205
private static var keyByteCount : Int = 160
public static func verifyPassword(savedHash: String, password: String) -> Bool{
var passwordHash : String = encryptPassword(password: password)
if savedHash == passwordHash {
return true
}
//backward compatibility
#if os(macOS)
passwordHash = encryptPassword(password: password, salt: Statics.instance.salt)
if savedHash == passwordHash {
return true
}
#endif
return false
}
#if os(macOS)
// not available on linux, so no PBKDF2
public static func encryptPassword(password : String, salt: String) -> String{
var outputBytes = Array<UInt8>(repeating: 0, count: kCCKeySizeAES256)
let status = CCKeyDerivationPBKDF(
@ -32,5 +54,17 @@ public class UserSecurity{
}
return Data(outputBytes).base64EncodedString()
}
#endif
public static func encryptPassword(password : String) -> String{
let inputData = Data(password.utf8)
let hashed = SHA512.hash(data: inputData)
let hashString = hashed.compactMap{
String(format: "%02x", $0)
}.joined()
Log.debug("password hash = \(hashString)")
return hashString
}
}