%\VignetteIndexEntry{Guide to the getPass Package} \documentclass[]{article} \input{./include/settings} \mytitle{Guide to the getPass Package} \mysubtitle{} \myversion{0.2-1} \myauthor{ \centering Drew Schmidt \\ \texttt{wrathematics@gmail.com} } \begin{document} \makefirstfew \section{Introduction}\label{introduction} \textbf{getPass}~\cite{getPassPackage} is an R package for reading user input in R with masking. There is one exported function, \texttt{getPass()}, which will behave as R's \texttt{readline()} but with masked input. You can pass a message to the password input via the \texttt{msg} argument, similar to the \texttt{prompt} argument in \texttt{readline()}. \subsection{Installation} You can install the stable version from CRAN using the usual \texttt{install.packages()}: \begin{lstlisting}[language=rr] install.packages("getPass") \end{lstlisting} The development version is maintained on GitHub. You can install this version using any of the well-known installer packages available to R: \begin{lstlisting}[language=rr] ### Pick your preference devtools::install_github("wrathematics/getPass") ghit::install_github("wrathematics/getPass") remotes::install_github("wrathematics/getPass") \end{lstlisting} \section{Password Reading}\label{password-reading} Using the package should mostly amount to calling \code{getPass::getPass()}. Currently there are two arguments to \texttt{getPass()}. By setting the \texttt{msg} parameter, you can change what is printed in the password dialogue box: \begin{lstlisting}[language=rr] getPass() ## PASSWORD: **** ## [1] "asdf" getPass(msg="") ## **** ## [1] "asdf" getPass(msg="shh, it's a secret! ") ## shh, it's a secret! **** ## [1] "asdf" \end{lstlisting} Finally, there is the \texttt{forcemask} flag, which indicates if reading without masking should be possible. By default, if one is running under an environment that does not allow reading with masking, then a warning message will be printed, and R's ordinary \texttt{readline()} will be used. However, if this flag is set to \texttt{TRUE}, then the function will stop with an error. \subsection{Interfaces} The form that password input takes will vary based on how you interface to R (with implementation details below). If you use \textbf{RStudio}, it will look something like this: \begin{center} \includegraphics{./pics/rstudio.png} \end{center} If you use \textbf{RGui} on Windows or \textbf{R.app} (if \textbf{tcltk} is supported; see Section~\ref{implementation-details} below), it will look like: \begin{center} \includegraphics{./pics/tcltk.png} \end{center} Finally, if you use the terminal (any OS), it will look like: \begin{center} \includegraphics{./pics/cli.png} \end{center} We believe this covers pretty much everyone. One notable exclusion is emacs in an environment without \textbf{tcltk}. Due to how it handles buffers, I believe it \emph{can't} be supported. If that is incorrect, please let us know! \section{Password Hashing}\label{password-hashing} \subsection{The Short Version} After reading in a password that you intend to store (or in some way ``pass around''), always hash it using a cryptographic hashing function. Some options for hashing with R include: \begin{itemize} \item \textbf{argon2} \url{https://cran.r-project.org/package=argon2}~\cite{argon2} \item \textbf{sodium} \url{https://cran.r-project.org/package=sodium}~\cite{sodium} \item \textbf{bcrypt} \url{https://cran.r-project.org/package=bcrypt}~\cite{bcrypt} \item \textbf{openssl} \url{https://cran.r-project.org/package=openssl}~\cite{openssl} \end{itemize} \subsection{The Long(er) Version} In an effort to keep the package as minimal as possible, we do not include any methods for hashing passwords. However, the suggested package \textbf{argon2}~\cite{argon2} contains an implementation of the \textit{argon2()} secure password hashing function. Many experts (of which I am not one) have written at length about this topic; and it can quickly get kind of complicated and mathy. The basic idea is: don't store passwords as plaintext. We can use a secure hash function to hash the password, basically turning the input string into a new ``garbled'' string. Hash functions are hard to ``invert'', so you can know which hash function I used and know the output, and still (hopefully) not recover the original string. We can quickly handle this problem without having to think very hard. Say you used \textbf{getPass} to read a password into the variable \code{pass}: \begin{lstlisting}[language=rr] pass ## [1] "myPassw0rd!" \end{lstlisting} An excellent choice to be sure. This is the ``plaintext''. We can hash it with a call to the \textbf{argon2} packages's \code{pw_hash()} function: \begin{lstlisting}[language=rr] hash <- argon2::pw_hash(pass) hash ## [1] "$argon2i$v=19$m=8192,t=16,p=2$JeV26p9ZmnlFyHKUWCe/46E3q2dtaXzuHO6L4Qg15IEgkNrOawOI5TnxI+6yLFRmLUZG6R4GJK0BTAkZhKgItg$MdafxeYEstYyT3RWyj2DDDcBAhfi8dE30tn6L1/Xaaus5su5Xiq2fdnD2zCK39DXTUyGWsOTTTZzGxKw1O4mtg" attr(,"hashtype") [1] "argon2" \end{lstlisting} Now say you need to validate a password that's been entered against the hashed password. All you need to do is call \code{pw_check()}: \begin{lstlisting}[language=rr] argon2::pw_check(hash, pass) ## [1] TRUE argon2::pw_check(hash, "password") ## [1] FALSE argon2::pw_check(hash, "1234") ## [1] FALSE \end{lstlisting} So inside of a user-facing application, the process might look something like this: \begin{lstlisting}[language=rr] user_pw <- getPass::getPass() hash_pw <- argon2::pw_hash(user_pw) store_user_pw(hash_pw) # pseudocode, but you get the idea \end{lstlisting} There are good reasons to prefer \textbf{argon2}: it is lightweight (with no package or system dependencies) and it is believed to be very secure. However, there are other options available in R, including the \textbf{bcrypt}, \textbf{sodium}, and \textbf{openssl} packages. \section{Implementation Details}\label{implementation-details} \subsection{RStudio}\label{rstudio} To use this with RStudio, you need: \begin{itemize} \item RStudio desktop version \textgreater{}= 0.99.879. \item The rstudioapi package version \textgreater{}= 0.5. \end{itemize} In this case, the \texttt{getPass()} function wraps the \textbf{rstudioapi} function \texttt{askForPassword()}. \subsection{Command Line}\label{command-line} Here, the input reader is custom C code. It has been tested successfully on Windows (in the ``RTerm'' session), Mac (in the terminal, not R.app which will not work!), Linux, and FreeBSD. The maximum length for a password in this case is 255 characters. On Windows, the reader is just \texttt{\_getch()}. On 'nix environments (Mac, Linux, \ldots{}), masking is made possible via \texttt{tcsetattr()}. Special handling for each is provided for handling \texttt{ctrl+c} and backspace. If you discover a problem using this, please \href{https://github.com/wrathematics/getPass/issues}{file an issue report}. \subsection{RGui (Windows)}\label{rgui-windows} If you use RGui (the Windows R GUI), then this should use the \textbf{tcltk} package. I don't think it's actually possible for \textbf{tcltk} to be unavailable on Windows, so if you are an RGui user and have trouble with this, please \href{https://github.com/wrathematics/getPass/issues}{file an issue report}. \subsection{R.app (Mac)}\label{r.app-mac} You will need to install dependencies for the \textbf{tcltk} package. I'm not completely sure what this process involves for Macs; if you know, please let us know. If \textbf{tcltk} is unavailable, then it will use the ``unsupported'' method below. \subsection{Other/Unsupported Platforms}\label{otherunsupported-platforms} When a platform is unsupported, the function will optionally default to use R's \texttt{readline()} (without masking!) with a warning communicated to the user, or it can stop with an error. \section{Acknowledgements}\label{acknowledgements} We thank Kevin Ushey for his assistance in answering questions in regard to supporting RStudio. The development for this package was supported in part by the project \emph{Harnessing Scalable Libraries for Statistical Computing on Modern Architectures and Bringing Statistics to Large Scale Computing} funded by the National Science Foundation Division of Mathematical Sciences under Grant No. 1418195. \addcontentsline{toc}{section}{References} \bibliography{./include/getPass} \bibliographystyle{plain} \end{document}