Home Programmierung Using Windows Powershell to request Credentials for use in the LISP REPL

Main Menu

Home
Veröffentlichungen
Texte / Essays
Programmierung
------------------
Kontakt
Impressum
Datenschutz
------------------
Using Windows Powershell to request Credentials for use in the LISP REPL

Using Windows Powershell to request Credentials for use in the LISP REPL

 

When doing Systems Analysis and Systems Testing, I often use the Lisp Repl and some smaller Lisp Utilities I wrote. Sometimes I connect to Databases or other systems which also requires entering Credentials. Saving Username / Password Information to files is not an option.

I use the REPL of Clozure Common Lisp in EMACS with Slime on Windows.

However, my Lisp prompt function to request Username and Password Information does not hide the information I type in. Entering my Password, which sometimes is my ActiveDirectory Password, would be visible on the screen to anyone looking at my screen at that moment.

I assume that there is a way to interface with EMACS and Slime to enter a Password which is not displayed.

But having played around with the Windows Powershell, why not use a built-in OS-Function to request Credentials from the User?

 

 

Starting the Powershell with

powershell get-credentials

opens up this Dialogue (German System Language for Windows):

 

I could use “ccl:run-program” to start this Powershell function. But I need a way to return the entered Information to my Lisp Process.

I found this way to do it within the powershell.

First I start the powershell.exe, then I tried these commands:

$credential = Get-Credential

$credential.username

$credential.getnetworkcredential().password.tostring()

The first command opens the Dialogue Box and stores the value in the variable $credential; the second one prints the Username Part, including a leading “\” and the third decodes the password and prints it in plaintext.

 

 

How can I return this information to my Lisp Repl? I will need to return the output of the powershell command, so I need a stream and convert it to a string.

A first try:

CL-USER> (with-output-to-string (stream)

(ccl:run-program "powershell.exe"

'("$credential = Get-Credential; $credential.username; $credential.getnetworkcredential().password.tostring()")

:output stream :external-format :windows))

-->

"\\username

password

"

CL-USER>

 

To get the two elements, we need to split the string using New Line as separator:

 

CL-USER> (cl-ppcre:split "\\n"  (with-output-to-string (stream)

(ccl:run-program "powershell.exe"

'("$credential = Get-Credential; $credential.username; $credential.getnetworkcredential().password.tostring()")

:output stream :external-format :windows)))

-->

("\\username" "pwd")

 

Almost perfect, but I need to remove the leading “\” from the Username String which is handled by “string-left-trim”.  Here is another Version of the Function:

(defun get-credentials-via-powershell ()

"Ask for Username, Password via  Windows Dialogue & return these in plaintext. Starting the powershell process sometimes takes a few seconds."

(let* ( ( resultlist (cl-ppcre:split "\\n"  (with-output-to-string (stream)

(ccl:run-program "powershell.exe"

'("$credential = Get-Credential; $credential.username; $credential.getnetworkcredential().password.tostring()")

:output stream :external-format :windows))))

; remove the \ from the username string

(username-sanitized (string-left-trim "\\" (first resultlist))))

(list username-sanitized (second resultlist))))

 

What happens, if the user presses ESC instead of entering credentials in the Windows Dialogue? Then the error string is returned, a list of strings too. But the first character of the first String Element in the error text is probably not a “\”. We can use this criterion as a simple form of error checking:

(string-equal "\\" (subseq  "\\abc" 0 1)) --> True

 

Now we have:


(defun get-credentials-via-powershell ()
"Ask for Username, Password via  Windows Dialogue & return these in plaintext. Starting the powershell process sometimes takes a few seconds."
(let* ( ( resultlist (cl-ppcre:split "\\n"  (with-output-to-string (stream)
(ccl:run-program "powershell.exe"
'("$credential = Get-Credential; $credential.username; $credential.getnetworkcredential().password.tostring()")
:output stream :external-format :windows))))
; remove the \ from the username string
(username-sanitized (string-left-trim "\\" (first resultlist))))
(if (string-equal "\\" (subseq (first resultlist) 0 1))
(list username-sanitized (second resultlist))
(warn "Incomplete password"))))



…which is nice: when I want to quit the password entering process, I just press escape, and NIL is returned, together with a warning:

 

 

Using “run-program” together with the high-level Scripting Interface of the PowerShell allows some form of integration with the OS and can be very practical.