From 12ca043333ded7411e6d5632590b0ad89fbb0c11 Mon Sep 17 00:00:00 2001 From: Logan Wright Date: Fri, 7 Apr 2017 16:00:30 +0200 Subject: [PATCH 1/2] add secure entry code --- Sources/Console/Console/Console.swift | 94 +++++++++++-------------- Sources/Console/Terminal/Terminal.swift | 14 +++- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/Sources/Console/Console/Console.swift b/Sources/Console/Console/Console.swift index 5261a500..2834a6a0 100644 --- a/Sources/Console/Console/Console.swift +++ b/Sources/Console/Console/Console.swift @@ -2,73 +2,61 @@ import libc import Foundation import Core -/** - Protocol for powering styled Console I/O. -*/ + +/// Protocol for powering styled Console I/O. public protocol ConsoleProtocol { - /** - Outputs a String in the given style to - the console. If newLine is true, the next - output will appear on a new line. - */ + /// Outputs a String in the given style to + /// the console. If newLine is true, the next + /// output will appear on a new line. func output(_ string: String, style: ConsoleStyle, newLine: Bool) - /** - Returns a String of input read from the - console until a line feed character was found. - - The line feed character should not be included. - */ + /// Returns a String of input read from the + /// console until a line feed character was found. + /// + /// The line feed character should not be included. func input() -> String - /** - Clears previously printed Console outputs - according to the ConsoleClear type given. - */ + /// Returns a string of input read from the console + /// until a line feed character was found, + /// hides entry for security + func secureInput() -> String + + /// Clears previously printed Console outputs + /// according to the ConsoleClear type given. func clear(_ clear: ConsoleClear) - /** - Executes a task using the supplied - FileHandles for IO. - */ + /// Executes a task using the supplied + /// FileHandles for IO. func execute(program: String, arguments: [String], input: Int32?, output: Int32?, error: Int32?) throws - /** - When set, all `confirm(_ prompt:)` methods - will return the value. When nil, the confirm - calls will wait for input from `input()` - */ + /// When set, all `confirm(_ prompt:)` methods + /// will return the value. When nil, the confirm + /// calls will wait for input from `input()` var confirmOverride: Bool? { get } - /** - The size of the console window used for centering. - */ + /// The size of the console window used for centering. var size: (width: Int, height: Int) { get } - /** - Executes a command using the console's POSIX subsystem. - The input, output, and error streams will appear - as though they are coming from the console program. - - - parameter program: Program to be executed - - parameter arguments: Input arguments to the program - - - throws: ConsoleError.execute(Int) - */ + /// Executes a command using the console's POSIX subsystem. + /// The input, output, and error streams will appear + /// as though they are coming from the console program. + /// + /// - parameter program: Program to be executed + /// - parameter arguments: Input arguments to the program + /// + /// - throws: ConsoleError.execute(Int) func foregroundExecute(program: String, arguments: [String]) throws - /** - Executes a command using the console's POSIX subsystem. - The input, output, and error streams will be input - and returned as strings. - - - parameter program: Program to be executed - - parameter arguments: Input arguments to the program - - - throws: ConsoleError.subexecute(Int, String) + /// Executes a command using the console's POSIX subsystem. + /// The input, output, and error streams will be input + /// and returned as strings. + /// + /// - parameter program: Program to be executed + /// - parameter arguments: Input arguments to the program - - returns: The return string from the method - */ + /// - throws: ConsoleError.subexecute(Int, String) + /// + /// - returns: The return string from the method func backgroundExecute(program: String, arguments: [String]) throws -> String /// Upon a console instance being killed for example w/ ctrl+c @@ -137,6 +125,10 @@ extension ConsoleProtocol { public func backgroundExecute(commands: String...) throws -> Type { return try backgroundExecute(commands: commands) } + + public func registerKillListener(_ listener: @escaping (Int32) -> Void) { + + } } extension ConsoleProtocol { diff --git a/Sources/Console/Terminal/Terminal.swift b/Sources/Console/Terminal/Terminal.swift index 517ceb1a..b05c89e8 100644 --- a/Sources/Console/Terminal/Terminal.swift +++ b/Sources/Console/Terminal/Terminal.swift @@ -71,13 +71,21 @@ public class Terminal: ConsoleProtocol { #endif } - /** - Reads a line of input from the terminal. - */ public func input() -> String { return readLine(strippingNewline: true) ?? "" } + public func secureInput() -> String { + // http://stackoverflow.com/a/30878869/2611971 + let entry: UnsafeMutablePointer = getpass("") + let pointer: UnsafePointer = .init(entry) + var pass = String(validatingUTF8: pointer) ?? "" + if pass.hasSuffix("\n") { + pass = pass.makeBytes().dropLast().makeString() + } + return pass + } + public func execute(program: String, arguments: [String], input: Int32? = nil, output: Int32? = nil, error: Int32? = nil) throws { var pid = UnsafeMutablePointer.allocate(capacity: 1) pid.initialize(to: pid_t()) From 711f5cf987312c0f72a74f90a71262494d6ea11c Mon Sep 17 00:00:00 2001 From: Logan Wright Date: Fri, 7 Apr 2017 16:23:15 +0200 Subject: [PATCH 2/2] allow secure ask --- Sources/Console/Console/Console+Ask.swift | 9 +++++++-- Tests/ConsoleTests/Utilities.swift | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Sources/Console/Console/Console+Ask.swift b/Sources/Console/Console/Console+Ask.swift index 073d2f16..86cf5921 100644 --- a/Sources/Console/Console/Console+Ask.swift +++ b/Sources/Console/Console/Console+Ask.swift @@ -3,12 +3,17 @@ extension ConsoleProtocol { Requests input from the console after displaying the desired prompt. */ - public func ask(_ prompt: String, style: ConsoleStyle = .info) -> String { + public func ask(_ prompt: String, style: ConsoleStyle = .info, secure: Bool = false) -> String { output(prompt, style: style) output("> ", style: style, newLine: false) - return input() + if secure { + return secureInput() + } else { + return input() + } } } + extension ConsoleProtocol { public func askList(withTitle title: String, from list: [String]) -> String? { info(title) diff --git a/Tests/ConsoleTests/Utilities.swift b/Tests/ConsoleTests/Utilities.swift index a80d60c1..4d356291 100644 --- a/Tests/ConsoleTests/Utilities.swift +++ b/Tests/ConsoleTests/Utilities.swift @@ -2,6 +2,7 @@ import XCTest import Console class TestConsole: ConsoleProtocol { + var inputBuffer: String = "" var outputBuffer: String = "" @@ -22,6 +23,11 @@ class TestConsole: ConsoleProtocol { return input } + func secureInput() -> String { + return input() + } + + func clear(_ clear: ConsoleClear) { // }