Additional ZEN/security issue changes removing the MasterPassword (Work in progress)
This commit is contained in:
parent
f4a458536f
commit
8b3f9ade47
@ -211,7 +211,7 @@ namespace Novell.CASA.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageDialog md=new MessageDialog(null,Gtk.DialogFlags.Modal,
|
MessageDialog md = new MessageDialog(null,Gtk.DialogFlags.Modal,
|
||||||
Gtk.MessageType.Error,
|
Gtk.MessageType.Error,
|
||||||
buttonType,
|
buttonType,
|
||||||
message);
|
message);
|
||||||
@ -245,8 +245,15 @@ namespace Novell.CASA.GUI
|
|||||||
// setup the users policy directory
|
// setup the users policy directory
|
||||||
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_CREATE_POLICY_DIR);
|
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_CREATE_POLICY_DIR);
|
||||||
|
|
||||||
|
if (CommonGUI.UseMasterPassword())
|
||||||
|
{
|
||||||
MasterPasswordAuthentication();
|
MasterPasswordAuthentication();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartWithoutMasterPassword();
|
||||||
|
}
|
||||||
|
|
||||||
if (Common.IsTrayAvailable()) // && Common.IsArgSet(args, Common.ARG_SHOW_TRAY_ICON))
|
if (Common.IsTrayAvailable()) // && Common.IsArgSet(args, Common.ARG_SHOW_TRAY_ICON))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -374,7 +381,25 @@ namespace Novell.CASA.GUI
|
|||||||
Logger.DbgLog("GUI:CasaMain.InitializeGUI() - END");
|
Logger.DbgLog("GUI:CasaMain.InitializeGUI() - END");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StartWithoutMasterPassword()
|
||||||
|
{
|
||||||
|
Logger.DbgLog("GUI:LoadPersistence - BEGIN");
|
||||||
|
|
||||||
|
// did the daemon get restarted before the user created a master password?
|
||||||
|
// if so, let's ask the user for their desktop password and set it if there's a cache file
|
||||||
|
if (false == miCASA.IsSecretPersistent(1, ""))
|
||||||
|
{
|
||||||
|
if (true == DoPersistentFilesExist())
|
||||||
|
{
|
||||||
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogDesktopPassword", null);
|
||||||
|
gxmlTemp.Autoconnect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InitializeGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ********************************************************************
|
/// ********************************************************************
|
||||||
|
@ -73,11 +73,9 @@ namespace Novell.CASA.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void HandleUnlock(CasaMain managerInstance, CasaTray trayInstance)
|
public void HandleUnlock(CasaMain managerInstance, CasaTray trayInstance)
|
||||||
{
|
{
|
||||||
|
|
||||||
mCasaInstance = managerInstance;
|
mCasaInstance = managerInstance;
|
||||||
mTrayInstance = trayInstance;
|
mTrayInstance = trayInstance;
|
||||||
|
|
||||||
|
|
||||||
//Logger.DbgLog("GUI:CasaMain.Login() - IsMasterPasswordSet returned false");
|
//Logger.DbgLog("GUI:CasaMain.Login() - IsMasterPasswordSet returned false");
|
||||||
#if W32
|
#if W32
|
||||||
Glade.XML gxmlTemp = new Glade.XML ("../images/casa.glade", "dialogLogin", null);
|
Glade.XML gxmlTemp = new Glade.XML ("../images/casa.glade", "dialogLogin", null);
|
||||||
@ -87,9 +85,10 @@ namespace Novell.CASA.GUI
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
gxmlTemp.Autoconnect (this);
|
gxmlTemp.Autoconnect (this);
|
||||||
dialogLogin.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain");;
|
|
||||||
|
|
||||||
|
dialogLogin.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain");;
|
||||||
label86.Text = "Enter your Master Password to unlock your secrets.";
|
label86.Text = "Enter your Master Password to unlock your secrets.";
|
||||||
|
|
||||||
entryMasterPassword3.Text="";
|
entryMasterPassword3.Text="";
|
||||||
label88.Hide();
|
label88.Hide();
|
||||||
entryMasterPassword4.Hide();
|
entryMasterPassword4.Hide();
|
||||||
@ -152,7 +151,9 @@ namespace Novell.CASA.GUI
|
|||||||
|
|
||||||
public void okbuttonLogin_clicked(object abj, EventArgs args)
|
public void okbuttonLogin_clicked(object abj, EventArgs args)
|
||||||
{
|
{
|
||||||
if( 0 == miCASA.SetMasterPassword(0, entryMasterPassword3.Text) )
|
if (CommonGUI.UseMasterPassword())
|
||||||
|
{
|
||||||
|
if (0 == miCASA.SetMasterPassword(0, entryMasterPassword3.Text))
|
||||||
{
|
{
|
||||||
// unlock it
|
// unlock it
|
||||||
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_UNLOCK_STORE, entryMasterPassword3.Text);
|
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_UNLOCK_STORE, entryMasterPassword3.Text);
|
||||||
@ -166,19 +167,49 @@ namespace Novell.CASA.GUI
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// prompt user
|
// prompt user
|
||||||
MessageDialog md=new MessageDialog(
|
MessageDialog md = new MessageDialog(
|
||||||
mainWindow,Gtk.DialogFlags.Modal,
|
mainWindow, Gtk.DialogFlags.Modal,
|
||||||
Gtk.MessageType.Warning,
|
Gtk.MessageType.Warning,
|
||||||
Gtk.ButtonsType.Ok,
|
Gtk.ButtonsType.Ok,
|
||||||
"Master Password entered is incorrect");
|
"Master Password entered is incorrect");
|
||||||
|
|
||||||
md.Response +=new ResponseHandler(md_Response2);
|
md.Response += new ResponseHandler(md_Response2);
|
||||||
md.SetPosition(Gtk.WindowPosition.CenterOnParent);
|
md.SetPosition(Gtk.WindowPosition.CenterOnParent);
|
||||||
md.Modal = true;
|
md.Modal = true;
|
||||||
md.SetIconFromFile(Common.CASAICONS);
|
md.SetIconFromFile(Common.CASAICONS);
|
||||||
md.Show();
|
md.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Novell.CASA.miCASA.ValidateDesktopPwd(entryMasterPassword3.Text))
|
||||||
|
{
|
||||||
|
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_UNLOCK_STORE, entryMasterPassword3.Text);
|
||||||
|
m_bPasswordVerified = true;
|
||||||
|
dialogLogin.Destroy();
|
||||||
|
|
||||||
|
//signal now
|
||||||
|
m_bIsVerifing = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// prompt user
|
||||||
|
MessageDialog md = new MessageDialog(
|
||||||
|
mainWindow, Gtk.DialogFlags.Modal,
|
||||||
|
Gtk.MessageType.Warning,
|
||||||
|
Gtk.ButtonsType.Ok,
|
||||||
|
"Password entered is incorrect");
|
||||||
|
|
||||||
|
md.Response += new ResponseHandler(md_Response2);
|
||||||
|
md.SetPosition(Gtk.WindowPosition.CenterOnParent);
|
||||||
|
md.Modal = true;
|
||||||
|
md.SetIconFromFile(Common.CASAICONS);
|
||||||
|
md.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void closebuttonLogin_clicked(object abj, EventArgs args)
|
public void closebuttonLogin_clicked(object abj, EventArgs args)
|
||||||
{
|
{
|
||||||
@ -299,20 +330,21 @@ namespace Novell.CASA.GUI
|
|||||||
|
|
||||||
public bool VerifyMasterPasswordWithUser()
|
public bool VerifyMasterPasswordWithUser()
|
||||||
{
|
{
|
||||||
|
if (UseMasterPassword())
|
||||||
|
{
|
||||||
//Logger.DbgLog("GUI:CasaMain.Login() - IsMasterPasswordSet returned false");
|
//Logger.DbgLog("GUI:CasaMain.Login() - IsMasterPasswordSet returned false");
|
||||||
#if W32
|
#if W32
|
||||||
Glade.XML gxmlTemp = new Glade.XML ("../images/casa.glade", "dialogLogin", null);
|
Glade.XML gxmlTemp = new Glade.XML("../images/casa.glade", "dialogLogin", null);
|
||||||
#endif
|
#endif
|
||||||
#if LINUX
|
#if LINUX
|
||||||
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogLogin", null);
|
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogLogin", null);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gxmlTemp.Autoconnect (this);
|
gxmlTemp.Autoconnect(this);
|
||||||
dialogLogin.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain");;
|
dialogLogin.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain"); ;
|
||||||
|
|
||||||
label86.Text = "Enter your Master Password to continue.";
|
label86.Text = "Enter your Master Password to continue.";
|
||||||
entryMasterPassword3.Text="";
|
entryMasterPassword3.Text = "";
|
||||||
label88.Hide();
|
label88.Hide();
|
||||||
entryMasterPassword4.Hide();
|
entryMasterPassword4.Hide();
|
||||||
//dialogLogin.SetPosition(Gtk.WindowPosition.Center);
|
//dialogLogin.SetPosition(Gtk.WindowPosition.Center);
|
||||||
@ -329,6 +361,11 @@ namespace Novell.CASA.GUI
|
|||||||
}
|
}
|
||||||
return m_bPasswordVerified;
|
return m_bPasswordVerified;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void DisplayMessage(Gtk.MessageType messageType, String sMessage)
|
public static void DisplayMessage(Gtk.MessageType messageType, String sMessage)
|
||||||
{
|
{
|
||||||
@ -354,6 +391,12 @@ namespace Novell.CASA.GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal static bool UseMasterPassword()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if W32
|
#if W32
|
||||||
|
|
||||||
public static bool IsGTKSharpInstalled()
|
public static bool IsGTKSharpInstalled()
|
||||||
@ -428,10 +471,7 @@ namespace Novell.CASA.GUI
|
|||||||
//return null;
|
//return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,8 @@ namespace Novell.CASA.GUI
|
|||||||
else if (true == cbShowValues.Active)
|
else if (true == cbShowValues.Active)
|
||||||
{
|
{
|
||||||
// prompt user for MasterPassword
|
// prompt user for MasterPassword
|
||||||
|
if (CommonGUI.UseMasterPassword())
|
||||||
|
{
|
||||||
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogLogin", null);
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogLogin", null);
|
||||||
gxmlTemp.Autoconnect(this);
|
gxmlTemp.Autoconnect(this);
|
||||||
dialogLogin.TransientFor = dialogFindAndReplace;
|
dialogLogin.TransientFor = dialogFindAndReplace;
|
||||||
@ -191,16 +192,22 @@ namespace Novell.CASA.GUI
|
|||||||
labelSeconds.Visible = false;
|
labelSeconds.Visible = false;
|
||||||
spinbuttonRememberFor.Visible = false;
|
spinbuttonRememberFor.Visible = false;
|
||||||
//spinbuttonRememberFor.Text = m_config.GetConfigSetting(CommonGUI.REMEMBER_SETTING, m_sRememberFor);
|
//spinbuttonRememberFor.Text = m_config.GetConfigSetting(CommonGUI.REMEMBER_SETTING, m_sRememberFor);
|
||||||
|
|
||||||
//dialogLogin.Show();
|
//dialogLogin.Show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// display the values
|
||||||
|
tvResults.RemoveColumn(tvResults.GetColumn(2));
|
||||||
|
tvCol = new TreeViewColumn("Value", new CellRendererText(), "text", 3);
|
||||||
|
tvResults.InsertColumn(tvCol, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tvResults.RemoveColumn(tvResults.GetColumn(2));
|
tvResults.RemoveColumn(tvResults.GetColumn(2));
|
||||||
tvCol = new TreeViewColumn("Value", new CellRendererText(), "text", 2);
|
tvCol = new TreeViewColumn("Value", new CellRendererText(), "text", 2);
|
||||||
tvResults.InsertColumn(tvCol, 2);
|
tvResults.InsertColumn(tvCol, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closebuttonLogin_clicked(object abj, EventArgs args)
|
public void closebuttonLogin_clicked(object abj, EventArgs args)
|
||||||
|
@ -768,12 +768,14 @@ public class Firefox : Store
|
|||||||
}
|
}
|
||||||
else if (true == cbuttonShowPassword.Active)
|
else if (true == cbuttonShowPassword.Active)
|
||||||
{
|
{
|
||||||
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogLogin", null);
|
if (CommonGUI.UseMasterPassword())
|
||||||
gxmlTemp.Autoconnect (this);
|
{
|
||||||
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogLogin", null);
|
||||||
|
gxmlTemp.Autoconnect(this);
|
||||||
dialogLogin.TransientFor = dialogManageSecret;
|
dialogLogin.TransientFor = dialogManageSecret;
|
||||||
|
|
||||||
label86.Text = "Enter your Master Password to view passwords";
|
label86.Text = "Enter your Master Password to view passwords";
|
||||||
entryMasterPassword3.Text="";
|
entryMasterPassword3.Text = "";
|
||||||
entryMasterPassword3.HasFocus = true;
|
entryMasterPassword3.HasFocus = true;
|
||||||
label88.Hide();
|
label88.Hide();
|
||||||
entryMasterPassword4.Hide();
|
entryMasterPassword4.Hide();
|
||||||
@ -784,6 +786,14 @@ public class Firefox : Store
|
|||||||
dialogLogin.Show();
|
dialogLogin.Show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// display the values
|
||||||
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 1);
|
||||||
|
tvKeyValue.InsertColumn(tvCol, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
||||||
|
@ -500,12 +500,15 @@ public class GnomeKeyring : Store
|
|||||||
}
|
}
|
||||||
else if (true == cbuttonShowPassword.Active)
|
else if (true == cbuttonShowPassword.Active)
|
||||||
{
|
{
|
||||||
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogLogin", null);
|
if (CommonGUI.UseMasterPassword())
|
||||||
gxmlTemp.Autoconnect (this);
|
{
|
||||||
|
|
||||||
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogLogin", null);
|
||||||
|
gxmlTemp.Autoconnect(this);
|
||||||
dialogLogin.TransientFor = dialogManageSecret;
|
dialogLogin.TransientFor = dialogManageSecret;
|
||||||
|
|
||||||
label86.Text = "Enter your Master Password to view passwords";
|
label86.Text = "Enter your Master Password to view passwords";
|
||||||
entryMasterPassword3.Text="";
|
entryMasterPassword3.Text = "";
|
||||||
entryMasterPassword3.HasFocus = true;
|
entryMasterPassword3.HasFocus = true;
|
||||||
label88.Hide();
|
label88.Hide();
|
||||||
entryMasterPassword4.Hide();
|
entryMasterPassword4.Hide();
|
||||||
@ -516,6 +519,14 @@ public class GnomeKeyring : Store
|
|||||||
dialogLogin.Show();
|
dialogLogin.Show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// display the values
|
||||||
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 1);
|
||||||
|
tvKeyValue.InsertColumn(tvCol, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
||||||
|
@ -500,12 +500,14 @@ public class KdeWallet : Store
|
|||||||
}
|
}
|
||||||
else if (true == cbuttonShowPassword.Active)
|
else if (true == cbuttonShowPassword.Active)
|
||||||
{
|
{
|
||||||
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogLogin", null);
|
if (CommonGUI.UseMasterPassword())
|
||||||
gxmlTemp.Autoconnect (this);
|
{
|
||||||
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogLogin", null);
|
||||||
|
gxmlTemp.Autoconnect(this);
|
||||||
dialogLogin.TransientFor = dialogManageSecret;
|
dialogLogin.TransientFor = dialogManageSecret;
|
||||||
|
|
||||||
label86.Text = "Enter your Master Password to view passwords";
|
label86.Text = "Enter your Master Password to view passwords";
|
||||||
entryMasterPassword3.Text="";
|
entryMasterPassword3.Text = "";
|
||||||
entryMasterPassword3.HasFocus = true;
|
entryMasterPassword3.HasFocus = true;
|
||||||
label88.Hide();
|
label88.Hide();
|
||||||
entryMasterPassword4.Hide();
|
entryMasterPassword4.Hide();
|
||||||
@ -516,6 +518,14 @@ public class KdeWallet : Store
|
|||||||
dialogLogin.Show();
|
dialogLogin.Show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// display the values
|
||||||
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 1);
|
||||||
|
tvKeyValue.InsertColumn(tvCol, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
||||||
|
@ -567,6 +567,8 @@ namespace Novell.CASA.GUI
|
|||||||
tvKeyValue.ButtonReleaseEvent += new ButtonReleaseEventHandler(OnRightClickedKeyValue);
|
tvKeyValue.ButtonReleaseEvent += new ButtonReleaseEventHandler(OnRightClickedKeyValue);
|
||||||
}
|
}
|
||||||
else if (true == cbuttonShowPassword.Active)
|
else if (true == cbuttonShowPassword.Active)
|
||||||
|
{
|
||||||
|
if (CommonGUI.UseMasterPassword())
|
||||||
{
|
{
|
||||||
// prompt user for MasterPassword
|
// prompt user for MasterPassword
|
||||||
|
|
||||||
@ -588,6 +590,15 @@ namespace Novell.CASA.GUI
|
|||||||
dialogLogin.Show();
|
dialogLogin.Show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
// display the values
|
||||||
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 1);
|
||||||
|
tvKeyValue.InsertColumn(tvCol, 1);
|
||||||
|
tvKeyValue.ButtonReleaseEvent += new ButtonReleaseEventHandler(OnRightClickedKeyValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
tvKeyValue.RemoveColumn(tvKeyValue.GetColumn(1));
|
||||||
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
tvCol = new TreeViewColumn("Value", cellEditable, "text", 2);
|
||||||
|
@ -178,7 +178,7 @@
|
|||||||
<References>
|
<References>
|
||||||
<ProjectReference
|
<ProjectReference
|
||||||
ReferencedProjectIdentifier="{B5DB4B53-AB02-4EDC-9C02-BF7DE68F91A3}"
|
ReferencedProjectIdentifier="{B5DB4B53-AB02-4EDC-9C02-BF7DE68F91A3}"
|
||||||
RelativePathToProject="..\..\..\..\micasacache\c_micasacache.vcproj"
|
RelativePathToProject="..\..\..\micasacache\c_micasacache.vcproj"
|
||||||
/>
|
/>
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user