Skip to content

Commit

Permalink
Adds a first-run notice informing user of telemetry. (#145)
Browse files Browse the repository at this point in the history
* Adds a first-run reminder about telemetry.

* Improve telemetry opt out message

* Fixes #120

* Updated strings

* Clean up telemetry strings some more

Now use three lines instead of 2 for telemetry info notice.

* Adds a clarifying comment.
  • Loading branch information
gfs committed Apr 24, 2019
1 parent 0c24af3 commit b130802
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 70 deletions.
168 changes: 102 additions & 66 deletions Cli/Program.cs
Expand Up @@ -195,8 +195,11 @@ public static class AttackSurfaceAnalyzerCLI

private static readonly string SQL_GET_RUN = "select run_id from runs where run_id=@run_id";

private static bool _isFirstRun = false;

static void Main(string[] args)
{

#if DEBUG
Logger.Setup(true,false);
#else
Expand All @@ -209,8 +212,17 @@ static void Main(string[] args)
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)
as AssemblyInformationalVersionAttribute[])[0].InformationalVersion;
Log.Information("AttackSurfaceAnalyzerCli v.{0}",version);
Log.Debug(version);

Strings.Setup();
DatabaseManager.Setup();
if (DatabaseManager.IsFirstRun())
{
_isFirstRun = true;
string exeStr = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "AttackSurfaceAnalyzerCli.exe config --telemetry-opt-out true" : "AttackSurfaceAnalyzerCli config --telemetry-opt-out true";
Log.Information(Strings.Get("ApplicationHasTelemetry"));
Log.Information(Strings.Get("ApplicationHasTelemetry2"), "https://github.com/Microsoft/AttackSurfaceAnalyzer/blob/master/PRIVACY.md");
Log.Information(Strings.Get("ApplicationHasTelemetry3"), exeStr);
}
Telemetry.Setup(Gui : false);

var argsResult = Parser.Default.ParseArguments<CollectCommandOptions, CompareCommandOptions, MonitorCommandOptions, ExportMonitorCommandOptions, ExportCollectCommandOptions, ConfigCommandOptions>(args)
Expand Down Expand Up @@ -245,92 +257,116 @@ private static int RunConfigCommand(ConfigCommandOptions opts)
if (opts.ListRuns)
{

Log.Information(Strings.Get("Begin")+" {0}", Strings.Get("EnumeratingCollectRunIds"));
List<string> CollectRuns = GetRuns("collect");
foreach (string run in CollectRuns)
if (_isFirstRun)
{
Log.Warning(Strings.Get("FirstRunListRunsError"), opts.DatabaseFilename);
}
else
{
using (var cmd = new SqliteCommand(SQL_GET_RESULT_TYPES_SINGLE, DatabaseManager.Connection, DatabaseManager.Transaction))
Log.Information(Strings.Get("DumpingDataFromDatabase"), opts.DatabaseFilename);
List<string> CollectRuns = GetRuns("collect");
if(CollectRuns.Count > 0)
{
cmd.Parameters.AddWithValue("@run_id", run);
using (var reader = cmd.ExecuteReader())
Log.Information(Strings.Get("Begin") + " {0}", Strings.Get("EnumeratingCollectRunIds"));
foreach (string run in CollectRuns)
{
while (reader.Read())
using (var cmd = new SqliteCommand(SQL_GET_RESULT_TYPES_SINGLE, DatabaseManager.Connection, DatabaseManager.Transaction))
{
Log.Information("RunId:{2} Timestamp:{0} AsaVersion:{1} ",
reader["timestamp"],
reader["version"],
reader["run_id"]);
List<RESULT_TYPE> resultTypes = new List<RESULT_TYPE>();
if (int.Parse(reader["file_system"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.FILE);
}
if (int.Parse(reader["ports"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.PORT);
}
if (int.Parse(reader["users"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.USER);
}
if (int.Parse(reader["services"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.SERVICES);
}
if (int.Parse(reader["certificates"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.CERTIFICATE);
}
if (int.Parse(reader["registry"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.REGISTRY);
}

foreach (RESULT_TYPE type in resultTypes)
cmd.Parameters.AddWithValue("@run_id", run);
using (var reader = cmd.ExecuteReader())
{
int num = DatabaseManager.GetNumResults(type, reader["run_id"].ToString());
Log.Information("{0} : {1}", type, num);
while (reader.Read())
{
Log.Information("RunId:{2} Timestamp:{0} AsaVersion:{1} ",
reader["timestamp"],
reader["version"],
reader["run_id"]);
List<RESULT_TYPE> resultTypes = new List<RESULT_TYPE>();
if (int.Parse(reader["file_system"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.FILE);
}
if (int.Parse(reader["ports"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.PORT);
}
if (int.Parse(reader["users"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.USER);
}
if (int.Parse(reader["services"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.SERVICES);
}
if (int.Parse(reader["certificates"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.CERTIFICATE);
}
if (int.Parse(reader["registry"].ToString()) != 0)
{
resultTypes.Add(RESULT_TYPE.REGISTRY);
}

foreach (RESULT_TYPE type in resultTypes)
{
int num = DatabaseManager.GetNumResults(type, reader["run_id"].ToString());
Log.Information("{0} : {1}", type, num);
}
}
}
}
}
}
}
Log.Information(Strings.Get("Begin") + " {0}", Strings.Get("EnumeratingMonitorRunIds"));
List<string> MonitorRuns = GetRuns("monitor");
foreach (string monitorRun in MonitorRuns)
{
using (var cmd = new SqliteCommand(SQL_GET_RESULT_TYPES_SINGLE, DatabaseManager.Connection, DatabaseManager.Transaction))
else
{
cmd.Parameters.AddWithValue("@run_id", monitorRun);
using (var reader = cmd.ExecuteReader())
Log.Information(Strings.Get("NoCollectRuns"));
}

List<string> MonitorRuns = GetRuns("monitor");
if (MonitorRuns.Count > 0)
{
Log.Information(Strings.Get("Begin") + " {0}", Strings.Get("EnumeratingMonitorRunIds"));

foreach (string monitorRun in MonitorRuns)
{
while (reader.Read())
using (var cmd = new SqliteCommand(SQL_GET_RESULT_TYPES_SINGLE, DatabaseManager.Connection, DatabaseManager.Transaction))
{
string output = String.Format("{0} {1} {2} {3}",
reader["timestamp"].ToString(),
reader["version"].ToString(),
reader["type"].ToString(),
reader["run_id"].ToString());
Log.Information(output);
output = String.Format("{0} {1} {2} {3} {4} {5}",
(int.Parse(reader["file_system"].ToString()) != 0) ? "FILES" : "",
(int.Parse(reader["ports"].ToString()) != 0) ? "PORTS" : "",
(int.Parse(reader["users"].ToString()) != 0) ? "USERS" : "",
(int.Parse(reader["services"].ToString()) != 0) ? "SERVICES" : "",
(int.Parse(reader["certificates"].ToString()) != 0) ? "CERTIFICATES" : "",
(int.Parse(reader["registry"].ToString()) != 0) ? "REGISTRY" : "");
Log.Information(output);

cmd.Parameters.AddWithValue("@run_id", monitorRun);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string output = String.Format("{0} {1} {2} {3}",
reader["timestamp"].ToString(),
reader["version"].ToString(),
reader["type"].ToString(),
reader["run_id"].ToString());
Log.Information(output);
output = String.Format("{0} {1} {2} {3} {4} {5}",
(int.Parse(reader["file_system"].ToString()) != 0) ? "FILES" : "",
(int.Parse(reader["ports"].ToString()) != 0) ? "PORTS" : "",
(int.Parse(reader["users"].ToString()) != 0) ? "USERS" : "",
(int.Parse(reader["services"].ToString()) != 0) ? "SERVICES" : "",
(int.Parse(reader["certificates"].ToString()) != 0) ? "CERTIFICATES" : "",
(int.Parse(reader["registry"].ToString()) != 0) ? "REGISTRY" : "");
Log.Information(output);

}
}
}
}
}
else
{
Log.Information(Strings.Get("NoMonitorRuns"));
}
}
}

if (opts.TelemetryOptOut != null)
{
Telemetry.SetOptOut(bool.Parse(opts.TelemetryOptOut));
Log.Information("{1} {0}.", Strings.Get("TelemetryOptOut"), (bool.Parse(opts.TelemetryOptOut)) ? "Opted out" : "Opted in");
Log.Information(Strings.Get("TelemetryOptOut"), (bool.Parse(opts.TelemetryOptOut)) ? "Opted out" : "Opted in");
}
if (opts.DeleteRunId != null)
{
Expand Down
42 changes: 42 additions & 0 deletions Cli/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 22 additions & 1 deletion Cli/Properties/Resources.resx
Expand Up @@ -169,7 +169,7 @@
<value>Monitor started for</value>
</data>
<data name="TelemetryOptOut" xml:space="preserve">
<value>Your telemetry opt out setting is now</value>
<value>Your telemetry opt out setting is now {0}.</value>
</data>
<data name="WelcomeHeader" xml:space="preserve">
<value>Welcome to Attack Surface Analyzer</value>
Expand Down Expand Up @@ -396,4 +396,25 @@
<data name="OutputWrittenTo" xml:space="preserve">
<value>Output written to: {0}</value>
</data>
<data name="ApplicationHasTelemetry" xml:space="preserve">
<value>This application collects usage data to help us improve Attack Surface Analyzer.</value>
</data>
<data name="ApplicationHasTelemetry2" xml:space="preserve">
<value>For our privacy policy visit: {0}.</value>
</data>
<data name="ApplicationHasTelemetry3" xml:space="preserve">
<value>To disable telemetry run '{0}'.</value>
</data>
<data name="DumpingDataFromDatabase" xml:space="preserve">
<value>Dumping data from database located at {0}.</value>
</data>
<data name="NoCollectRuns" xml:space="preserve">
<value>There were no collect runs in the database.</value>
</data>
<data name="NoMonitorRuns" xml:space="preserve">
<value>There were no monitor runs in the database.</value>
</data>
<data name="FirstRunListRunsError" xml:space="preserve">
<value>This appears to be the first run with database {0}. There are no runs to list.</value>
</data>
</root>
17 changes: 14 additions & 3 deletions Lib/Utils/DatabaseManager.cs
Expand Up @@ -23,7 +23,6 @@ public static class DatabaseManager
private static readonly string SQL_CREATE_REGISTRY_COLLECTION = "create table if not exists registry (run_id text, row_key text, key text, value text, subkeys text, permissions text, serialized text)";
private static readonly string SQL_CREATE_CERTIFICATES_COLLECTION = "create table if not exists certificates (run_id text, row_key text, pkcs12 text, store_location text, store_name text, hash text, hash_plus_store text, cert text, cn text, serialized text)";


private static readonly string SQL_CREATE_ANALYZED_TABLE = "create table if not exists results (base_run_id text, compare_run_id text, status int)";

private static readonly string SQL_CREATE_FILE_SYSTEM_INDEX = "create index if not exists path_index on file_system(path)";
Expand Down Expand Up @@ -65,7 +64,9 @@ public static class DatabaseManager

private static SqliteTransaction _transaction;

public static void Setup()
private static bool _firstRun = true;

public static bool Setup()
{
if (Connection == null)
{
Expand Down Expand Up @@ -109,7 +110,10 @@ public static void Setup()

cmd.CommandText = SQL_CREATE_DEFAULT_SETTINGS;
cmd.Parameters.AddWithValue("@schema_version", SCHEMA_VERSION);
cmd.ExecuteNonQuery();
if(cmd.ExecuteNonQuery() == 0)
{
_firstRun = false;
}

cmd.CommandText = SQL_CREATE_FILE_SYSTEM_INDEX;
cmd.ExecuteNonQuery();
Expand Down Expand Up @@ -142,7 +146,14 @@ public static void Setup()
DatabaseManager.Transaction.Commit();
_transaction = null;
Log.Debug("Done with database setup");
return true;
}
return false;
}

public static bool IsFirstRun()
{
return _firstRun;
}

public static void VerifySchemaVersion()
Expand Down

0 comments on commit b130802

Please sign in to comment.