ide: Credentials passkey

git-svn-id: svn://ultimatepp.org/upp/trunk@15635 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2021-01-02 19:58:35 +00:00
parent 0d8b96d4d4
commit 4016428b7d
3 changed files with 149 additions and 33 deletions

View file

@ -70,7 +70,7 @@ class Sha256Stream : public OutStream {
void Cleanup();
public:
void Finish(byte *hash20);
void Finish(byte *hash32);
String FinishString();
String FinishStringS();
@ -81,8 +81,8 @@ public:
~Sha256Stream();
};
void SHA256(byte *hash20, const void *data, dword size);
void SHA256(byte *hash20, const String& s);
void SHA256(byte *hash32, const void *data, dword size);
void SHA256(byte *hash32, const String& s);
String SHA256String(const void *data, dword size);
String SHA256String(const String& data);
String SHA256StringS(const void *data, dword size);

View file

@ -11,6 +11,39 @@ String GetSvnDir(const String& p)
return Null;
}
byte passkey_sha256[32];
String CredentialsCrypt(const String& src)
{
int ci = 0;
byte c[32];
memcpy(c, passkey_sha256, 32);
String r;
for(char b : src) {
if(ci >= 32) { // poor mans acceptable encryption
SHA256(c, c, 32);
ci = 0;
}
r.Cat(b ^ c[ci++]);
}
return r;
}
struct PasskeyDlg : WithPasskeyLayout<TopWindow> {
PasskeyDlg();
void Sync() { passkey1.Password(!show_passkey); passkey2.Password(!show_passkey); }
};
PasskeyDlg::PasskeyDlg()
{
CtrlLayoutOK(*this, "Passkey");
show_passkey << [=] { Sync(); };
Sync();
}
struct Credential {
String url;
String username;
@ -22,10 +55,12 @@ String CredentialsFile()
return ConfigFile("repo.credentials");
}
bool LoadCredentials(Array<Credential>& r)
bool LoadCredentials0(Array<Credential>& r)
{
r.Clear();
String s = LoadFile(CredentialsFile());
if(String(passkey_sha256, 32) != String(0, 32))
s = CredentialsCrypt(s);
Value v = ParseJSON(s);
if(IsError(v))
return false;
@ -44,6 +79,45 @@ bool LoadCredentials(Array<Credential>& r)
return true;
}
struct GetPasskeyDlg : WithGetPasskeyLayout<TopWindow> {
GetPasskeyDlg();
void Sync() { passkey.Password(!show_passkey);; }
};
GetPasskeyDlg::GetPasskeyDlg()
{
CtrlLayoutOKCancel(*this, "Passkey");
show_passkey << [=] { Sync(); };
Sync();
}
bool LoadCredentials(Array<Credential>& r)
{
if(!FileExists(CredentialsFile()))
return false;
if(LoadCredentials0(r)) return true;
if(String(passkey_sha256, 32) == String(0, 32)) {
for(;;) {
GetPasskeyDlg dlg;
dlg.Run();
SHA256(passkey_sha256, ~dlg.passkey);
if(LoadCredentials0(r)) return true;
WithFailedPasskeyLayout<TopWindow> p;
CtrlLayoutOK(p, "Passkey");
p.Breaker(p.clear, IDEXIT);
if(p.Run() == IDEXIT) {
memset(passkey_sha256, 0, 32);
FileDelete(CredentialsFile());
break;
}
}
}
return false;
}
bool GetCredentials(const String& url, const String& dir, String& username, String& password)
{
Array<Credential> cr;
@ -97,11 +171,52 @@ struct CredentialsDlg : WithCredentialsLayout<TopWindow> {
void Load();
void Save();
void Passkey();
typedef CredentialsDlg CLASSNAME;
CredentialsDlg(const Vector<String>& url_hints);
};
CredentialsDlg::CredentialsDlg(const Vector<String>& url_hints)
: url_hints(url_hints)
{
CtrlLayoutOKCancel(*this, "Credentials");
list.AddColumn("Url (or directory)");
list.AddColumn("Username");
list.AddColumn("Password");
list.ColumnWidths("500 200 200");
list.EvenRowColor();
list.SetLineCy(max(Draw::GetStdFontCy() + Zy(4), Zy(20)));
list.WhenSel = [=] { Sync(); };
list.WhenLeftDouble = [=] { Edit(); };
show_passwords << [=] { Sync(); };
add << [=] { Add(); };
edit << [=] { Edit(); };
remove << [=] { Remove(); };
clear << [=] {
if(PromptYesNo("Remove all?"))
list.Clear();
};
passkey << [=] { Passkey(); };
}
void CredentialsDlg::Passkey()
{
PasskeyDlg dlg;
String k;
for(;;) {
if(dlg.Run() == IDCANCEL)
return;
k = ~dlg.passkey1;
if(k == ~dlg.passkey2)
break;
Exclamation("Fields do not match!");
}
SHA256(passkey_sha256, k);
}
void CredentialsDlg::Load()
{
list.Clear();
@ -121,7 +236,7 @@ void CredentialsDlg::Save()
va << ValueMap()("url", list.Get(i, 0))
("username", list.Get(i, 1))
("password", list.Get(i, 2));
SaveFile(CredentialsFile(), AsJSON(va));
SaveFile(CredentialsFile(), CredentialsCrypt(AsJSON(va)));
}
else
FileDelete(CredentialsFile());
@ -189,29 +304,6 @@ void CredentialsDlg::Sync()
);
}
CredentialsDlg::CredentialsDlg(const Vector<String>& url_hints)
: url_hints(url_hints)
{
CtrlLayoutOKCancel(*this, "Credentials");
list.AddColumn("Url (or directory)");
list.AddColumn("Username");
list.AddColumn("Password");
list.ColumnWidths("500 200 200");
list.EvenRowColor();
list.SetLineCy(max(Draw::GetStdFontCy() + Zy(4), Zy(20)));
list.WhenSel = [=] { Sync(); };
list.WhenLeftDouble = [=] { Edit(); };
show_passwords << [=] { Sync(); };
add << [=] { Add(); };
edit << [=] { Edit(); };
remove << [=] { Remove(); };
clear << [=] {
if(PromptYesNo("Remove all?"))
list.Clear();
};
}
void EditCredentials(const Vector<String>& url_hints)
{
CredentialsDlg dlg(url_hints);

View file

@ -7,13 +7,14 @@ END_LAYOUT
LAYOUT(CredentialsLayout, 680, 400)
ITEM(Upp::ArrayCtrl, list, AutoHideSb(true).HSizePosZ(4, 4).VSizePosZ(4, 36))
ITEM(Upp::Option, show_passwords, SetLabel(t_("Show passwords")).LeftPosZ(4, 108).TopPosZ(372, 20))
ITEM(Upp::Button, passkey, SetLabel(t_("Passkey..")).LeftPosZ(136, 76).TopPosZ(372, 24))
ITEM(Upp::Button, add, SetLabel(t_("Add..")).LeftPosZ(240, 64).TopPosZ(372, 24))
ITEM(Upp::Button, edit, SetLabel(t_("Edit..")).LeftPosZ(308, 64).TopPosZ(372, 24))
ITEM(Upp::Button, remove, SetLabel(t_("Remove")).LeftPosZ(376, 64).TopPosZ(372, 24))
ITEM(Upp::Button, clear, SetLabel(t_("Remove all")).LeftPosZ(456, 72).TopPosZ(372, 24))
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(544, 64).BottomPosZ(4, 24))
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(612, 64).BottomPosZ(4, 24))
ITEM(Upp::Option, show_passwords, SetLabel(t_("Show passwords")).LeftPosZ(4, 108).TopPosZ(372, 20))
ITEM(Upp::Button, clear, SetLabel(t_("Remove all")).LeftPosZ(448, 72).TopPosZ(372, 24))
ITEM(Upp::Button, add, SetLabel(t_("Add..")).LeftPosZ(220, 64).TopPosZ(372, 24))
ITEM(Upp::Button, edit, SetLabel(t_("Edit..")).LeftPosZ(288, 64).TopPosZ(372, 24))
ITEM(Upp::Button, remove, SetLabel(t_("Remove")).LeftPosZ(356, 64).TopPosZ(372, 24))
END_LAYOUT
LAYOUT(UrepoConsoleLayout, 680, 660)
@ -45,3 +46,26 @@ LAYOUT(CredentialLayout, 368, 116)
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(296, 64).BottomPosZ(8, 24))
END_LAYOUT
LAYOUT(PasskeyLayout, 368, 92)
ITEM(Upp::Label, dv___0, SetLabel(t_("Passkey")).LeftPosZ(8, 92).TopPosZ(8, 19))
ITEM(Upp::EditString, passkey1, LeftPosZ(112, 248).TopPosZ(8, 19))
ITEM(Upp::Label, dv___2, SetLabel(t_("Passkey (confirm)")).LeftPosZ(8, 92).TopPosZ(32, 19))
ITEM(Upp::EditString, passkey2, LeftPosZ(112, 248).TopPosZ(32, 19))
ITEM(Upp::Option, show_passkey, SetLabel(t_("Show passkey")).LeftPosZ(8, 108).TopPosZ(60, 20))
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(296, 64).BottomPosZ(8, 24))
END_LAYOUT
LAYOUT(GetPasskeyLayout, 368, 68)
ITEM(Upp::Label, dv___0, SetLabel(t_("Passkey")).LeftPosZ(8, 92).TopPosZ(8, 19))
ITEM(Upp::EditString, passkey, LeftPosZ(112, 248).TopPosZ(8, 19))
ITEM(Upp::Option, show_passkey, SetLabel(t_("Show passkey")).LeftPosZ(8, 108).TopPosZ(36, 20))
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(228, 64).BottomPosZ(8, 24))
ITEM(Upp::Button, ok, SetLabel(t_("OK")).LeftPosZ(296, 64).BottomPosZ(8, 24))
END_LAYOUT
LAYOUT(FailedPasskeyLayout, 296, 64)
ITEM(Upp::Label, dv___0, SetLabel(t_("Invalid passkey.")).LeftPosZ(8, 296).TopPosZ(8, 19))
ITEM(Upp::Button, clear, SetLabel(t_("Clear credentials and passkey")).LeftPosZ(8, 168).TopPosZ(32, 24))
ITEM(Upp::Button, ok, SetLabel(t_("Try again")).LeftPosZ(212, 76).TopPosZ(32, 24))
END_LAYOUT