summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-01-21 02:56:53 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-01-21 02:56:53 +0100
commit6443695f275167adb123070daf2a6b6ecc0bb371 (patch)
treee55e9cb7795f3a5fb239793eab60f2320fe11cbc /src
parentf1322558475277ffed7a9c61f4b9478b4dd1d46c (diff)
downloadabrt-6443695f275167adb123070daf2a6b6ecc0bb371.tar.gz
abrt-6443695f275167adb123070daf2a6b6ecc0bb371.tar.xz
abrt-6443695f275167adb123070daf2a6b6ecc0bb371.zip
abrtd: fix Report() dbus call gaping security holes
We were blindly trusting the values passed to us Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r--src/CLI/CLI.cpp8
-rw-r--r--src/CLI/report.cpp12
-rw-r--r--src/Daemon/CommLayerServerDBus.cpp7
-rw-r--r--src/Daemon/CommLayerServerSocket.cpp3
-rw-r--r--src/Daemon/CrashWatcher.cpp13
-rw-r--r--src/Daemon/CrashWatcher.h2
-rw-r--r--src/Daemon/Daemon.cpp12
-rw-r--r--src/Daemon/MiddleWare.cpp231
-rw-r--r--src/Gui/CCDump.py61
-rw-r--r--src/Gui/CCReporterDialog.py154
10 files changed, 250 insertions, 253 deletions
diff --git a/src/CLI/CLI.cpp b/src/CLI/CLI.cpp
index 5b96d7cb..a8786e99 100644
--- a/src/CLI/CLI.cpp
+++ b/src/CLI/CLI.cpp
@@ -55,7 +55,7 @@ static void print_crash_infos(vector_map_crash_data_t& pCrashInfos, int pMode)
map_crash_data_t& info = pCrashInfos[ii];
if (pMode == OPT_GET_LIST_FULL || get_crash_data_item_content(info, CD_REPORTED) != "1")
{
- const char *timestr = get_crash_data_item_content(info, CD_TIME).c_str();
+ const char *timestr = get_crash_data_item_content(info, FILENAME_TIME).c_str();
long time = strtol(timestr, NULL, 10);
if (time == 0)
error_msg_and_die("Error while converting time string.");
@@ -73,10 +73,10 @@ static void print_crash_infos(vector_map_crash_data_t& pCrashInfos, int pMode)
"\tCrash Time : %s\n"
"\tCrash Count: %s\n"),
ii,
- get_crash_data_item_content(info, CD_UID).c_str(),
+ get_crash_data_item_content(info, FILENAME_UID).c_str(),
get_crash_data_item_content(info, CD_UUID).c_str(),
- get_crash_data_item_content(info, CD_PACKAGE).c_str(),
- get_crash_data_item_content(info, CD_EXECUTABLE).c_str(),
+ get_crash_data_item_content(info, FILENAME_PACKAGE).c_str(),
+ get_crash_data_item_content(info, FILENAME_EXECUTABLE).c_str(),
timeloc,
get_crash_data_item_content(info, CD_COUNT).c_str()
);
diff --git a/src/CLI/report.cpp b/src/CLI/report.cpp
index 11037ca7..76cd3d5a 100644
--- a/src/CLI/report.cpp
+++ b/src/CLI/report.cpp
@@ -192,13 +192,13 @@ static void write_crash_report(const map_crash_data_t &report, FILE *fp)
fprintf(fp, "# Please check this report. Lines starting with '#' will be ignored.\n"
"# Lines starting with '%%----' separate fields, please do not delete them.\n\n");
- write_crash_report_field(fp, report, CD_COMMENT,
+ write_crash_report_field(fp, report, FILENAME_COMMENT,
_("# Describe the circumstances of this crash below."));
- write_crash_report_field(fp, report, CD_REPRODUCE,
+ write_crash_report_field(fp, report, FILENAME_REPRODUCE,
_("# How to reproduce the crash?"));
write_crash_report_field(fp, report, FILENAME_BACKTRACE,
_("# Stack trace: a list of active stack frames at the time the crash occurred\n# Check that it does not contain any sensitive data such as passwords."));
- write_crash_report_field(fp, report, CD_UUID, _("# UUID"));
+ write_crash_report_field(fp, report, CD_DUPHASH, "# DUPHASH");
write_crash_report_field(fp, report, FILENAME_ARCHITECTURE, _("# Architecture"));
write_crash_report_field(fp, report, FILENAME_CMDLINE, _("# Command line"));
write_crash_report_field(fp, report, FILENAME_COMPONENT, _("# Component"));
@@ -282,10 +282,10 @@ static int read_crash_report_field(const char *text, map_crash_data_t &report,
static int read_crash_report(map_crash_data_t &report, const char *text)
{
int result = 0;
- result |= read_crash_report_field(text, report, CD_COMMENT);
- result |= read_crash_report_field(text, report, CD_REPRODUCE);
+ result |= read_crash_report_field(text, report, FILENAME_COMMENT);
+ result |= read_crash_report_field(text, report, FILENAME_REPRODUCE);
result |= read_crash_report_field(text, report, FILENAME_BACKTRACE);
- result |= read_crash_report_field(text, report, CD_UUID);
+ result |= read_crash_report_field(text, report, CD_DUPHASH);
result |= read_crash_report_field(text, report, FILENAME_ARCHITECTURE);
result |= read_crash_report_field(text, report, FILENAME_CMDLINE);
result |= read_crash_report_field(text, report, FILENAME_COMPONENT);
diff --git a/src/Daemon/CommLayerServerDBus.cpp b/src/Daemon/CommLayerServerDBus.cpp
index ddfbba49..f1f10e50 100644
--- a/src/Daemon/CommLayerServerDBus.cpp
+++ b/src/Daemon/CommLayerServerDBus.cpp
@@ -190,7 +190,8 @@ static int handle_CreateReport(DBusMessage* call, DBusMessage* reply)
}
long unix_uid = get_remote_uid(call);
- map_crash_data_t report = CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0);
+ map_crash_data_t report;
+ CreateReport(pUUID, to_string(unix_uid).c_str(), /*force:*/ 0, report);
DBusMessageIter out_iter;
dbus_message_iter_init_append(reply, &out_iter);
@@ -214,9 +215,9 @@ static int handle_Report(DBusMessage* call, DBusMessage* reply)
return -1;
}
- map_crash_data_t::const_iterator it_comment = argin1.find(CD_COMMENT);
+ map_crash_data_t::const_iterator it_comment = argin1.find(FILENAME_COMMENT);
const char* comment = (it_comment != argin1.end()) ? it_comment->second[CD_CONTENT].c_str() : "";
- map_crash_data_t::const_iterator it_reproduce = argin1.find(CD_REPRODUCE);
+ map_crash_data_t::const_iterator it_reproduce = argin1.find(FILENAME_REPRODUCE);
const char* reproduce = (it_reproduce != argin1.end()) ? it_reproduce->second[CD_CONTENT].c_str() : "";
const char* errmsg = NULL;
if (strlen(comment) > LIMIT_MESSAGE)
diff --git a/src/Daemon/CommLayerServerSocket.cpp b/src/Daemon/CommLayerServerSocket.cpp
index b54f9a6e..ab880fb2 100644
--- a/src/Daemon/CommLayerServerSocket.cpp
+++ b/src/Daemon/CommLayerServerSocket.cpp
@@ -145,7 +145,8 @@ void CCommLayerServerSocket::ProcessMessage(const std::string& pMessage, GIOChan
else if (!strncmp(pMessage.c_str(), MESSAGE_CREATE_REPORT, sizeof(MESSAGE_CREATE_REPORT) - 1))
{
// std::string UUID = pMessage.substr(sizeof(MESSAGE_CREATE_REPORT) - 1);
-// map_crash_data_t crashReport = CreateReport(UUID, UID);
+// map_crash_data_t crashReport;
+// CreateReport(UUID, UID, crashReport);
//use CreateReportThread instead of CreateReport?
// std::string message = MESSAGE_CREATE_REPORT + crash_report_to_string(crashReport);
// Send(message, pSource);
diff --git a/src/Daemon/CrashWatcher.cpp b/src/Daemon/CrashWatcher.cpp
index 80d8cd47..93365f3b 100644
--- a/src/Daemon/CrashWatcher.cpp
+++ b/src/Daemon/CrashWatcher.cpp
@@ -57,12 +57,11 @@ vector_map_crash_data_t GetCrashInfos(const char *pUID)
unsigned int ii;
for (ii = 0; ii < UUIDsUIDs.size(); ii++)
{
- mw_result_t res;
- map_crash_data_t info;
const char *uuid = UUIDsUIDs[ii].first.c_str();
const char *uid = UUIDsUIDs[ii].second.c_str();
- res = FillCrashInfo(uuid, uid, info);
+ map_crash_data_t info;
+ mw_result_t res = FillCrashInfo(uuid, uid, info);
switch (res)
{
case MW_OK:
@@ -96,18 +95,18 @@ vector_map_crash_data_t GetCrashInfos(const char *pUID)
* StartJob dbus call already did all the processing, and we just retrieve
* the result from dump directory, which is fast.
*/
-map_crash_data_t CreateReport(const char* pUUID, const char* pUID, int force)
+void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t& crashReport)
{
/* FIXME: starting from here, any shared data must be protected with a mutex.
* For example, CreateCrashReport does:
* g_pPluginManager->GetDatabase(g_settings_sDatabase.c_str());
* which is unsafe wrt concurrent updates to g_pPluginManager state.
*/
- map_crash_data_t crashReport;
mw_result_t res = CreateCrashReport(pUUID, pUID, force, crashReport);
switch (res)
{
case MW_OK:
+ VERB2 log_map_crash_data(crashReport, "crashReport");
break;
case MW_IN_DB_ERROR:
error_msg("Can't find crash with UUID %s in database", pUUID);
@@ -120,7 +119,6 @@ map_crash_data_t CreateReport(const char* pUUID, const char* pUID, int force)
DeleteDebugDump(pUUID, pUID);
break;
}
- return crashReport;
}
typedef struct thread_data_t {
@@ -140,7 +138,8 @@ static void* create_report(void* arg)
try
{
log("Creating report...");
- map_crash_data_t crashReport = CreateReport(thread_data->UUID, thread_data->UID, thread_data->force);
+ map_crash_data_t crashReport;
+ CreateReport(thread_data->UUID, thread_data->UID, thread_data->force, crashReport);
g_pCommLayer->JobDone(thread_data->peer, thread_data->UUID);
}
catch (CABRTException& e)
diff --git a/src/Daemon/CrashWatcher.h b/src/Daemon/CrashWatcher.h
index 1e672b96..31b72e08 100644
--- a/src/Daemon/CrashWatcher.h
+++ b/src/Daemon/CrashWatcher.h
@@ -50,7 +50,7 @@ class CCrashWatcher
vector_map_crash_data_t GetCrashInfos(const char *pUID);
int CreateReportThread(const char* pUUID, const char* pUID, int force, const char* pSender);
-map_crash_data_t CreateReport(const char* pUUID, const char* pUID, int force);
+void CreateReport(const char* pUUID, const char* pUID, int force, map_crash_data_t&);
int DeleteDebugDump(const char *pUUID, const char *pUID);
void DeleteDebugDump_by_dir(const char *dump_dir);
diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp
index 829b2a76..83b1ceef 100644
--- a/src/Daemon/Daemon.cpp
+++ b/src/Daemon/Daemon.cpp
@@ -328,7 +328,7 @@ static void FindNewDumps(const char* pPath)
{
case MW_OK:
VERB1 log("Saving %s into database", itt->c_str());
- RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_MWDDD).c_str());
+ RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str());
break;
case MW_IN_DB:
VERB1 log("%s is already saved in database", itt->c_str());
@@ -479,14 +479,14 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
try
{
std::string fullname = concat_path_file(DEBUG_DUMPS_DIR, name);
- map_crash_data_t crashinfo;
//todo: rename SaveDebugDump to ???? it does not save crashinfo, it FETCHES crashinfo
+ map_crash_data_t crashinfo;
mw_result_t res = SaveDebugDump(fullname.c_str(), crashinfo);
switch (res)
{
case MW_OK:
log("New crash, saving");
- RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_MWDDD).c_str());
+ RunActionsAndReporters(get_crash_data_item_content(crashinfo, CD_DUMPDIR).c_str());
/* Fall through */
case MW_REPORTED:
case MW_OCCURED:
@@ -494,8 +494,8 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
if (res != MW_OK)
log("Already saved crash, just sending dbus signal");
- const char *analyzer = get_crash_data_item_content(crashinfo, CD_MWANALYZER).c_str();
- const char *uid_str = get_crash_data_item_content(crashinfo, CD_UID).c_str();
+ const char *analyzer = get_crash_data_item_content(crashinfo, FILENAME_ANALYZER).c_str();
+ const char *uid_str = get_crash_data_item_content(crashinfo, FILENAME_UID).c_str();
/* Autoreport it if configured to do so */
if (analyzer_has_AutoReportUIDs(analyzer, uid_str))
@@ -525,7 +525,7 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpoin
/* Send dbus signal */
if (analyzer_has_InformAllUsers(analyzer))
uid_str = NULL;
- g_pCommLayer->Crash(get_crash_data_item_content(crashinfo, CD_PACKAGE).c_str(), uid_str);
+ g_pCommLayer->Crash(get_crash_data_item_content(crashinfo, FILENAME_PACKAGE).c_str(), uid_str);
break;
}
case MW_BLACKLISTED:
diff --git a/src/Daemon/MiddleWare.cpp b/src/Daemon/MiddleWare.cpp
index 9ca492de..ecf3c13a 100644
--- a/src/Daemon/MiddleWare.cpp
+++ b/src/Daemon/MiddleWare.cpp
@@ -148,37 +148,12 @@ static void load_crash_data_from_debug_dump(CDebugDump& dd, map_crash_data_t& da
dd.LoadText(short_name.c_str(), content);
free(text);
- if (short_name == FILENAME_ARCHITECTURE
- || short_name == FILENAME_KERNEL
- || short_name == FILENAME_PACKAGE
- || short_name == FILENAME_COMPONENT
- || short_name == FILENAME_RELEASE
- || short_name == FILENAME_EXECUTABLE
- ) {
- add_to_crash_data_ext(data,
- short_name.c_str(),
- CD_TXT,
- CD_ISNOTEDITABLE,
- content.c_str()
- );
- continue;
- }
-
- if (short_name != FILENAME_UID
- && short_name != FILENAME_ANALYZER
- && short_name != FILENAME_TIME
- && short_name != FILENAME_DESCRIPTION
- && short_name != FILENAME_REPRODUCE
- && short_name != FILENAME_COMMENT
- ) {
- add_to_crash_data_ext(
- data,
- short_name.c_str(),
- CD_TXT,
- CD_ISEDITABLE,
- content.c_str()
- );
- }
+ add_to_crash_data_ext(data,
+ short_name.c_str(),
+ CD_TXT,
+ is_editable_file(short_name.c_str()) ? CD_ISEDITABLE : CD_ISNOTEDITABLE,
+ content.c_str()
+ );
}
}
@@ -190,16 +165,19 @@ static void load_crash_data_from_debug_dump(CDebugDump& dd, map_crash_data_t& da
*/
static void DebugDumpToCrashReport(const char *pDebugDumpDir, map_crash_data_t& pCrashData)
{
+ VERB3 log(" DebugDumpToCrashReport('%s')", pDebugDumpDir);
+
CDebugDump dd;
dd.Open(pDebugDumpDir);
- if (!dd.Exist(FILENAME_ARCHITECTURE)
- || !dd.Exist(FILENAME_KERNEL)
- || !dd.Exist(FILENAME_PACKAGE)
- || !dd.Exist(FILENAME_COMPONENT)
- || !dd.Exist(FILENAME_RELEASE)
- || !dd.Exist(FILENAME_EXECUTABLE)
- ) {
- throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): One or more of important file(s) are missing");
+
+ const char *const *v = must_have_files;
+ while (*v)
+ {
+ if (!dd.Exist(*v))
+ {
+ throw CABRTException(EXCEP_ERROR, "DebugDumpToCrashReport(): important file '%s' is missing", *v);
+ }
+ v++;
}
load_crash_data_from_debug_dump(dd, pCrashData);
@@ -245,7 +223,7 @@ static std::string GetGlobalUUID(const char *pAnalyzer,
* @param pAnalyzer A name of an analyzer plugin.
* @param pDebugDumpPath A debugdump dir containing all necessary data.
*/
-static void CreateReport(const char *pAnalyzer,
+static void run_analyser_CreateReport(const char *pAnalyzer,
const char *pDebugDumpDir,
int force)
{
@@ -278,6 +256,7 @@ mw_result_t CreateCrashReport(const char *pUUID,
return MW_IN_DB_ERROR;
}
+ mw_result_t r = MW_OK;
try
{
CDebugDump dd;
@@ -296,45 +275,42 @@ mw_result_t CreateCrashReport(const char *pUUID,
{
dd.LoadText(FILENAME_REPRODUCE, reproduce);
}
+ load_crash_data_from_debug_dump(dd, pCrashData);
dd.Close();
VERB3 log(" CreateReport('%s')", analyzer.c_str());
- CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force);
+ run_analyser_CreateReport(analyzer.c_str(), row.m_sDebugDumpDir.c_str(), force);
std::string gUUID = GetGlobalUUID(analyzer.c_str(), row.m_sDebugDumpDir.c_str());
VERB3 log(" GetGlobalUUID:'%s'", gUUID.c_str());
VERB3 log(" RunAnalyzerActions('%s','%s')", analyzer.c_str(), row.m_sDebugDumpDir.c_str());
RunAnalyzerActions(analyzer.c_str(), row.m_sDebugDumpDir.c_str());
- VERB3 log(" DebugDumpToCrashReport");
DebugDumpToCrashReport(row.m_sDebugDumpDir.c_str(), pCrashData);
- add_to_crash_data_ext(pCrashData, CD_UUID , CD_TXT, CD_ISNOTEDITABLE, gUUID.c_str() );
- add_to_crash_data_ext(pCrashData, CD_MWANALYZER, CD_SYS, CD_ISNOTEDITABLE, analyzer.c_str() );
- add_to_crash_data_ext(pCrashData, CD_MWUID , CD_SYS, CD_ISNOTEDITABLE, pUID );
- add_to_crash_data_ext(pCrashData, CD_MWUUID , CD_SYS, CD_ISNOTEDITABLE, pUUID );
- add_to_crash_data_ext(pCrashData, CD_COMMENT , CD_TXT, CD_ISEDITABLE , comment.c_str() );
- add_to_crash_data_ext(pCrashData, CD_REPRODUCE , CD_TXT, CD_ISEDITABLE , reproduce.c_str());
+ add_to_crash_data_ext(pCrashData, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, gUUID.c_str());
+ add_to_crash_data_ext(pCrashData, CD_UUID , CD_SYS, CD_ISNOTEDITABLE, pUUID);
}
catch (CABRTException& e)
{
+ r = MW_CORRUPTED;
error_msg("%s", e.what());
if (e.type() == EXCEP_DD_OPEN)
{
- return MW_ERROR;
+ r = MW_ERROR;
}
- if (e.type() == EXCEP_DD_LOAD)
+ else if (e.type() == EXCEP_DD_LOAD)
{
- return MW_FILE_ERROR;
+ r = MW_FILE_ERROR;
}
- if (e.type() == EXCEP_PLUGIN)
+ else if (e.type() == EXCEP_PLUGIN)
{
- return MW_PLUGIN_ERROR;
+ r = MW_PLUGIN_ERROR;
}
- return MW_CORRUPTED;
}
- return MW_OK;
+ VERB3 log("CreateCrashReport() returns %d", r);
+ return r;
}
void RunAction(const char *pActionDir,
@@ -391,88 +367,74 @@ void RunActionsAndReporters(const char *pDebugDumpDir)
}
-static bool CheckReport(const map_crash_data_t& pCrashData)
-{
- map_crash_data_t::const_iterator it_analyzer = pCrashData.find(CD_MWANALYZER);
- map_crash_data_t::const_iterator it_mwuid = pCrashData.find(CD_MWUID);
- map_crash_data_t::const_iterator it_mwuuid = pCrashData.find(CD_MWUUID);
-
- map_crash_data_t::const_iterator it_package = pCrashData.find(FILENAME_PACKAGE);
- map_crash_data_t::const_iterator it_architecture = pCrashData.find(FILENAME_ARCHITECTURE);
- map_crash_data_t::const_iterator it_kernel = pCrashData.find(FILENAME_KERNEL);
- map_crash_data_t::const_iterator it_component = pCrashData.find(FILENAME_COMPONENT);
- map_crash_data_t::const_iterator it_release = pCrashData.find(FILENAME_RELEASE);
- map_crash_data_t::const_iterator it_executable = pCrashData.find(FILENAME_EXECUTABLE);
-
- map_crash_data_t::const_iterator end = pCrashData.end();
-
- if (it_package == end)
- {
- return false;
- }
-
- // FIXME: bypass the test if it's kerneloops
- if (it_package->second[CD_CONTENT] == "kernel")
- return true;
-
- if (it_analyzer == end || it_mwuid == end ||
- it_mwuuid == end || /* it_package == end || */
- it_architecture == end || it_kernel == end ||
- it_component == end || it_release == end ||
- it_executable == end)
- {
- return false;
- }
-
- if (it_analyzer->second[CD_CONTENT] == "" || it_mwuid->second[CD_CONTENT] == "" ||
- it_mwuuid->second[CD_CONTENT] == "" || it_package->second[CD_CONTENT] == "" ||
- it_architecture->second[CD_CONTENT] == "" || it_kernel->second[CD_CONTENT] == "" ||
- it_component->second[CD_CONTENT] == "" || it_release->second[CD_CONTENT] == "" ||
- it_executable->second[CD_CONTENT] == "")
- {
- return false;
- }
-
- return true;
-}
-
-report_status_t Report(const map_crash_data_t& pCrashData,
+// We must not trust client_report here!
+// dbus handler passes it from user without checking
+report_status_t Report(const map_crash_data_t& client_report,
map_map_string_t& pSettings,
const char *pUID)
{
- report_status_t ret;
-
- /* dbus handler passes pCrashData from user without checking it */
+ map_crash_data_t::const_iterator itc_end = client_report.end();
- if (!CheckReport(pCrashData))
- {
- throw CABRTException(EXCEP_ERROR, "Report(): Some of mandatory report data are missing.");
+ // Get ID fields
+ map_crash_data_t::const_iterator itc_UID = client_report.find(FILENAME_UID);
+ map_crash_data_t::const_iterator itc_UUID = client_report.find(CD_UUID);
+ if (itc_UID == itc_end /* || !exists itc_UID->second[CD_CONTENT] (TODO) */
+ || itc_UUID == itc_end
+ ) {
+ throw CABRTException(EXCEP_ERROR, "Report(): UID or UUID is missing in client's report data");
}
- const std::string& analyzer = get_crash_data_item_content(pCrashData, CD_MWANALYZER);
- const std::string& UID = get_crash_data_item_content(pCrashData, CD_MWUID);
- const std::string& UUID = get_crash_data_item_content(pCrashData, CD_MWUUID);
- const std::string& packageNVR = get_crash_data_item_content(pCrashData, FILENAME_PACKAGE);
- std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1));
+ // Retrieve corresponding stored record
+ std::string UID = itc_UID->second[CD_CONTENT];
+ std::string UUID = itc_UUID->second[CD_CONTENT];
+
+ map_crash_data_t stored_report;
+ mw_result_t r = FillCrashInfo(UUID.c_str(), UID.c_str(), stored_report);
+ if (r != MW_OK)
+ return report_status_t();
+ const std::string& pDumpDir = get_crash_data_item_content(stored_report, CD_DUMPDIR);
// Save comment and "how to reproduce"
- map_crash_data_t::const_iterator it_comment = pCrashData.find(CD_COMMENT);
- map_crash_data_t::const_iterator it_reproduce = pCrashData.find(CD_REPRODUCE);
- if (it_comment != pCrashData.end() || it_reproduce != pCrashData.end())
+ map_crash_data_t::const_iterator itc_COMMENT = client_report.find(FILENAME_COMMENT);
+ map_crash_data_t::const_iterator itc_REPRODUCE = client_report.find(FILENAME_REPRODUCE);
+ if (itc_COMMENT != itc_end || itc_REPRODUCE != itc_end)
{
- std::string pDumpDir = getDebugDumpDir(UUID.c_str(), UID.c_str());
CDebugDump dd;
dd.Open(pDumpDir.c_str());
- if (it_comment != pCrashData.end())
+ if (itc_COMMENT != itc_end && itc_COMMENT->second.size() > CD_CONTENT)
{
- dd.SaveText(FILENAME_COMMENT, it_comment->second[CD_CONTENT].c_str());
+ const char *comment = itc_COMMENT->second[CD_CONTENT].c_str();
+ dd.SaveText(FILENAME_COMMENT, comment);
+ add_to_crash_data_ext(stored_report, FILENAME_COMMENT, CD_TXT, CD_ISEDITABLE, comment);
}
- if (it_reproduce != pCrashData.end())
+ if (itc_REPRODUCE != itc_end && itc_REPRODUCE->second.size() > CD_CONTENT)
{
- dd.SaveText(FILENAME_REPRODUCE, it_reproduce->second[CD_CONTENT].c_str());
+ const char *reproduce = itc_REPRODUCE->second[CD_CONTENT].c_str();
+ dd.SaveText(FILENAME_REPRODUCE, reproduce);
+ add_to_crash_data_ext(stored_report, FILENAME_REPRODUCE, CD_TXT, CD_ISEDITABLE, reproduce);
}
}
+ map_crash_data_t::const_iterator its_ANALYZER = stored_report.find(FILENAME_ANALYZER);
+ std::string analyzer = its_ANALYZER->second[CD_CONTENT];
+
+ std::string gUUID = GetGlobalUUID(analyzer.c_str(), pDumpDir.c_str());
+ VERB3 log(" GetGlobalUUID:'%s'", gUUID.c_str());
+ add_to_crash_data_ext(stored_report, CD_DUPHASH, CD_TXT, CD_ISNOTEDITABLE, gUUID.c_str());
+
+ // Run reporters
+
+ VERB3 {
+ log("Run reporters");
+ log_map_crash_data(client_report, " client_report");
+ log_map_crash_data(stored_report, " stored_report");
+ }
+#define client_report client_report_must_not_be_used_below
+
+ map_crash_data_t::const_iterator its_PACKAGE = stored_report.find(FILENAME_PACKAGE);
+ std::string packageNVR = its_PACKAGE->second[CD_CONTENT];
+ std::string packageName = packageNVR.substr(0, packageNVR.rfind("-", packageNVR.rfind("-") - 1));
+
// analyzer with package name (CCpp:xorg-x11-app) has higher priority
std::string key = analyzer + ":" + packageName;
map_analyzer_actions_and_reporters_t::iterator end = s_mapAnalyzerActionsAndReporters.end();
@@ -484,6 +446,7 @@ report_status_t Report(const map_crash_data_t& pCrashData,
key = analyzer;
}
+ report_status_t ret;
std::string message;
if (keyPtr != end)
{
@@ -518,7 +481,7 @@ report_status_t Report(const map_crash_data_t& pCrashData,
}
#endif
map_plugin_settings_t plugin_settings = pSettings[plugin_name];
- std::string res = reporter->Report(pCrashData, plugin_settings, it_r->second.c_str());
+ std::string res = reporter->Report(stored_report, plugin_settings, it_r->second.c_str());
#if 0 /* Using ~user/.abrt/ is bad wrt security */
if (home != "")
@@ -548,6 +511,7 @@ report_status_t Report(const map_crash_data_t& pCrashData,
database->DisConnect();
return ret;
+#undef client_report
}
/**
@@ -935,10 +899,7 @@ mw_result_t FillCrashInfo(const char *pUUID,
{
CDebugDump dd;
dd.Open(row.m_sDebugDumpDir.c_str());
- dd.LoadText(FILENAME_EXECUTABLE, executable);
- dd.LoadText(FILENAME_PACKAGE, package);
- dd.LoadText(FILENAME_DESCRIPTION, description);
- dd.LoadText(FILENAME_ANALYZER, analyzer);
+ load_crash_data_from_debug_dump(dd, pCrashData);
}
catch (CABRTException& e)
{
@@ -946,18 +907,14 @@ mw_result_t FillCrashInfo(const char *pUUID,
return MW_ERROR;
}
- pCrashData.clear();
- add_to_crash_data(pCrashData, CD_EXECUTABLE , executable.c_str() );
- add_to_crash_data(pCrashData, CD_PACKAGE , package.c_str() );
- add_to_crash_data(pCrashData, CD_DESCRIPTION, description.c_str() );
- add_to_crash_data(pCrashData, CD_UUID , row.m_sUUID.c_str() );
- add_to_crash_data(pCrashData, CD_UID , row.m_sUID.c_str() );
- add_to_crash_data(pCrashData, CD_COUNT , row.m_sCount.c_str() );
- add_to_crash_data(pCrashData, CD_TIME , row.m_sTime.c_str() );
- add_to_crash_data(pCrashData, CD_REPORTED , row.m_sReported.c_str() );
- add_to_crash_data(pCrashData, CD_MESSAGE , row.m_sMessage.c_str() );
- add_to_crash_data(pCrashData, CD_MWDDD , row.m_sDebugDumpDir.c_str());
- add_to_crash_data(pCrashData, CD_MWANALYZER , analyzer.c_str() );
+ add_to_crash_data(pCrashData, CD_UUID , row.m_sUUID.c_str() );
+ add_to_crash_data(pCrashData, CD_COUNT , row.m_sCount.c_str() );
+ add_to_crash_data(pCrashData, CD_REPORTED , row.m_sReported.c_str() );
+ add_to_crash_data(pCrashData, CD_MESSAGE , row.m_sMessage.c_str() );
+ add_to_crash_data(pCrashData, CD_DUMPDIR , row.m_sDebugDumpDir.c_str());
+//TODO: why do we keep uid and time in DB and in dumpdir?!
+ add_to_crash_data(pCrashData, FILENAME_UID , row.m_sUID.c_str() );
+ add_to_crash_data(pCrashData, FILENAME_TIME , row.m_sTime.c_str() );
return MW_OK;
}
diff --git a/src/Gui/CCDump.py b/src/Gui/CCDump.py
index 96d036c4..1f290929 100644
--- a/src/Gui/CCDump.py
+++ b/src/Gui/CCDump.py
@@ -3,20 +3,55 @@ from datetime import datetime
from abrt_utils import _, init_logging, log, log1, log2
+# Should match CrashTypes.h!
CD_TYPE = 0
CD_EDITABLE = 1
CD_CONTENT = 2
+CD_SYS = "s"
+CD_BIN = "b"
+CD_TXT = "t"
+
+FILENAME_ARCHITECTURE = "architecture"
+FILENAME_KERNEL = "kernel"
+FILENAME_TIME = "time"
+FILENAME_UID = "uid"
+FILENAME_PACKAGE = "package"
+FILENAME_COMPONENT = "component"
+FILENAME_DESCRIPTION = "description"
+FILENAME_ANALYZER = "analyzer"
+FILENAME_RELEASE = "release"
+FILENAME_EXECUTABLE = "executable"
+FILENAME_REASON = "reason"
+FILENAME_COMMENT = "comment"
+FILENAME_REPRODUCE = "reproduce"
+FILENAME_RATING = "rating"
+FILENAME_CMDLINE = "cmdline"
+FILENAME_COREDUMP = "coredump"
+FILENAME_BACKTRACE = "backtrace"
+FILENAME_MEMORYMAP = "memorymap"
+FILENAME_KERNELOOPS = "kerneloops"
+
+CD_DUPHASH = "DUPHASH"
+CD_UUID = "UUID"
+CD_DUMPDIR = "DumpDir"
+CD_COUNT = "Count"
+CD_REPORTED = "Reported"
+CD_MESSAGE = "Message"
+
+# FIXME - create method or smth that returns type|editable|content
+
+
class Dump():
"""Class for mapping the debug dump to python object"""
def __init__(self):
self.UUID = None
- self.UID = None
+ self.uid = None
self.Count = None
- self.Executable = None
- self.Package = None
- self.Time = None
- self.Description = None
+ self.executable = None
+ self.package = None
+ self.time = None
+ self.description = None
self.Message = None
self.Reported = None
@@ -24,16 +59,16 @@ class Dump():
return self.UUID[CD_CONTENT]
def getUID(self):
- return self.UID[CD_CONTENT]
+ return self.uid[CD_CONTENT]
def getCount(self):
return self.Count[CD_CONTENT]
def getExecutable(self):
- return self.Executable[CD_CONTENT]
+ return self.executable[CD_CONTENT]
def getPackage(self):
- return self.Package[CD_CONTENT]
+ return self.package[CD_CONTENT]
def isReported(self):
return self.Reported[CD_CONTENT] == "1"
@@ -44,17 +79,17 @@ class Dump():
#return self.Message[CD_CONTENT].split('\n')
return self.Message[CD_CONTENT]
- def getTime(self,format):
+ def getTime(self, format):
#print format
if format:
try:
- return datetime.fromtimestamp(int(self.Time[CD_CONTENT])).strftime(format)
+ return datetime.fromtimestamp(int(self.time[CD_CONTENT])).strftime(format)
except Exception, e:
print e
- return int(self.Time[CD_CONTENT])
+ return int(self.time[CD_CONTENT])
def getPackageName(self):
- return self.Package[CD_CONTENT][:self.Package[CD_CONTENT].find("-")]
+ return self.package[CD_CONTENT][:self.package[CD_CONTENT].find("-")]
def getDescription(self):
- return self.Description[CD_CONTENT]
+ return self.description[CD_CONTENT]
diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py
index d24c0dd8..f46c180f 100644
--- a/src/Gui/CCReporterDialog.py
+++ b/src/Gui/CCReporterDialog.py
@@ -11,16 +11,10 @@ from ABRTPlugin import PluginInfo
from PluginSettingsUI import PluginSettingsUI
from PluginList import getPluginInfoList
#from CCDumpList import getDumpList, DumpList
+from CCDump import * # FILENAME_xxx, CD_xxx
from abrt_utils import _, log, log1, log2
# FIXME - create method or smth that returns type|editable|content
-CD_TYPE = 0
-CD_EDITABLE = 1
-CD_CONTENT = 2
-
-CD_SYS = "s"
-CD_BIN = "b"
-CD_TXT = "t"
# response
REFRESH = -50
@@ -34,7 +28,7 @@ class ReporterDialog():
self.report = report
#Set the Glade file
# FIXME add to path
- builderfile = "%s%sreport.glade" % (sys.path[0],"/")
+ builderfile = "%s/report.glade" % sys.path[0]
self.builder = gtk.Builder()
self.builder.add_from_file(builderfile)
#Get the Main Window, and connect the "destroy" event
@@ -47,21 +41,20 @@ class ReporterDialog():
# comment textview
self.tvComment = self.builder.get_object("tvComment")
self.tvComment.connect("focus-in-event", self.on_comment_focus_cb)
- self.comment_changed = False
+ self.show_hint_comment = 1
# "how to reproduce" textview
self.tevHowToReproduce = self.builder.get_object("tevHowToReproduce")
- self.how_to_changed = False
self.builder.get_object("fErrors").hide()
self.builder.get_object("bLog").connect("clicked", self.show_log_cb, log)
self.builder.get_object("cbSendBacktrace").connect("toggled", self.on_send_backtrace_toggled)
self.allow_send()
self.hydrate()
-
+
def check_backtrace(self):
print "checking backtrace"
-
+
def warn_user(self, warnings):
# FIXME: show in lError
fErrors = self.builder.get_object("fErrors")
@@ -74,12 +67,12 @@ class ReporterDialog():
warning_lbl = "* %s" % warning
lErrors.set_label(warning_lbl)
fErrors.show_all()
-
+
def hide_warning(self):
fErrors = self.builder.get_object("fErrors")
lErrors = self.builder.get_object("lErrors")
fErrors.hide()
-
+
def allow_send(self):
self.hide_warning()
bSend = self.builder.get_object("bSend")
@@ -87,7 +80,7 @@ class ReporterDialog():
send = True
error_msgs = []
try:
- rating = self.report["rating"]
+ rating = self.report[FILENAME_RATING]
except:
rating = None
# active buttons acording to required fields
@@ -98,29 +91,30 @@ class ReporterDialog():
# we have both SendBacktrace and rating
if rating:
try:
- package = self.report["package"][CD_CONTENT]
+ package = self.report[FILENAME_PACKAGE][CD_CONTENT]
# if we don't have package for some reason
except:
package = None
# not usable report
- if int(self.report["rating"][CD_CONTENT]) < 3:
+ if int(self.report[FILENAME_RATING][CD_CONTENT]) < 3:
if package:
error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: <b>debuginfo-install %s</b> \nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))]))
else:
error_msgs.append(_("The backtrace is unusable, you can't report this!"))
# probably usable 3
- elif int(self.report["rating"][CD_CONTENT]) < 4:
+ elif int(self.report[FILENAME_RATING][CD_CONTENT]) < 4:
error_msgs.append(_("The backtrace is incomplete, please make sure you provide good steps to reproduce."))
-
+
if error_msgs:
self.warn_user(error_msgs)
bSend.set_sensitive(send)
-
+
def on_send_backtrace_toggled(self, toggle_button):
self.allow_send()
-
+
def show_log_cb(self, widget, log):
show_log(log, parent=self.window)
+
# this callback is called when user press Cancel or Report button in Report dialog
def on_response(self, dialog, response_id, daemon):
# the button has been pressed (probably)
@@ -136,9 +130,10 @@ class ReporterDialog():
model[path][3] = not model[path][3]
def on_comment_focus_cb(self, widget, event):
- if not self.comment_changed:
+ if self.show_hint_comment:
+ # clear "hint" text by supplying a fresh, empty TextBuffer
widget.set_buffer(gtk.TextBuffer())
- self.comment_changed = True
+ self.show_hint_comment = 0
def on_config_plugin_clicked(self, button, plugin, image):
ui = PluginSettingsUI(plugin, parent=self.window)
@@ -204,66 +199,77 @@ class ReporterDialog():
if len(text) > label_widget.get_max_width_chars():
label_widget.set_tooltip_text(text)
label_widget.set_text(text)
-
+
def hydrate(self):
self.editable = []
+ self.old_comment = ""
+ self.old_how_to_reproduce = ""
for item in self.report:
- if item == "backtrace":
+ try:
+ log2("report[%s]:%s/%s/%s", item, self.report[item][0], self.report[item][1], self.report[item][2][0:20])
+ except:
+ pass
+
+ if item == FILENAME_BACKTRACE:
buff = gtk.TextBuffer()
tvBacktrace = self.builder.get_object("tvBacktrace")
buff.set_text(self.report[item][CD_CONTENT])
tvBacktrace.set_buffer(buff)
continue
- if item == "Comment":
- buff = gtk.TextBuffer()
- comment = _("Brief description how to reproduce this or what you did...")
+
+ if item == FILENAME_COMMENT:
try:
if self.report[item][CD_CONTENT]:
- comment = self.report[item][CD_CONTENT]
- self.comment_changed = True
+ self.old_comment = self.report[item][CD_CONTENT]
except Exception, e:
pass
-
- buff.set_text(comment)
-
- self.tvComment.set_buffer(buff)
continue
- if item == "How to reproduce":
- buff = gtk.TextBuffer()
- how_to_reproduce = _("")
+
+ if item == FILENAME_REPRODUCE:
try:
if self.report[item][CD_CONTENT]:
- how_to_reproduce = self.report[item][CD_CONTENT]
- self.how_to_changed = True
+ self.old_how_to_reproduce = self.report[item][CD_CONTENT]
except Exception, e:
pass
+ continue
- buff.set_text(how_to_reproduce)
+ if self.report[item][CD_TYPE] == CD_SYS:
+ continue
- self.tevHowToReproduce.set_buffer(buff)
+ # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4
+ # FIXME: handle editable fields
+ if self.report[item][CD_TYPE] == CD_BIN:
+ self.builder.get_object("fAttachment").show()
+ vbAttachments = self.builder.get_object("vbAttachments")
+ toggle = gtk.CheckButton(self.report[item][CD_CONTENT])
+ vbAttachments.pack_start(toggle)
+ # bind item to checkbox
+ toggle.item = item
+ toggle.show()
continue
- if self.report[item][CD_TYPE] != CD_SYS:
- # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4
- # FIXME: handle editable fields
- if self.report[item][CD_TYPE] == CD_BIN:
- self.builder.get_object("fAttachment").show()
- vbAttachments = self.builder.get_object("vbAttachments")
- toggle = gtk.CheckButton(self.report[item][CD_CONTENT])
- vbAttachments.pack_start(toggle)
- # bind item to checkbox
- toggle.item = item
- toggle.show()
- continue
- item_label = self.builder.get_object("l%s" % item)
- if item_label:
- self.set_label(item_label, self.report[item][CD_CONTENT])
- else:
- # no widget to show this item
- # probably some new item need to adjust the GUI!
- # FIXME: add some window+button to show all the info
- # in raw form (smth like the old report dialog)
- pass
+ # It must be CD_TXT field
+ item_label = self.builder.get_object("l%s" % item)
+ if item_label:
+ self.set_label(item_label, self.report[item][CD_CONTENT])
+ else:
+ # no widget to show this item
+ # probably some new item need to adjust the GUI!
+ # FIXME: add some window+button to show all the info
+ # in raw form (smth like the old report dialog)
+ pass
+ #end for
+
+ buff = gtk.TextBuffer()
+ self.show_hint_comment = (self.old_comment == "")
+ if self.show_hint_comment:
+ buff.set_text(_("Brief description how to reproduce this or what you did..."))
+ else:
+ buff.set_text(self.old_comment)
+ self.tvComment.set_buffer(buff)
+ buff = gtk.TextBuffer()
+ buff.set_text(self.old_how_to_reproduce)
+ self.tevHowToReproduce.set_buffer(buff)
def dehydrate(self):
# handle attachments
@@ -271,23 +277,22 @@ class ReporterDialog():
for attachment in vbAttachments.get_children():
#print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label())
del self.report[attachment.item]
-
+
# handle comment
- if self.comment_changed:
- buff = self.tvComment.get_buffer()
- self.report["Comment"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())]
- else:
- del self.report["Comment"]
+ buff = self.tvComment.get_buffer()
+ text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+ if self.old_comment != text:
+ self.report[FILENAME_COMMENT] = [CD_TXT, 'y', text]
# handle how to reproduce
- if self.how_to_changed:
- buff = self.tevHowToReproduce.get_buffer()
- self.report["How to reproduce"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())]
- else:
- del self.report["How to reproduce"]
+ buff = self.tevHowToReproduce.get_buffer()
+ text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+ if self.old_how_to_reproduce != text:
+ self.report[FILENAME_REPRODUCE] = [CD_TXT, 'y', text]
#handle backtrace
tev_backtrace = self.builder.get_object("tvBacktrace")
buff = tev_backtrace.get_buffer()
- self.report["backtrace"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())]
+ text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+ self.report[FILENAME_BACKTRACE] = [CD_TXT, 'y', text]
def check_report(self):
# FIXME: check the report for passwords and some other potentially
@@ -299,4 +304,3 @@ class ReporterDialog():
result = self.window.run()
self.window.destroy()
return (result, self.report)
-