Way to securely give a password to R application from the terminal?

五迷三道 提交于 2019-11-27 03:56:32

The problem is that R does not have functions to control the terminal it is running in (something like Rncurses); probably this is due to portability issues.
Some time ago I was struggling with the same problem and I ended up with a function using TclTk:

getPass<-function(){  
  require(tcltk);  
  wnd<-tktoplevel();tclVar("")->passVar;  
  #Label  
  tkgrid(tklabel(wnd,text="Enter password:"));  
  #Password box  
  tkgrid(tkentry(wnd,textvariable=passVar,show="*")->passBox);  
  #Hitting return will also submit password  
  tkbind(passBox,"<Return>",function() tkdestroy(wnd));  
  #OK button  
  tkgrid(tkbutton(wnd,text="OK",command=function() tkdestroy(wnd)));  
  #Wait for user to click OK  
  tkwait.window(wnd);  
  password<-tclvalue(passVar);  
  return(password);  
}  

Of course it won't work in non-GUI environments.

Very simple linux concept for terminal secure password question:

   password <- function(prompt = "Password:"){
      cat(prompt)
      pass <- system('stty -echo && read ff && stty echo && echo $ff && ff=""',
                        intern=TRUE)
      cat('\n')
      invisible(pass)
   }        

My package keyringr solves this problem by retrieving passwords from the underlying operating system keyring (DPAPI on Windows, Keychain on OSX and the Gnome Keyring on Linux).

The vignette gives a detailed explanation on how to use the package, but if you were using OSX and have the password saved in Keychain, you could use the following command to return the password to R (where mydb_myuser is the Keychain item name):

install.packages("keyringr")
library("keyringr")
mypwd <- decrypt_kc_pw("mydb_myuser")
print(mypwd)

Per m-dz in the comments above, there is a now a package for doing this called getPass, which has a single function, getPass(). This is a replacement for base::readline().

Here is a login pop-up, based on ?modalDialog.

library("shiny")

shinyApp(
  ui <- basicPage(
    actionButton("login", "Login"),
    verbatimTextOutput("secrets")
  ),

  server <- function(input, output, session) {
    vals <- reactiveValues(authenticated=FALSE)

    passwordModal <- function(message=NULL) {
      modalDialog(
        textInput("username", "Username", input$username),
        passwordInput("password", "Password", input$password),

        if (!is.null(message)) div(tags$b(message, style="color: red;")),

        footer = tagList(
          modalButton("Cancel"),
          actionButton("authenticate", "OK")
        )
      )
    }

    observeEvent(input$login, {
      showModal(passwordModal())
    })

    observeEvent(input$authenticate, {
      vals$authenticated <- FALSE
      if (!is.null(input$username) && nzchar(input$username) &&
          !is.null(input$password) && nzchar(input$password)) {
        removeModal()

        if (input$password == "letmein") {
          vals$authenticated <- TRUE
        } else {
          showModal(passwordModal(message="Incorrect password!"))
        }

      } else {
        showModal(passwordModal(message="Please fill in your username and password"))
      }
    })

    output$secrets <- renderText({
      if (vals$authenticated) {
        paste("Don't tell anyone, ", input$username, ", but...", sep="")
      } else {
        "I can't tell you that!"
      }
    })
  }
)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!