// ĠCopyright Ġ 2 0 0 0 - 2 0 1 8 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ package Ġcom . intellij . credential Store Ċ Ċ import Ġcom . intellij . credential Store . k db x . Incorrect Master Password Exception Ċ import Ġcom . intellij . credential Store . ke e Pass . DB _ FILE _ NAME Ċ import Ġcom . intellij . credential Store . ke e Pass . K ee Pass FileManager Ċ import Ġcom . intellij . credential Store . ke e Pass . Master Key File Storage Ċ import Ġcom . intellij . credential Store . ke e Pass . getDefault Master Password File Ċ import Ġcom . intellij . ide . password Safe . Password Safe Ċ import Ġcom . intellij . ide . password Safe . impl . Password Safe Impl Ċ import Ġcom . intellij . ide . password Safe . impl . create Persistent Credential Store Ċ import Ġcom . intellij . ide . password Safe . impl . getDefault K ee Pass Db File Ċ import Ġcom . intellij . openapi . action System . An ActionEvent Ċ import Ġcom . intellij . openapi . file Chooser . FileChooser Descriptor Factory Ċ import Ġcom . intellij . openapi . options . Configurable Base Ċ import Ġcom . intellij . openapi . options . Configurable Ui Ċ import Ġcom . intellij . openapi . options . ConfigurationException Ċ import Ġcom . intellij . openapi . project . D umb Aware Action Ċ import Ġcom . intellij . openapi . ui . Message Dialog Builder Ċ import Ġcom . intellij . openapi . ui . TextField With Browse Button Ċ import Ġcom . intellij . openapi . util . System Info Ċ import Ġcom . intellij . ui . components . RadioButton Ċ import Ġcom . intellij . ui . layout .* Ċ import Ġcom . intellij . util . io . exists Ċ import Ġcom . intellij . util . io . isDirectory Ċ import Ġcom . intellij . util . text . nul lize Ċ import Ġg nu . tro ve . TH ash Map Ċ import Ġjava . io . File Ċ import Ġjava . nio . file . Paths Ċ import Ġjavax . swing . JPanel Ċ import Ġkotlin . properties . Deleg ates . notNull Ċ Ċ internal Ġclass ĠPassword Safe Configurable ( private Ġval Ġsettings : ĠPassword Safe Settings ) Ġ: ĠConfigur able Base < Password Safe Configurable Ui , ĠPassword Safe Settings >(" application . password Safe ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Password s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" reference . ide . settings . password . safe ") Ġ{ ĊĠ Ġoverride Ġfun Ġget Settings () Ġ= Ġsettings ĊĊĠ Ġoverride Ġfun Ġcreate Ui () Ġ= ĠPassword Safe Configurable Ui () Ċ } Ċ Ċ internal Ġclass ĠPassword Safe Configurable Ui Ġ: ĠConfigur able Ui < Password Safe Settings > Ġ{ ĊĠ Ġprivate Ġval Ġin Key chain Ġ= ĠRadio Button (" In Ġnative ĠKey chain ") ĊĊĠ Ġprivate Ġval Ġin K ee Pass Ġ= ĠRadio Button (" In ĠK ee Pass ") ĊĠ Ġprivate Ġvar Ġke e Pass Db File : ĠTextField With Browse Button Ġby Ġnot Null () ĊĊĠ Ġprivate Ġval Ġremember Password s Until Closing Ġ= ĠRadio Button (" Do Ġnot Ġsave , Ġforget Ġpasswords Ġafter Ġrestart ") ĊĊĠ Ġprivate Ġval Ġmode To Row Ġ= ĠT HashMap < Provider Type , ĠRow >() ĊĊĠ Ġoverride Ġfun Ġreset ( settings : ĠPassword Safe Settings ) Ġ{ ĊĠĠĠ Ġwhen Ġ( settings . provider Type ) Ġ{ ĊĠĠĠĠĠ ĠProvider Type . MEMORY _ ONLY Ġ-> Ġremember Password s Until Closing . isSelected Ġ= Ġtrue ĊĠĠĠĠĠ ĠProvider Type . KEY CHAIN Ġ-> Ġin Key chain . isSelected Ġ= Ġtrue ĊĠĠĠĠĠ ĠProvider Type . KEEP ASS Ġ-> Ġin K ee Pass . isSelected Ġ= Ġtrue ĊĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Unknown Ġprovider Ġtype : Ġ${ settings . provider Type }") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" If Then To El vis ") ĊĠĠĠ Ġke e Pass Db File . text Ġ= Ġsettings . keep ass Db Ġ?: ĠgetDefault K ee Pass Db File (). toString () ĊĠĠĠ Ġupdate Enabled State () ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġis Modified ( settings : ĠPassword Safe Settings ): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn Ġget New Provider Type () Ġ!= Ġsettings . provider Type Ġ|| Ġis Keep ass File Location Changed ( settings ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġis Keep ass File Location Changed ( settings : ĠPassword Safe Settings ): ĠBoolean Ġ{ ĊĠĠĠ Ġreturn Ġget New Provider Type () Ġ== ĠProvider Type . KEEP ASS Ġ&& Ġget New Db File AsString () Ġ!= Ġsettings . keep ass Db ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġapply ( settings : ĠPassword Safe Settings ) Ġ{ ĊĠĠĠ Ġval Ġprovider Type Ġ= Ġget New Provider Type () ĊĠĠĠ Ġval Ġpassword Safe Ġ= ĠPassword Safe . instance Ġas ĠPassword Safe Impl ĊĠĠĠ Ġif Ġ( settings . provider Type Ġ!= Ġprovider Type ) Ġ{ ĊĠĠĠĠĠ Ġ@ Suppress (" NON _ EX HA UST IVE _ WHEN ") ĊĠĠĠĠĠ Ġwhen Ġ( provider Type ) Ġ{ ĊĠĠĠĠĠĠĠ ĠProvider Type . MEMORY _ ONLY Ġ-> Ġclose Current Store If K ee Pass () ĊĊĠĠĠĠĠĠĠ ĠProvider Type . KEY CHAIN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġpassword Safe . current Provider Ġ= Ġcreate Persistent Credential Store () !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠProvider Type . KEEP ASS Ġ-> Ġcreate And Save K ee Pass Database With New Options ( settings ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalStateException (" Unknown Ġprovider Ġtype : Ġ$ provider Type ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġif Ġ( is Keep ass File Location Changed ( settings )) Ġ{ ĊĠĠĠĠĠ Ġcreate And Save K ee Pass Database With New Options ( settings ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsettings . provider Type Ġ= Ġprovider Type ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġcreate And Save K ee Pass Database With New Options ( settings : ĠPassword Safe Settings ) Ġ{ ĊĠĠĠ Ġ// Ġexisting Ġin - memory ĠK ee Pass Ġdatabase Ġis Ġnot Ġused , Ġthe Ġsame Ġas Ġif Ġswitched Ġto ĠKEY CHAIN ĊĠĠĠ Ġ// Ġfor ĠK ee Pass Ġnot Ġclear Ġ- Ġshould Ġwe Ġappend Ġin - memory Ġcredentials Ġto Ġexisting Ġdatabase Ġor Ġnot ĊĠĠĠ Ġ// Ġ( and Ġif Ġdatabase Ġdoesn 't Ġexist , Ġshould Ġwe Ġappend Ġor Ġnot ), Ġso , Ġwait Ġfirst Ġuser Ġrequest Ġ( prefer Ġto Ġkeep Ġimplementation Ġsimple ) ĊĠĠĠ Ġclose Current Store If K ee Pass () ĊĊĠĠĠ Ġval Ġnew Db File Ġ= Ġget New Db File () Ġ?: Ġthrow ĠConfiguration Exception (" K ee Pass Ġdatabase Ġpath Ġis Ġempty .") ĊĠĠĠ Ġif Ġ( new Db File . isDirectory ()) Ġ{ ĊĠĠĠĠĠ Ġ// Ġwe Ġdo Ġnot Ġnormalize Ġas Ġwe Ġdo Ġon Ġfile Ġchoose Ġbecause Ġif Ġuser Ġdecoded Ġto Ġtype Ġpath Ġmanually , ĊĠĠĠĠĠ Ġ// Ġit Ġshould Ġbe Ġvalid Ġpath Ġand Ġbetter Ġto Ġavoid Ġany Ġmagic Ġhere ĊĠĠĠĠĠ Ġthrow ĠConfiguration Exception (" K ee Pass Ġdatabase Ġfile Ġis Ġdirectory .") ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ(! new Db File . fileName . toString (). endsWith (". k db x ")) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠConfiguration Exception (" K ee Pass Ġdatabase Ġfile Ġshould Ġends Ġwith Ġ\ ". k db x \" .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsettings . keep ass Db Ġ= Ġnew Db File . toString () ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ ĠK ee Pass FileManager ( new Db File , ĠgetDefault Master Password File ()). use Existing () ĊĠĠĠ Ġ} ĊĠĠĠ Ġcatch Ġ( e : ĠInc orrect Master Password Exception ) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠConfiguration Exception (" Master Ġpassword Ġfor ĠK ee Pass Ġdatabase Ġis Ġnot Ġcorrect Ġ( \" Clear \" Ġcan Ġbe Ġused Ġto Ġreset Ġdatabase ). ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġget New Db File () Ġ= Ġget New Db File AsString ()?. let Ġ{ ĠPaths . get ( it ) Ġ} ĊĊĠ Ġprivate Ġfun Ġget New Db File AsString () Ġ= Ġke e Pass Db File . text . trim (). nul lize () ĊĊĠ Ġprivate Ġfun Ġupdate Enabled State () Ġ{ ĊĠĠĠ Ġmode To Row [ Provider Type . KEEP ASS ]?. sub Rows Enabled Ġ= Ġget New Provider Type () Ġ== ĠProvider Type . KEEP ASS ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġget Component (): ĠJPanel Ġ{ ĊĠĠĠ Ġreturn Ġpanel Ġ{ ĊĠĠĠĠĠ Ġrow Ġ{ Ġlabel (" Save Ġpasswords :") Ġ} ĊĊĠĠĠĠĠ Ġbutton Group ({ Ġupdate Enabled State () Ġ}) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( System Info . is Linux Ġ|| Ġis Mac Os Credential Store Supported ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġrow Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġin Key chain () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġmode To Row [ Provider Type . KEEP ASS ] Ġ= Ġrow Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġin K ee Pass () ĊĠĠĠĠĠĠĠĠĠ Ġrow (" Database :") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Chooser Descriptor Ġ= ĠFile Chooser Descriptor Factory . create Single Local FileDescriptor (). with File Filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . isDirectory Ġ|| Ġit . name . endsWith (". k db x ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġke e Pass Db File Ġ= Ġtext Field With Browse Button (" K ee Pass ĠDatabase ĠFile ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Chooser Descriptor Ġ= Ġfile Chooser Descriptor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Ch osen Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . isDirectory Ġ-> Ġ"${ it . path }${ File . separator }$ DB _ FILE _ NAME " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġit . path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcomment Ġ= Ġif Ġ( System Info . is Windows ) Ġnull Ġelse Ġ" Stored Ġusing Ġweak Ġencryption . ĠIt Ġis Ġrecommended Ġto Ġstore Ġon Ġencrypted Ġvolume Ġfor Ġadditional Ġsecurity .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġge ar Button ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClear K ee Pass Database Action (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠImport K ee Pass Database Action (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠChange K ee Pass Database Master Password Action () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġrow Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġremember Password s Until Closing () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġcreate K ee Pass FileManager (): ĠK ee Pass FileManager ? Ġ{ ĊĠĠĠ Ġreturn ĠK ee Pass FileManager ( getNew Db File () Ġ?: Ġreturn Ġnull , ĠgetDefault Master Password File ()) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġget New Provider Type (): ĠProvider Type Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠ Ġremember Password s Until Closing . isSelected Ġ-> ĠProvider Type . MEMORY _ ONLY ĊĠĠĠĠĠ Ġin K ee Pass . isSelected Ġ-> ĠProvider Type . KEEP ASS ĊĠĠĠĠĠ Ġelse Ġ-> ĠProvider Type . KEY CHAIN ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġinner Ġclass ĠClear K ee Pass Database Action Ġ: ĠD umb Aware Action (" Clear ") Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠactionPerformed ( event : ĠAn ActionEvent ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! Message Dialog Builder . yes No (" Clear ĠPassword s ", Ġ" Are Ġyou Ġsure Ġwant Ġto Ġremove Ġall Ġpasswords ? "). yes Text (" Remove ĠPassword s "). is Yes ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġclose Current Store If K ee Pass () ĊĊĠĠĠĠĠ ĠLOG . info (" Password s Ġcleared ", ĠError ()) ĊĠĠĠĠĠ Ġcreate K ee Pass FileManager ()?. clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġupdate ( e : ĠAn ActionEvent ) Ġ{ ĊĠĠĠĠĠ Ġe . presentation . isEnabled Ġ= Ġget New Db File ()?. exists () Ġ?: Ġfalse ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġinner Ġclass ĠImport K ee Pass Database Action Ġ: ĠD umb Aware Action (" Import ") Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠactionPerformed ( event : ĠAn ActionEvent ) Ġ{ ĊĠĠĠĠĠ Ġclose Current Store If K ee Pass () ĊĊĠĠĠĠĠ ĠFile Chooser Descriptor Factory . create Single Local FileDescriptor () ĊĠĠĠĠĠĠĠ Ġ. with File Filter Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ! it . isDirectory Ġ&& Ġit . name Sequence . endsWith (". k db x ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. choose File ( event ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcreate K ee Pass FileManager ()?. import ( Paths . get ( it . path ), Ġevent ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġinner Ġclass ĠChange K ee Pass Database Master Password Action Ġ: ĠD umb Aware Action ("${ if Ġ( Master Key File Storage ( getDefault Master Password File ()). is Auto Generated ()) Ġ" Set " Ġelse Ġ" Change "} ĠMaster ĠPassword ") Ġ{ ĊĠĠĠ Ġoverride Ġfun ĠactionPerformed ( event : ĠAn ActionEvent ) Ġ{ ĊĠĠĠĠĠ Ġclose Current Store If K ee Pass () ĊĊĠĠĠĠĠ Ġ// Ġeven Ġif Ġcurrent Ġprovider Ġis Ġnot ĠK EE PASS , Ġall Ġactions Ġfor Ġdb Ġfile Ġmust Ġbe Ġapplied Ġimmediately Ġ( show Ġerror Ġif Ġnew Ġmaster Ġpassword Ġnot Ġapplicable Ġfor Ġexisting Ġdb Ġfile ) ĊĠĠĠĠĠ Ġif Ġ( create K ee Pass FileManager ()?. ask AndSet Master Key ( event ) Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtemplate Presentation . text Ġ= Ġ" Change ĠMaster ĠPassword " ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġupdate ( e : ĠAn ActionEvent ) Ġ{ ĊĠĠĠĠĠ Ġe . presentation . isEnabled Ġ= Ġget New Db File AsString () Ġ!= Ġnull ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ // Ġwe Ġmust Ġsave Ġand Ġclose Ġopened ĠK ee Pass Ġdatabase Ġbefore Ġany Ġaction Ġthat Ġcan Ġmodify ĠK ee Pass Ġdatabase Ġfiles Ċ private Ġfun Ġclose Current Store If K ee Pass () Ġ{ ĊĠ Ġ( Password Safe . instance Ġas ĠPassword Safe Impl ). close Current Store If K ee Pass () Ċ }