...
 
Commits (12)
opt_in_rules:
- sorted_first_last
- strict_fileprivate
- trailing_closure
- yoda_condition
disabled_rules:
- line_length
- large_tuple
- identifier_name
# Overriding existing rules
file_length:
ignore_comment_only_lines: true
trailing_whitespace:
ignores_empty_lines: true
# paths to ignore during linting.
excluded:
- Pods
- Tests
- Carthage
......@@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */
01260458223ED15300523109 /* ADUserRecordTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01260457223ED15300523109 /* ADUserRecordTests.swift */; };
1A10FCC71FAEA7B300D30727 /* NoMAD_ADAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A10FCBD1FAEA7B300D30727 /* NoMAD_ADAuth.framework */; };
1A10FCCC1FAEA7B300D30727 /* NoMAD_ADAuthTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A10FCCB1FAEA7B300D30727 /* NoMAD_ADAuthTests.swift */; };
1A10FCCC1FAEA7B300D30727 /* NoMADADAuthTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A10FCCB1FAEA7B300D30727 /* NoMADADAuthTests.swift */; };
1A10FCCE1FAEA7B300D30727 /* NoMAD_ADAuth.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A10FCC01FAEA7B300D30727 /* NoMAD_ADAuth.h */; settings = {ATTRIBUTES = (Public, ); }; };
1AB3EEED1FB6887C002D5F99 /* ADLDAPPing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB3EEEC1FB6887C002D5F99 /* ADLDAPPing.swift */; };
1AB3EEF31FB688A6002D5F99 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB3EEF01FB688A6002D5F99 /* Extensions.swift */; };
......@@ -45,12 +45,13 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0110477822418C8F00E3F355 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .swiftlint.yml; sourceTree = "<group>"; };
01260457223ED15300523109 /* ADUserRecordTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ADUserRecordTests.swift; sourceTree = "<group>"; };
1A10FCBD1FAEA7B300D30727 /* NoMAD_ADAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NoMAD_ADAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1A10FCC01FAEA7B300D30727 /* NoMAD_ADAuth.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NoMAD_ADAuth.h; sourceTree = "<group>"; };
1A10FCC11FAEA7B300D30727 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1A10FCC61FAEA7B300D30727 /* NoMAD-ADAuthTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "NoMAD-ADAuthTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
1A10FCCB1FAEA7B300D30727 /* NoMAD_ADAuthTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoMAD_ADAuthTests.swift; sourceTree = "<group>"; };
1A10FCCB1FAEA7B300D30727 /* NoMADADAuthTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoMADADAuthTests.swift; sourceTree = "<group>"; };
1A10FCCD1FAEA7B300D30727 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1AB3EEEC1FB6887C002D5F99 /* ADLDAPPing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ADLDAPPing.swift; sourceTree = "<group>"; };
1AB3EEF01FB688A6002D5F99 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
......@@ -106,6 +107,7 @@
isa = PBXGroup;
children = (
1AB3EF0A1FB689A2002D5F99 /* README.md */,
0110477822418C8F00E3F355 /* .swiftlint.yml */,
1A10FCBF1FAEA7B300D30727 /* NoMAD-ADAuth */,
1A10FCCA1FAEA7B300D30727 /* NoMAD-ADAuthTests */,
1A10FCBE1FAEA7B300D30727 /* Products */,
......@@ -144,7 +146,7 @@
children = (
01260457223ED15300523109 /* ADUserRecordTests.swift */,
9C00CCFD1FD5B8E900B5B36A /* SessionManagerTests.swift */,
1A10FCCB1FAEA7B300D30727 /* NoMAD_ADAuthTests.swift */,
1A10FCCB1FAEA7B300D30727 /* NoMADADAuthTests.swift */,
1AB3EF621FB698CC002D5F99 /* ADUserFunctionTests.swift */,
1A10FCCD1FAEA7B300D30727 /* Info.plist */,
);
......@@ -238,6 +240,7 @@
1A10FCB91FAEA7B300D30727 /* Frameworks */,
1A10FCBA1FAEA7B300D30727 /* Headers */,
1A10FCBB1FAEA7B300D30727 /* Resources */,
0110477A22418CAF00E3F355 /* ShellScript */,
);
buildRules = (
);
......@@ -278,12 +281,12 @@
TargetAttributes = {
1A10FCBC1FAEA7B300D30727 = {
CreatedOnToolsVersion = 9.1;
LastSwiftMigration = 1000;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
};
1A10FCC51FAEA7B300D30727 = {
CreatedOnToolsVersion = 9.1;
LastSwiftMigration = 1000;
LastSwiftMigration = 1100;
ProvisioningStyle = Automatic;
};
};
......@@ -323,6 +326,26 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0110477A22418CAF00E3F355 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "#if which swiftlint >/dev/null; then\n#swiftlint\n#else\n#echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\n#fi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1A10FCB81FAEA7B300D30727 /* Sources */ = {
isa = PBXSourcesBuildPhase;
......@@ -346,7 +369,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1A10FCCC1FAEA7B300D30727 /* NoMAD_ADAuthTests.swift in Sources */,
1A10FCCC1FAEA7B300D30727 /* NoMADADAuthTests.swift in Sources */,
9C00CCFE1FD5B8E900B5B36A /* SessionManagerTests.swift in Sources */,
1AB3EF631FB698CC002D5F99 /* ADUserFunctionTests.swift in Sources */,
01260458223ED15300523109 /* ADUserRecordTests.swift in Sources */,
......@@ -508,13 +531,14 @@
"$(SDKROOT)/usr/lib/system",
);
MACOSX_DEPLOYMENT_TARGET = 10.10;
MARKETING_VERSION = 1.0.3;
MODULEMAP_PRIVATE_FILE = "";
PRODUCT_BUNDLE_IDENTIFIER = "menu.nomad.NoMAD-ADAuth";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/NOMAD-ADAuth/**";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
......@@ -540,12 +564,13 @@
"$(SDKROOT)/usr/lib/system",
);
MACOSX_DEPLOYMENT_TARGET = 10.10;
MARKETING_VERSION = 1.0.3;
MODULEMAP_PRIVATE_FILE = "";
PRODUCT_BUNDLE_IDENTIFIER = "menu.nomad.NoMAD-ADAuth";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = NO;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/NOMAD-ADAuth/**";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Release;
};
......@@ -561,7 +586,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "menu.nomad.NoMAD-ADAuthTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
......@@ -577,7 +602,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "menu.nomad.NoMAD-ADAuthTests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Release;
};
......
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
LastUpgradeVersion = "1100"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
......@@ -26,10 +26,9 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
<CodeCoverageTargets>
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1A10FCBC1FAEA7B300D30727"
......@@ -37,7 +36,7 @@
BlueprintName = "NoMAD-ADAuth"
ReferencedContainer = "container:NoMAD-ADAuth.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
......@@ -57,17 +56,6 @@
</SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1A10FCBC1FAEA7B300D30727"
BuildableName = "NoMAD_ADAuth.framework"
BlueprintName = "NoMAD-ADAuth"
ReferencedContainer = "container:NoMAD-ADAuth.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
......@@ -88,8 +76,6 @@
ReferencedContainer = "container:NoMAD-ADAuth.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
......
......@@ -8,7 +8,7 @@
import Foundation
struct DS_FLAGS : OptionSet {
struct DS_FLAGS: OptionSet {
let rawValue: UInt32
init(rawValue value: UInt32) {
rawValue = value
......@@ -92,9 +92,9 @@ class ADLDAPPing {
cursor += 1
// we would appear to have a pointer, let's remember it
var ptr: UInt16 = 0
let d: [UInt8] = [byte, (tag & ~marker)]
let data: [UInt8] = [byte, (tag & ~marker)]
// ptr += UnsafePointer<UInt16>(d).pointee
ptr += UnsafePointer(d).withMemoryRebound(to: UInt16.self,
ptr += UnsafePointer(data).withMemoryRebound(to: UInt16.self,
capacity: 1) {
$0.pointee
}
......@@ -110,10 +110,10 @@ class ADLDAPPing {
throw DecodeError.illegalTag
} else {
// read 'tag'-many bytes
var s: [UInt8] = [UInt8](repeating: 0, count: Int(tag))
(buffer as NSData).getBytes(&s, range: NSRange(location: Int(cursor), length: Int(tag)))
var stringBytes: [UInt8] = [UInt8](repeating: 0, count: Int(tag))
(buffer as NSData).getBytes(&stringBytes, range: NSRange(location: Int(cursor), length: Int(tag)))
cursor += UInt16(tag)
result.append(NSString(bytes: s, length: Int(tag), encoding: String.Encoding.utf8.rawValue)! as String)
result.append(NSString(bytes: stringBytes, length: Int(tag), encoding: String.Encoding.utf8.rawValue)! as String)
}
}
let final = result.joined(separator: ".")
......@@ -142,13 +142,12 @@ class ADLDAPPing {
myLogger.logit(.debug, message: "Is Writable: " + flags.contains(.DS_WRITABLE_FLAG).description)
myLogger.logit(.debug, message: "Is Closest: " + flags.contains(.DS_CLOSEST_FLAG).description)
// END
domainGUID = ADLDAPPing.decodeGUID(netlogonData, start: 8)
// Get forest
do {
(forest, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(forest, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -162,7 +161,7 @@ class ADLDAPPing {
}
// Get domain
do {
(domain, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(domain, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -176,7 +175,7 @@ class ADLDAPPing {
}
// Get hostname
do {
(hostname, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(hostname, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -190,7 +189,7 @@ class ADLDAPPing {
}
// Get netbiosDomain
do {
(netbiosDomain, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(netbiosDomain, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -204,7 +203,7 @@ class ADLDAPPing {
}
// Get netbiosHostname
do {
(netbiosHostname, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(netbiosHostname, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -218,7 +217,7 @@ class ADLDAPPing {
}
// Get user
do {
(user, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(user, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -232,7 +231,7 @@ class ADLDAPPing {
}
// Get the site the DC is in.
do {
(serverSite, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(serverSite, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -246,7 +245,7 @@ class ADLDAPPing {
}
// Get the site the client is in.
do {
(clientSite, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen:nil)
(clientSite, cursor) = try ADLDAPPing.decodeRFC1035(netlogonData, start: cursor, seen: nil)
} catch let error {
switch error {
case DecodeError.cyclicPointer:
......@@ -259,5 +258,5 @@ class ADLDAPPing {
return nil
}
}
}
......@@ -9,11 +9,11 @@
import Foundation
extension String {
func trimWhitespace() -> String {
func trimmingWhitespace() -> String {
return self.trimmingCharacters(in: CharacterSet.whitespaces)
}
/*
// TODO: move this to UserInfo
......@@ -40,7 +40,7 @@ extension String {
}
*/
}
extension TimeInterval {
......
......@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
......
......@@ -29,84 +29,81 @@ public struct Ticket {
public let klistUtil = KlistUtil()
public class KlistUtil {
var dateFormatter = DateFormatter()
public var tickets = [String:Ticket]()
// var tempDict = [String:Ticket]()
let dateFormatter = DateFormatter()
public lazy var tickets = [String: Ticket]()
public var defaultPrincipal: String?
public var defaultExpires: Date?
init() {
dateFormatter.dateFormat = "yyyyMMddHHmmss"
}
public func returnTickets() -> [Ticket] {
// update the tickets
klist()
var results = [Ticket]()
for ticket in tickets {
results.append(ticket.value)
}
return results
}
// convenience function to return all principals
public func returnPrincipals() -> [String] {
klist()
return tickets.keys.sorted()
}
// convenience function to return default principal
public func returnDefaultPrincipal() -> String {
return defaultPrincipal ?? "No Ticket"
}
public func returnDefaultExpiration() -> Date? {
return defaultExpires
}
public func klist() {
let sema = DispatchSemaphore(value: 0)
// clear the current cached tickets
tickets.removeAll()
defaultPrincipal = nil
defaultExpires = nil
// use krb5 API to get default tickets and all tickets, including expired ones
var context: krb5_context? = nil
var context: krb5_context?
krb5_init_secure_context(&context)
var oCache : krb5_ccache? = nil
var oCache: krb5_ccache?
_ = UnsafeMutablePointer<Any>.init(oCache)
let cname = krb5_cc_default_name(context)
let defaultName = String(cString: cname!).replacingOccurrences(of: "API:", with: "")
var cursor: krb5_cccol_cursor? = nil
var ret: krb5_error_code? = nil
var min_stat = OM_uint32()
var cursor: krb5_cccol_cursor?
var ret: krb5_error_code?
var minStat = OM_uint32()
ret = krb5_cccol_cursor_new(context, &cursor)
while ((krb5_cccol_cursor_next(context, cursor, &oCache) == 0 ) && oCache != nil) {
while ((krb5_cccol_cursor_next(context, cursor, &oCache) == 0 ) && oCache != nil) {
let name = (String(cString: (krb5_cc_get_name(context, oCache))))
var princ : krb5_principal? = nil
var princ: krb5_principal?
ret = krb5_cc_get_principal(context, oCache, &princ)
//print(princ.debugDescription)
var princName : UnsafeMutablePointer<Int8>? = nil
var princName: UnsafeMutablePointer<Int8>?
krb5_unparse_name(context, princ!, &princName)
let princNameString = String(cString: princName!)
tickets[princNameString] = Ticket(expired: true, expires: Date.distantPast, defaultCache: false, principal: princNameString, krb5Cache: oCache, GSSItem: nil)
......@@ -117,15 +114,15 @@ public class KlistUtil {
tickets[princNameString]?.defaultCache = true
}
}
// now move to GSS APIs to get expiration times
// TODO: move this all to GSS APIs when the GSS API functionality is there
gss_iter_creds(&min_stat, 0, nil, { a, cred in
gss_iter_creds(&minStat, 0, nil, { _, cred in
_ = OM_uint32()
_ = gss_buffer_desc()
if cred != nil {
let name = GSSCredentialCopyName(cred!)
if name != nil {
......@@ -150,13 +147,13 @@ public class KlistUtil {
})
sema.wait()
//return tickets
// clean up any expired tickets
let ticks = tickets
tickets.removeAll()
for tick in ticks {
if !tick.value.expired {
// ticket is not expired add it back
......@@ -165,52 +162,52 @@ public class KlistUtil {
}
//print(tickets)
}
// function to delete a kerb ticket
public func kdestroy(princ: String = "" ) {
var name = ""
if princ == "" {
name = defaultPrincipal!
} else {
name = princ
}
myLogger.logit(.debug, message: "Destroying ticket for: " + princ)
// update this for GSSAPI when the functionality is there
var context: krb5_context? = nil
var context: krb5_context?
krb5_init_secure_context(&context)
krb5_cc_destroy(context, tickets[name]?.krb5Cache)
}
// function to switch the default cache
public func kswitch(princ: String = "" ) {
var name = ""
var p : krb5_principal? = nil
var cache: krb5_ccache? = nil
var kerbPrinc: krb5_principal?
var cache: krb5_ccache?
if princ == "" {
name = defaultPrincipal!
} else {
name = princ
}
var nameInt = Int8(name)
myLogger.logit(.debug, message: "Switching ticket for: " + princ)
// update this for GSSAPI when the functionality is there
var context: krb5_context? = nil
var context: krb5_context?
krb5_init_secure_context(&context)
krb5_parse_name(context!, &nameInt!, &p)
krb5_cc_cache_match(context, p, &cache)
krb5_parse_name(context!, &nameInt!, &kerbPrinc)
krb5_cc_cache_match(context, kerbPrinc, &cache)
// krb5_cc_set_default_name
}
}
......@@ -20,16 +20,16 @@ import os.log
/// - notice: Nice to know issues that may, or may not, cause issues
/// - debug: Lots of verbose logging
enum LogLevel: Int {
/// General errors
case base = 0
/// Positive info
case info = 1
/// Nice to know issues that may, or may not, cause issues
case notice = 2
/// Lots of verbose logging
case debug = 3
}
......@@ -42,19 +42,17 @@ var log: OSLog? {
}
}
/// Simple class to handle logging levels. Use the `LogLevel` enum to specify the logging details.
class Logger {
/// Set to a level from `LogLevel` enum to control what gets logged.
var loglevel: LogLevel
/// Init method simply check to see if Verbose logging is enabled or not for the Logger object.
init() {
let defaults = UserDefaults.init(suiteName: "menu.nomad.login.ad")
if defaults?.bool(forKey: "Verbose") ?? false {
NSLog("Enaging verbose logging")
loglevel = .debug
......@@ -62,7 +60,7 @@ class Logger {
loglevel = .base
}
}
/// Simple wrapper around NSLog to provide control of logging.
///
/// - Parameters:
......@@ -71,7 +69,7 @@ class Logger {
func logit(_ level: LogLevel, message: String) {
if (level.rawValue <= loglevel.rawValue) {
if #available(OSX 10.12, *) {
os_log("%{public}@", log: log!, type: .debug)
os_log("%{public}@", log: log!, type: .debug, message)
} else {
NSLog("level: \(level) - " + message)
}
......
This diff is collapsed.
......@@ -27,120 +27,120 @@ public class SessionManager: NoMADUserSessionDelegate {
/// The default instance of `SessionManager` to be used.
public static let shared = SessionManager()
public var sessions = [String : NoMADSessionUserObject]()
public var sessions = [String: NoMADSessionUserObject]()
let dateFormatter = DateFormatter()
let myWorkQueue = DispatchQueue(label: "menu.nomad.NoMADADAuth.sessionmanager.background_work_queue", attributes: [])
init() {
// a bit more setup
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .short
// get all of the current principals with tickets
self.getList()
}
// udpate the list
public func update(user : String) {
public func update(user: String) {
if sessions[user] == nil {
// We don't know about this user yet
return
}
sessions[user]?.session.delegate = self
sessions[user]?.session.getUserInformation()
}
// updates all known users
public func updateAll() {
if sessions.count < 1 {
// no sessions so return
return
}
for session in sessions {
session.value.session.delegate = self
session.value.session.getUserInformation()
}
}
// gets new list of users
public func getList() {
klistUtil.klist()
let principals = klistUtil.returnPrincipals()
if principals.count > 0 {
for user in principals {
if sessions[user] == nil {
// add the account
let userSession = NoMADSession.init(domain: user.components(separatedBy: "@").last?.lowercased() ?? "", user: user, type: .AD)
myWorkQueue.async {
userSession.delegate = self
userSession.userInfo()
}
sessions[user] = NoMADSessionUserObject.init(userPrincipal: user, session: userSession, aging: false, expiration: nil, daysToGo: nil, userInfo: nil)
}
}
}
}
// manually adds a user with a session
public func createEntry(user : String, session : NoMADSession, update: Bool=true) {
public func createEntry(user: String, session: NoMADSession, update: Bool=true) {
sessions[user] = NoMADSessionUserObject.init(userPrincipal: user, session: session, aging: false, expiration: nil, daysToGo: nil, userInfo: nil)
if update {
// update the information
session.delegate = self
session.getUserInformation()
}
}
// update a NoMADSessionUserObject object
public func updateUser(user : String) {
public func updateUser(user: String) {
}
// Add a new session to the list
// PRAGMA: Auth callbacks
public func NoMADAuthenticationSucceded() {
// we'll never auth here
}
public func NoMADAuthenticationFailed(error: NoMADSessionError, description: String) {
// we'll never auth here
}
public func NoMADUserInformation(user: ADUserRecord) {
// we shouldn't not already know about this user, but we'll double check
if sessions[user.userPrincipal] == nil {
return
}
if user.passwordExpire != nil && user.passwordAging! {
sessions[user.userPrincipal]?.daysToGo = Int((user.passwordExpire?.timeIntervalSince(Date()))!)/86400
sessions[user.userPrincipal]?.expiration = user.passwordExpire
......
......@@ -15,50 +15,50 @@ import NoMADPRIVATE
let siteManager = SiteManager()
var updatePending = false
var updateTimer: Timer? = nil
var updateTimer: Timer?
// simple class to use as a global site manager
class SiteManager {
// variables
var sites = [String:[NoMADLDAPServer]]()
var sites = [String: [NoMADLDAPServer]]()
// this seems silly to set a notification to notify internally to clearSites... but here goes
let changed: SCDynamicStoreCallBack = { dynamicStore, _, _ in
// TODO: throttle too many lookups too quickly
print("Network change")
let updateNotification = Notification(name: Notification.Name(rawValue: "menu.nomad.NoMAD-ADAuth.updateNow"))
NotificationQueue.default.enqueue(updateNotification, postingStyle: .now)
}
func checkNetwork() {
var dynamicContext = SCDynamicStoreContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let dcAddress = withUnsafeMutablePointer(to: &dynamicContext, {UnsafeMutablePointer<SCDynamicStoreContext>($0)})
if let dynamicStore = SCDynamicStoreCreate(kCFAllocatorDefault, "menu.nomad.NoMAD.networknotification" as CFString, changed, dcAddress) {
let keysArray = ["State:/Network/Global/IPv4" as CFString, "State:/Network/Global/IPv6"] as CFArray
SCDynamicStoreSetNotificationKeys(dynamicStore, nil, keysArray)
let loop = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynamicStore, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), loop, .defaultMode)
}
// register for notifications
NotificationCenter.default.addObserver(self, selector: #selector(clearSites), name: NSNotification.Name(rawValue: "menu.nomad.NoMAD-ADAuth.updateNow"), object: nil)
}
@objc func clearSites() {
// removes all sites
sites.removeAll()
}
// listen for network changes
}
......@@ -11,7 +11,6 @@ import Foundation
import SystemConfiguration
import IOKit
/// A simple wrapper around NSTask
///
/// - Parameters:
......@@ -23,7 +22,7 @@ public func cliTask(_ command: String, arguments: [String]? = nil, waitForTermin
var commandLaunchPath: String
var commandPieces: [String]
if arguments == nil {
// turn the command into an array and get the first element as the launch path
commandPieces = command.components(separatedBy: " ")
......@@ -31,13 +30,13 @@ public func cliTask(_ command: String, arguments: [String]? = nil, waitForTermin
if command.contains("\\") {
// we need to rebuild the string with the right components
var x = 0
var index = 0
for line in commandPieces {
if line.last == "\\" {
commandPieces[x] = commandPieces[x].replacingOccurrences(of: "\\", with: " ") + commandPieces.remove(at: x+1)
x -= 1
commandPieces[index] = commandPieces[index].replacingOccurrences(of: "\\", with: " ") + commandPieces.remove(at: index+1)
index -= 1
}
x += 1
index += 1
}
}
commandLaunchPath = commandPieces.remove(at: 0)
......@@ -100,14 +99,14 @@ public func cliTaskNoTerm(_ command: String) -> String {
if command.contains("\\") {
// we need to rebuild the string with the right components
var x = 0
var index = 0
for line in commandPieces {
if line.last == "\\" {
commandPieces[x] = commandPieces[x].replacingOccurrences(of: "\\", with: " ") + commandPieces.remove(at: x+1)
x -= 1
commandPieces[index] = commandPieces[index].replacingOccurrences(of: "\\", with: " ") + commandPieces.remove(at: index+1)
index -= 1
}
x += 1
index += 1
}
}
......@@ -158,17 +157,16 @@ public func getConsoleUser() -> String {
return userName
}
/// Finds the serial number of the Mac.
///
/// - Returns: The serial number of the Mac as a `String`.
public func getSerial() -> String {
let platformExpert: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"))
let platformSerialNumberKey = kIOPlatformSerialNumberKey
let serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, platformSerialNumberKey as CFString, kCFAllocatorDefault, 0)
let serialNumber = serialNumberAsCFString?.takeUnretainedValue() as! String
return serialNumber
guard let serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, platformSerialNumberKey as CFString, kCFAllocatorDefault, 0) else {
return ""
}
return String(describing: serialNumberAsCFString.takeUnretainedValue())
}
/// Finds the MAC address of the primary ethernet connection.
......@@ -205,7 +203,7 @@ private func which(_ command: String) -> String {
let data = whichPipe.fileHandleForReading.readDataToEndOfFile()
let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
if output == "" {
NSLog("Binary doesn't exist")
}
......
......@@ -20,7 +20,7 @@ public protocol BasicUserInfo {
}
public struct ADUserRecord: BasicUserInfo, Equatable {
public let type: LDAPType = .AD
public var userPrincipal: String
public var firstName: String
......@@ -39,8 +39,10 @@ public struct ADUserRecord: BasicUserInfo, Equatable {
public var updatedLast: Date
public var domain: String
public var cn: String
public var pso: String?
public var passwordLength: Int?
public var customAttributes: [String:Any]?
public static func ==(lhs: ADUserRecord, rhs: ADUserRecord) -> Bool {
return (lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName)
}
......
......@@ -11,36 +11,35 @@ import XCTest
import NoMADPRIVATE
@testable import NoMAD_ADAuth
class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
class ADUserFunctionTests: XCTestCase, NoMADUserSessionDelegate {
func NoMADAuthenticationFailed(error: NoMADSessionError, description: String) {
NSLog("%@", "Authentication failed called.")
}
// some setup
let session = NoMADSession.init(domain: "nomad.test", user: "ftest@NOMAD.TEST", type: .AD)
let session2 = NoMADSession.init(domain: "nomad.test", user: "ftest2@NOMAD.TEST", type: .AD)
// kill any existing tickets
let result = cliTask("kdestroy -a")
var expectation: XCTestExpectation?
override func setUp() {
super.setUp()
}
func testAuth() {
session.userPass = "NoMADRocks1!"
expectation = self.expectation(description: "Auth Succeeded")
session.delegate = self
session.authenticate()
self.waitForExpectations(timeout: 10, handler: nil)
}
func testAuthAgain() {
// this should not need to lookup sites
session.userPass = "NoMADRocks1!"
......@@ -50,7 +49,7 @@ class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
self.waitForExpectations(timeout: 10, handler: nil)
session.userInfo()
}
func testAuthFail() {
// this should fail
session.userPass = "NotthePassword!"
......@@ -62,10 +61,10 @@ class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
func testUserLookup() {
session.userInfo()
print(session.userRecord)
print(session.userRecord?.computedExireDate)
print(session.userRecord as Any)
print(session.userRecord?.computedExireDate as Any)
}
func testSecondAuth() {
session2.userPass = "NoMAD21!"
expectation = self.expectation(description: "Auth Succeeded")
......@@ -74,15 +73,15 @@ class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
self.waitForExpectations(timeout: 10, handler: nil)
session2.userInfo()
}
func testTicketList() {
print(klistUtil.klist())
}
// MARK: Delegate
func NoMADAuthenticationSucceded() {
if expectation?.description == "Auth Succeeded" {
print("Auth Succeeded")
expectation?.fulfill()
......@@ -91,7 +90,7 @@ class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
}
}
func NoMADAuthenticationFailed(error: Error, description: String) {
if expectation?.description == "Auth Failed" {
print("Auth Failed")
......@@ -100,7 +99,7 @@ class ADUserFunctionTests : XCTestCase, NoMADUserSessionDelegate {
XCTFail()
}
}
func NoMADUserInformation(user: ADUserRecord) {
print("***User Record for: \(user.fullName)***")
print(user)
......
......@@ -42,4 +42,3 @@ class ADUserRecordTests: XCTestCase {
}
}
......@@ -9,28 +9,28 @@
import XCTest
@testable import NoMAD_ADAuth
class NoMAD_ADAuthTests: XCTestCase {
class NoMADADAuthTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}
......@@ -15,7 +15,7 @@ class SessionManagerTests: XCTestCase {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
......@@ -30,7 +30,7 @@ class SessionManagerTests: XCTestCase {
func testSharedInitPerf() {
// This is an example of a performance test case.
self.measure {
let _ = SessionManager.shared
_ = SessionManager.shared
}
}
......
This diff is collapsed.