Beispiel #1
0
        private XmlDocument GetXmlReport(WatcherResultCollection resultslist)
        {
            XmlDocument    doc = new XmlDocument();
            XmlDeclaration xmlDec;
            XmlElement     root  = doc.DocumentElement;
            XmlElement     issue = null;
            XmlElement     level = null;
            XmlElement     url   = null;
            XmlElement     type  = null;
            XmlElement     desc  = null;

            // Get current Watcher version
            Version currentver = new UpdateManager().CurrentVersionEngine;

            // Create the very beginning Xml Declaration
            xmlDec = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            root   = doc.CreateElement("watcher");

            root.SetAttribute("version", currentver.ToString());
            root.SetAttribute("date", DateTime.Today.ToLongDateString());
            root.SetAttribute("originDomain", WatcherEngine.Configuration.OriginDomain.ToString());
            root.SetAttribute("trustedDomains", WatcherEngine.Configuration.GetTrustedDomainsAsString());
            root.SetAttribute("enabledChecks", WatcherEngine.CheckManager.GetEnabledChecksAsString());

            doc.AppendChild(root);

            doc.InsertBefore(xmlDec, root);

            foreach (WatcherResult item in resultslist)
            {
                WatcherEngine.ProgressDialog.labelOperation.Text = "Saving Finding: " + item.Title;
                WatcherEngine.ProgressDialog.UpdateProgress();

                issue = doc.CreateElement("issue");
                level = doc.CreateElement("level");

                level.InnerText = item.Severity.ToString();

                url = doc.CreateElement("url");

                url.InnerText = item.URL;

                type = doc.CreateElement("type");

                type.InnerText = item.Title;

                desc = doc.CreateElement("description");

                desc.InnerText = item.Description;

                issue.AppendChild(type);
                issue.AppendChild(level);
                issue.AppendChild(url);
                issue.AppendChild(desc);

                root.AppendChild(issue);
            }

            return(doc);
        }
        /// <summary>
        /// This method is the delegate called when an export is to be handled using a plugin.
        /// </summary>
        /// <returns>True if the operation succeeded, False otherwise.</returns>
        private void ExportResults(WatcherOutputPlugin plugin, WatcherResultCollection results, String filename)
        {
            // Perform the Save operation.  Not every save operation will return a
            // stream; therefore, a null return value is not necessarily an error.
            //
            // TODO: This class is a candidate for redesign as it handles exports with different semantics (e.g., TFS)
            Stream outputStream = plugin.SaveResult(results);

            if (outputStream != null)
            {
                using (FileStream fs = new FileStream(filename, FileMode.Create))
                {
                    Utility.ReadWriteStream(outputStream, fs);
                }
            }
        }
Beispiel #3
0
        public override Stream SaveResult(WatcherResultCollection resultslist)
        {
            // Reset the bar's progress position
            WatcherEngine.ProgressDialog.ProgressValue = 0;
            WatcherEngine.ProgressDialog.MaximumRange  = resultslist.Count;
            WatcherEngine.ProgressDialog.MinimumRange  = 0;
            WatcherEngine.ProgressDialog.Increment     = 1;
            WatcherEngine.ProgressDialog.BodyText      = "Exporting results to XML:";

            MemoryStream s   = new MemoryStream();
            XmlDocument  doc = GetXmlReport(resultslist);

            if (doc != null)
            {
                doc.Save(s);
                return(s);
            }

            return(null);
        }
        /// <summary>
        /// This is an event handler called when the user clicks the Export button.
        /// </summary>
        private void FileSaveButton_Click(object sender, EventArgs e)
        {
            // If no export method is selected, bail.
            if (cbExportMethod.SelectedItem == null)
            {
                MessageBox.Show("No export method selected.  Please select an export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Gather the selected results
            WatcherResultCollection selectedResults = new WatcherResultCollection();

            foreach (AlertListViewItem item in alertListView.Items)
            {
                WatcherResult result = new WatcherResult();
                result.Description = item.Description;
                result.Severity    = item.Severity;
                result.Title       = item.TypeX;
                result.URL         = item.URL;

                selectedResults.Add(result);
            }

            // The export method refers to an instance of the output plugin
            WatcherOutputPlugin outputPlugin = cbExportMethod.SelectedItem as WatcherOutputPlugin;

            if (outputPlugin == null)
            {
                Trace.TraceError("WatcherResultsControl: Invalid export method selected.");
                MessageBox.Show("Unable to use the selected export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            String filename = String.Empty;
            String filter   = String.Empty;

            // If this plugin is a file-based export, open a file save dialog and allow
            // the user to select the output filename.  Use the default values provided
            // by the plugin.
            //
            // TODO: Plugin should be interface-based or provide a property to tell whether it is a file-based export or not
            if (outputPlugin.GetExportDefaults(ref filename, ref filter))
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.FileName         = filename;
                dlg.Filter           = filter;
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                dlg.FilterIndex      = 1;
                dlg.RestoreDirectory = true;

                // Display the dialog, and if canceled, abort.
                if (dlg.ShowDialog() != DialogResult.OK)
                {
                    Trace.TraceInformation("User canceled export.");
                    return;
                }

                // Update the filename selected by the user
                filename = dlg.FileName;
            }

            // This is the export progress dialog shown during the export process

            // CHANGE - potentially breaking change, removing progress dialog
            // which seems to be dreadfully slowing down real work.
            WatcherEngine.ProgressDialog.Show();
            WatcherEngine.ProgressDialog.Title = "Export Data";

            // Perform the export asynchronously
            ExportResultsCallback callback = new ExportResultsCallback(ExportResults);

            callback.BeginInvoke(outputPlugin, selectedResults, filename,

                                 // This is the anonymous callback method
                                 delegate(IAsyncResult ar)
            {
                try
                {
                    // Tidy up after the export
                    ExportResultsCallback _callback = (ExportResultsCallback)ar.AsyncState;
                    _callback.EndInvoke(ar);     // NOTE: This will throw any unhandled exceptions that happened during the call
                }

                catch (WatcherException ex)
                {
                    Trace.TraceError("Exception: {0}", ex.Message);
                    if (ex.Data.Contains("UserAbortedOperation") == false)
                    {
                        // Only show a message box if the user hasn't already seen one (i.e., they've elected to abort the operation)
                        MessageBox.Show(this, String.Format("{0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    return;
                }

                finally
                {
                    // CHANGE - see above breaking change, removing progress dialog.
                    WatcherEngine.ProgressDialog.Hide();
                }

                MessageBox.Show(this, "Items successfully exported.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            },

                                 // Pass the callback as user data so we can call EndInvoke() when the operation completes
                                 // to retrieve the result.
                                 callback);
        }
Beispiel #5
0
        private XmlDocument GetHtmlReport(WatcherResultCollection resultslist)
        {
            doc = new XmlDocument();
            XmlDocumentType doctype;

            // The HTML element
            XmlElement root = doc.DocumentElement;
            // The HEAD element
            XmlElement head  = null;
            XmlElement title = null;
            // The meta tag element
            XmlElement meta = null;
            // The style element
            XmlElement style        = null;
            XmlElement script       = null;
            XmlElement toggleHidden = null;
            // The body element
            XmlElement          body       = null;
            XmlElement          level      = null;
            XmlElement          url        = null;
            XmlElement          typex      = null;
            XmlElement          desc       = doc.DocumentElement;
            XmlElement          divResults = doc.DocumentElement;
            XmlElement          divTOC     = doc.DocumentElement;
            XmlDocumentFragment metaIE     = null;

            string css = @" 
                            body {
                                font-family: 'Arial';
                                font-size: 12pt;
                            }
                            .issue {
                                margin-left: 30px;
                                display: block;
                            }
                            .type {
                                color: #FF0000;
                                font-size: 15pt;
                                display: block;
                            }
                            .level:before {
                                font-weight: bolder;
                                font-variant:small-caps;
                                content: 'severity: ';
                            }
                            .level {
                                display: block;
                            }
                            pre {
                                visibility: hidden;
                                display: none;
                            }
                            .description {
                                width: 80%;
                                margin-bottom: 30pt;
                                margin-left: 30pt;
                                white-space: pre; 
                            }
                            .toggler {
                                font-weight: normal;
                                font-style:italic;
                            }
                            .toggler:before {
                                font-style:normal;
                                font-weight: bolder;
                                font-variant:small-caps;
                                content: 'description: ';
                                text-decoration: none;
                            }
                            .url {
                                display: block;
                            }
                            .url:before {
                                font-weight: bolder;
                                font-variant:small-caps;
                                content: 'url: ';
                                text-decoration: none;
                            }
                            ";
            string js  = @"
                            function toggleVisibility(id){
                                var elem = document.getElementById(id);
	                            if (elem.style.visibility=='hidden'){
		                            elem.style.visibility='visible';
                                    elem.style.display = 'block';
		                            }
	                            else {
		                            elem.style.visibility='hidden';
                                    elem.style.display = 'none';
		                            }
	                        }
                            ";

            string introduction = @"<h1>Watcher Security Report</h1>
                                <p>The following issues were automatically identified by the <a href='http://www.casaba.com'>Watcher security plugin</a>
                                for <a href='http://www.fiddler2.com'>Fiddler</a>.</p>";

            doctype = doc.CreateDocumentType("html", "-//W3C//DTD XHTML 1.0 Transitional//EN", null, null);
            doc.AppendChild(doctype);
            root = doc.CreateElement("html");
            doc.AppendChild(root);

            head = doc.CreateElement("head");
            root.AppendChild(head);
            // Add a title
            title           = doc.CreateElement("title");
            title.InnerText = "Watcher Security Report";
            head.AppendChild(title);

            // Setup the meta tag
            meta = doc.CreateElement("meta");
            meta.SetAttribute("http-equiv", "Content-Type");
            meta.SetAttribute("content", "text/html; charset=utf-8");
            head.AppendChild(meta);
            metaIE          = doc.CreateDocumentFragment();
            metaIE.InnerXml = "<meta http-equiv='x-ua-compatible' content='IE=8' />";
            head.AppendChild(metaIE);
            // Setup the style tag
            style = doc.CreateElement("style");
            style.SetAttribute("type", "text/css");
            style.InnerXml = css;
            head.AppendChild(style);
            // Setup script tag
            script = doc.CreateElement("script");
            script.SetAttribute("language", "JavaScript");
            script.InnerXml = js;;
            head.AppendChild(script);


            // Create the body tag
            body          = doc.CreateElement("body");
            body.InnerXml = introduction;
            // Insert the body after the head
            root.InsertAfter(body, head);

            // Create a TOC and intro
            divTOC = doc.CreateElement("div");
            divTOC.SetAttribute("class", "TOC");
            divTOC.SetAttribute("id", "TOC");
            // Start the ordered list
            string contents = "<ol>";

            // Create div to hold selectedResults
            divResults = doc.CreateElement("div");
            divResults.SetAttribute("class", "selectedResults");
            divResults.SetAttribute("id", "selectedResults");

            int x = 0;

            foreach (WatcherResult item in resultslist)
            {
                WatcherEngine.ProgressDialog.labelOperation.Text = "Saving Finding: " + item.Title;
                WatcherEngine.ProgressDialog.UpdateProgress();
                string resultTitle = System.Security.SecurityElement.Escape(item.Title);

                level = doc.CreateElement("span");
                level.SetAttribute("class", "level");
                // Safe from XSS, we control this and its treated as text.
                level.InnerText = item.Severity.ToString();

                url = doc.CreateElement("span");
                url.SetAttribute("class", "url");
                // Use InnertText for URL to make it safe from XSS
                url.InnerText = item.URL;

                typex = doc.CreateElement("span");
                typex.SetAttribute("class", "type");
                // Safe from XSS? We don't control all of the titles - at least not the body regex one.
                typex.InnerXml = "<a name='content-" + x + "'>" + resultTitle + "</a>";

                // Update the string holding the TOC
                // Link to anchor
                contents = String.Concat(contents, String.Format("<li><a href='#content-{0}' class='list'>{1}</a></li>\r\n", x, resultTitle));

                toggleHidden = doc.CreateElement("span");
                toggleHidden.SetAttribute("class", "toggler");
                toggleHidden.InnerXml = "<input type=\"button\" value=\"show/hide\" onclick=\"toggleVisibility('description-" + x + "');\" />";

                desc = doc.CreateElement("pre");
                desc.SetAttribute("class", "description");
                desc.SetAttribute("id", "description-" + x);
                desc.SetAttribute("style", "visibility:hidden;display:none");
                // Safe from XSS, we control this and its treated as text.
                desc.InnerText = item.Description;

                divResults.AppendChild(typex);
                divResults.AppendChild(level);
                divResults.AppendChild(url);
                divResults.AppendChild(toggleHidden);
                divResults.AppendChild(desc);
                x++;
            }
            // Append the TOC to the body
            // End the ordered list
            contents        = String.Concat(contents, "</ol>");
            divTOC.InnerXml = contents;
            body.AppendChild(divTOC);

            // Append the selectedResults to the body
            body.AppendChild(divResults);
            return(doc);
        }
Beispiel #6
0
 //Standard Compliance Handling?
 /// <summary>
 /// This method Takes a single result and processes for output.
 /// </summary>
 public abstract Stream SaveResult(WatcherResultCollection result);
Beispiel #7
0
        /// <summary>
        /// This method saves the collection of Watcher findings to the Team Foundation Server specified in the UI.
        /// </summary>
        /// <param name="watcherResults">Collection of Watcher findings to export.</param>
        /// <returns>This method always returns null for Team Foundation Server exports.</returns>
        public override Stream SaveResult(WatcherResultCollection watcherResults)
        {
            Trace.TraceInformation("Exporting {0} items...", watcherResults.Count);

            // Create an instance of the Watcher Result to Team Foundation Work Item adapter
            _adapter = TeamFoundationAdapter.Create(_configurationPanel.servername, _configurationPanel.projectname);

            Trace.TraceInformation("Connecting to Team Foundation Server...");
            WatcherEngine.ProgressDialog.UpdateProgress("Connecting to Team Foundation Server...");

            // Attempt to connect to the Team Foundation Server specified in the configuration panel
            try { _adapter.Connect(); }
            catch (WatcherException ex)
            {
                Trace.TraceError("Unable to connect to Team Foundation Server \"{0}\": {1}", _adapter.ServerName, ex.Message);
                throw;
            }

            Trace.TraceInformation("Opening the project...");
            WatcherEngine.ProgressDialog.UpdateProgress("Opening the project...");

            // Attempt to open the Team Foundation Project specified in the configuration panel
            try { _adapter.OpenProject(); }
            catch (WatcherException ex)
            {
                Trace.TraceError("Unable to connect to Team Foundation Server \"{0}\": {1}", _adapter.ServerName, ex.Message);
                throw;
            }

            // TODO: collect results and throw with error
            // Enumerate and export the results
            for (int ndx = 0; ndx < watcherResults.Count;)
            {
                // Reset the progress bar for each finding exported
                WatcherEngine.ProgressDialog.ProgressValue = 10;

                // Determine the current finding
                WatcherResult watcherResult = watcherResults[ndx];

                // Export the current finding
                try { ExportResult(watcherResult); }
                catch (WatcherException ex)
                {
                    DialogResult dlgResult = MessageBox.Show(ex.Message, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning);
                    switch (dlgResult)
                    {
                    case DialogResult.Abort:
                        Trace.TraceInformation("User has aborted the export.");
                        WatcherException e = new WatcherException(ex.Message);
                        e.Data["UserAbortedOperation"] = true;      // Prevent an additional dialog from appearing when the exception is
                        throw e;                                    // rethrown to abort the operation.

                    case DialogResult.Retry:
                        Trace.TraceInformation("User is attempting to retry the export of item \"{0}\".", watcherResult.Title);
                        continue;

                    case DialogResult.Ignore:
                        break;
                    }
                }

                // Continue with the next finding
                ++ndx;
            }

            // TODO: Make the SaveResult return type more generic.  Returning null here is
            // a kludge since output plugins were originally intended to return a Stream.
            return(null);
        }