Skip to content

Commit

Permalink
added override script and secure token admin reset
Browse files Browse the repository at this point in the history
  • Loading branch information
twocanoes committed May 24, 2023
1 parent 488b664 commit 6717b3a
Show file tree
Hide file tree
Showing 26 changed files with 275 additions and 196 deletions.
211 changes: 162 additions & 49 deletions DefaultsOverride.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,87 +7,200 @@

import Cocoa

class DefaultsOverride: UserDefaults {
public class DefaultsOverride: UserDefaults {

var cachedPrefs=Dictionary<String,Any>()
func refreshCachedPrefs() {
static let standardOverride = DefaultsOverride()

private override init?(suiteName suitename: String?) {
TCSLogWithMark()
super.init(suiteName: suitename)
self.refreshCachedPrefs()
}
private convenience init() {
TCSLogWithMark()
self.init(suiteName: nil)!
}
var cachedPrefs=Dictionary<String, Any>()
@objc func refreshCachedPrefs() {
TCSLogWithMark()
cachedPrefs=Dictionary()
let prefScriptPath = super.string(forKey: PrefKeys.settingsOverrideScriptPath.rawValue)
if let prefScriptPath = prefScriptPath {
TCSLogErrorWithMark("Pref script defined at \(prefScriptPath)")
if FileManager.default.fileExists(atPath:prefScriptPath)==false{
TCSLogErrorWithMark("Pref script defined but does not exist")
let prefScriptPath = UserDefaults.standard.string(forKey: PrefKeys.settingsOverrideScriptPath.rawValue)
guard let prefScriptPath = prefScriptPath else {
TCSLogWithMark("no override defined")
return
}
TCSLogErrorWithMark("Pref script defined at \(prefScriptPath)")
if FileManager.default.fileExists(atPath:prefScriptPath)==false{
TCSLogErrorWithMark("Pref script defined but does not exist")
return
}
do {
let attributes = try FileManager.default.attributesOfItem(atPath: prefScriptPath)

guard let ownerID=attributes[.ownerAccountID] as? NSNumber else {
TCSLogErrorWithMark("Could not get owner id")
return
}
guard let permission = attributes[.posixPermissions] as? NSNumber else

if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: prefScriptPath), let ownerID=attributes[.ownerAccountID] as? NSNumber,
let permission = attributes[.posixPermissions] as? NSNumber
{
TCSLogErrorWithMark("Could not get permission")
return

if ownerID.uintValue != 0 {
TCSLogErrorWithMark("override script is not owned by root. not running")
return
}
}
if ownerID.uintValue != 0 {
TCSLogErrorWithMark("override script is not owned by root. not running: \(ownerID.debugDescription)")
return
}

let unixPermissions = permission.int16Value
let unixPermissions = permission.int16Value

if unixPermissions & 0x15 != 0 {
TCSLogErrorWithMark("override script cannot be writable by anyone besides root. not running.")
return
if unixPermissions & 0x12 != 0 {
TCSLogErrorWithMark("override script cannot be writable by anyone besides root. not running: \(unixPermissions)")
return

}
let scriptRes=cliTask(prefScriptPath)
}

let scriptRes=cliTask(prefScriptPath)

if scriptRes.count>0{
let rawData = scriptRes.data(using: .utf8)
var format: PropertyListSerialization.PropertyListFormat = .xml
TCSLogWithMark(scriptRes)
if scriptRes.count==0{
TCSLogErrorWithMark("script did not return anything")
return
}
TCSLogWithMark()
guard let rawData = scriptRes.data(using: .utf8) else {
TCSLogErrorWithMark("could not convert raw data");
return
}
var format: PropertyListSerialization.PropertyListFormat = .xml

TCSLogWithMark()

do {
TCSLogWithMark()

/*
guard let propertyListObject = try PropertyListSerialization.propertyList(from: rawData, options: [], format: &format) else {
TCSLogErrorWithMark("could not turn to plist")
return
}
var propertyListObject = [ String: [String]]()
*/
let propertyListObject = try PropertyListSerialization.propertyList(from: rawData, options: [], format: &format)

do {
propertyListObject = try PropertyListSerialization.propertyList(from: rawData!, options: [], format: &format) as! [ String: [String]]
} catch {
TCSLogErrorWithMark("Error converting script to property list: \(scriptRes)")
return
}
if let propertyListObject = propertyListObject as? [String: Any] {
cachedPrefs=propertyListObject

}

else {
TCSLogWithMark("Could not convert to plist")
}
} catch {
TCSLogErrorWithMark("Error converting script to property list: \(scriptRes)")
return
}
TCSLogWithMark()

}

catch {

TCSLogErrorWithMark(error.localizedDescription)
}




}
override func string(forKey defaultName: String) -> String? {
return super.string(forKey: defaultName)
override public func string(forKey defaultName: String) -> String? {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? String{
return defaultName
}
return UserDefaults.standard.string(forKey: defaultName)
}
override func object(forKey defaultName: String) -> Any? {
return super.object(forKey: defaultName)
override public func object(forKey defaultName: String) -> Any? {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName]{
return defaultName
}

return UserDefaults.standard.object(forKey: defaultName)
}

override func array(forKey defaultName: String) -> [Any]? {
return super.array(forKey: defaultName)
override public func array(forKey defaultName: String) -> [Any]? {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? [Any]{
return defaultName
}

return UserDefaults.standard.array(forKey: defaultName)
}
override func data(forKey defaultName: String) -> Data? {
return super.data(forKey: defaultName)
override public func data(forKey defaultName: String) -> Data? {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? Data {
return defaultName
}

return UserDefaults.standard.data(forKey: defaultName)
}
override func integer(forKey defaultName: String) -> Int {
return super.integer(forKey: defaultName)
override public func integer(forKey defaultName: String) -> Int {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? Int {
return defaultName
}

return UserDefaults.standard.integer(forKey: defaultName)
}
override func float(forKey defaultName: String) -> Float {
return super.float(forKey: defaultName)
override public func float(forKey defaultName: String) -> Float {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? Float {
return defaultName
}

return UserDefaults.standard.float(forKey: defaultName)
}
override func double(forKey defaultName: String) -> Double {
return super.double(forKey: defaultName)
override public func double(forKey defaultName: String) -> Double {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? Double {
return defaultName
}

return UserDefaults.standard.double(forKey: defaultName)
}
override func bool(forKey defaultName: String) -> Bool {
return super.bool(forKey: defaultName)
override public func bool(forKey defaultName: String) -> Bool {
TCSLogWithMark()

if cachedPrefs.count != 0 {
TCSLogWithMark("got prefs")

}
else {
TCSLogWithMark("No prefs")
}
if let defaultName = cachedPrefs[defaultName] as? Bool {
return defaultName
}

return UserDefaults.standard.bool(forKey: defaultName)
}
override func url(forKey defaultName: String) -> URL? {
return super.url(forKey: defaultName)
override public func url(forKey defaultName: String) -> URL? {
TCSLogWithMark()

if let defaultName = cachedPrefs[defaultName] as? URL {
return defaultName
}

return UserDefaults.standard.url(forKey: defaultName)
}


Expand Down
5 changes: 5 additions & 0 deletions LicenseChecker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class LicenseChecker: NSObject {
let trialDays = 14

if UserDefaults.standard.value(forKey: "tts") == nil {
TCSLogErrorWithMark("setting trial date")
UserDefaults.standard.setValue(Date(), forKey: "tts")
}
let firstLaunchDate = UserDefaults.standard.value(forKey: "tts") as? Date
Expand All @@ -28,12 +29,16 @@ class LicenseChecker: NSObject {
if let firstLaunchDate = firstLaunchDate {
let secondsPassed = Date().timeIntervalSince(firstLaunchDate)
let trialDaysLeft=trialDays-(Int(secondsPassed)/(24*60*60));
TCSLogWithMark("trial days: \(secondsPassed)")

if secondsPassed<Double(24*60*60*trialDays) {
trialState = .trial(trialDaysLeft)
}

}
else {
TCSLogErrorWithMark("did not get first launch date")
}
let check = TCSLicenseCheck()
let status = check.checkLicenseStatus("com.twocanoes.xcreds", withExtension: "")

Expand Down
2 changes: 0 additions & 2 deletions Profile Manifest/com.twocanoes.xcreds.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<date>2022-09-01T15:08:44Z</date>
<key>pfm_subkeys</key>
<array>
<string></string>
<dict>
<key>pfm_default</key>
<string>Configures XCreds configuration preferences</string>
Expand Down Expand Up @@ -775,7 +774,6 @@ A profile can consist of payloads with different version numbers. For example, c
<key>pfm_type</key>
<string>string</string>
</dict>

</array>
<key>pfm_targets</key>
<array>
Expand Down
3 changes: 2 additions & 1 deletion XCreds/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
return true
}
@objc func screenLocked(_ sender:Any) {
if UserDefaults.standard.bool(forKey: PrefKeys.shouldSwitchToLoginWindowWhenLocked.rawValue)==true{
TCSLogWithMark()
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.shouldSwitchToLoginWindowWhenLocked.rawValue)==true{
TCSLoginWindowUtilities().switchToLoginWindow(self)
}
}
Expand Down
2 changes: 1 addition & 1 deletion XCreds/ChangePasswordMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ChangePasswordMenuItem: NSMenuItem {
}

@objc func doAction() {
if let passwordChangeURLString = UserDefaults.standard.value(forKey: PrefKeys.passwordChangeURL.rawValue) as? String, passwordChangeURLString.count>0, let url = URL(string: passwordChangeURLString) {
if let passwordChangeURLString = DefaultsOverride.standardOverride.value(forKey: PrefKeys.passwordChangeURL.rawValue) as? String, passwordChangeURLString.count>0, let url = URL(string: passwordChangeURLString) {


NSWorkspace.shared.open(url)
Expand Down
2 changes: 1 addition & 1 deletion XCreds/CheckTokenMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CheckTokenMenuItem: NSMenuItem {

override var isHidden: Bool {
get {
if let _ = UserDefaults.standard.object(forKey: PrefKeys.accessToken.rawValue) as? String {
if let _ = DefaultsOverride.standardOverride.object(forKey: PrefKeys.accessToken.rawValue) as? String {
return false
} else {
return true
Expand Down
3 changes: 2 additions & 1 deletion XCreds/DefaultsHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Cocoa

class DefaultsHelper: NSObject {
static func backgroundImage(includeDefault:Bool=true) -> NSImage? {
if let imagePathURL = DefaultsOverride.standard.string(forKey: PrefKeys.loginWindowBackgroundImageURL.rawValue), let image = NSImage.imageFromPathOrURL(pathURLString: imagePathURL){
TCSLogWithMark()
if let imagePathURL = DefaultsOverride.standardOverride.string(forKey: PrefKeys.loginWindowBackgroundImageURL.rawValue), let image = NSImage.imageFromPathOrURL(pathURLString: imagePathURL){

return image

Expand Down
7 changes: 3 additions & 4 deletions XCreds/LoginPasswordWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class LoginPasswordWindowController: NSWindowController {

override func windowDidLoad() {
super.windowDidLoad()

if DefaultsOverride.standard.string(forKey: PrefKeys.localAdminUserName.rawValue) != nil &&
DefaultsOverride.standard.string(forKey: PrefKeys.localAdminPassword.rawValue) != nil
TCSLogWithMark()
if DefaultsOverride.standardOverride.string(forKey: PrefKeys.localAdminUserName.rawValue) != nil &&
DefaultsOverride.standardOverride.string(forKey: PrefKeys.localAdminPassword.rawValue) != nil
{
resetButton.isHidden=false
}
Expand Down Expand Up @@ -50,7 +50,6 @@ class LoginPasswordWindowController: NSWindowController {
@IBAction func cancelButtonPressed(_ sender: Any) {
if self.window?.isModalPanel==true {
NSApp.stopModal(withCode: .cancel)
self.window?.close()
}
}
}
15 changes: 10 additions & 5 deletions XCreds/MainController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ class MainController: NSObject {
if let defaultsPath = defaultsPath {

let defaultsDict = NSDictionary(contentsOfFile: defaultsPath)
UserDefaults.standard.register(defaults: defaultsDict as! [String : Any])
TCSLogWithMark()
DefaultsOverride.standardOverride.register(defaults: defaultsDict as! [String : Any])
}


Expand Down Expand Up @@ -52,7 +53,7 @@ class MainController: NSObject {
let localPassword = self.localPassword()
if (localPassword != tokens.password){
var updatePassword = true
if UserDefaults.standard.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
if DefaultsOverride.standardOverride.bool(forKey: PrefKeys.verifyPassword.rawValue)==true {
let verifyOIDPassword = VerifyOIDCPasswordWindowController.init(windowNibName: NSNib.Name("VerifyOIDCPassword"))
NSApp.activate(ignoringOtherApps: true)

Expand Down Expand Up @@ -122,23 +123,27 @@ class MainController: NSObject {
return password
}
}
TCSLogWithMark()
let passwordWindowController = LoginPasswordWindowController.init(windowNibName: NSNib.Name("LoginPasswordWindowController"))


TCSLogWithMark()
while (true){

TCSLogWithMark()
NSApp.activate(ignoringOtherApps: true)
let timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { timer in
NSApp.activate(ignoringOtherApps: true)

}

TCSLogWithMark()
let response = NSApp.runModal(for: passwordWindowController.window!)

timer.invalidate()
if response == .cancel {
break
}
if passwordWindowController.resetKeychain==true {
return nil
}
let localPassword = passwordWindowController.password
guard let localPassword = localPassword else {
continue
Expand Down

0 comments on commit 6717b3a

Please sign in to comment.