func Load_Blacklist(filename string) BlackList { blist := BlackList{} file, err := os.Open(filename) if err != nil { syslog.Errf("%v", err) panic(err) } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() // Ignore empty lines if len(line) > 0 { blist.items = append(blist.items, scanner.Text()) } } if err := scanner.Err(); err != nil { syslog.Errf("%v", err) panic(err) } return blist }
func (j *Jira) Init() { // Loading Jira related settings b, err := ioutil.ReadFile("/opt/cvesync/etc/jira.json") if err != nil { syslog.Errf("Unable to read Jira settings file: %v", err) panic(err) } err = json.Unmarshal(b, &j) if err != nil { syslog.Errf("Unable to unmarshal Jira settings json: %v", err) panic(err) } funcMap := template.FuncMap{ "escape_text": escape_text, } j.Template, err = template.New("jira.templ").Funcs(funcMap).ParseFiles(j.TemplateFile) if err != nil { syslog.Errf("Unable to parse Jira template file: %v", err) panic(err) } }
func (rt RT) Update(e nvd.Entry, ticketid string) error { // Authenticate against RT for this operation jar, err := cookiejar.New(nil) if err != nil { syslog.Errf("Unable to create cookie jar: %v", err) panic(err) } err = rt.authenticate(jar) if err != nil { syslog.Errf("%v", err) return err } // Build ticket information... ticket, err := rt.build_ticket(e) if err != nil { return err } // Build the request request := fmt.Sprintf("Queue: %v\nSubject: %v\nPriority: %v\nText:%v\n", ticket.Queue, ticket.Subject, ticket.Priority, ticket.Text) _, err = rt_request("POST", rt.BaseURL+"/REST/1.0/ticket/"+ticketid+"/edit", rt.CAFile, jar, request) if err != nil { return err } // For some reason the RT doesn't react to Text on ticket/edit // Adding the new text as comment comment_request := fmt.Sprintf("id: %v\nAction: comment\nText:%v\n", ticketid, ticket.Text) _, err = rt_request("POST", rt.BaseURL+"/REST/1.0/ticket/"+ticketid+"/comment", rt.CAFile, jar, comment_request) return err }
func sync_entry(entry nvd.Entry, db *sql.DB, cwes nvd.CWE, ts tracker.Tracker) { entry.CWE.CWECatalog = &cwes // Completely new? if !util.Exists(db, entry.Id) { syslog.Noticef("Adding new CVE %s", entry.Id) id, err := ts.Add(entry) if err != nil { syslog.Errf("Unable to add %v to issue tracker: %v", entry.Id, err) return } // Add to database, too util.DB_Add(db, entry.Id, entry.Last_Modified, id) // Already existing, but modified? } else if !util.Modified_Matches(db, entry.Id, entry.Last_Modified) { syslog.Noticef("Modifying old CVE %s", entry.Id) ticketid := util.DB_TicketID(db, entry.Id) err := ts.Update(entry, ticketid) if err != nil { syslog.Errf("Unable to modify %v in issue tracker: %v", entry.Id, err) return } // Update to database, too util.DB_Update(db, entry.Id, entry.Last_Modified) } }
func (rt RT) Add(e nvd.Entry) (string, error) { // Authenticate against RT for this operation jar, err := cookiejar.New(nil) if err != nil { syslog.Errf("Unable to create cookie jar: %v", err) panic(err) } err = rt.authenticate(jar) if err != nil { syslog.Errf("%v", err) return "", err } // Build ticket information... ticket, err := rt.build_ticket(e) if err != nil { return "", err } // Build the request request := fmt.Sprintf("id: ticket/new\nQueue: %v\nSubject: %v\nPriority: %v\nText:%v\n", ticket.Queue, ticket.Subject, ticket.Priority, ticket.Text) id, err := rt_request("POST", rt.BaseURL+"/REST/1.0/ticket/new", rt.CAFile, jar, request) return id, err }
func Download_File(url string, cafile string) []byte { // Load the CA certificate for server certificate validation capool := x509.NewCertPool() cacert, err := ioutil.ReadFile(cafile) checkerr(err) capool.AppendCertsFromPEM(cacert) // Check server certificate tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: capool}, } // Get! client := &http.Client{Transport: tr} resp, err := client.Get(url) checkerr(err) // 500s and such if resp.StatusCode != 200 { errr := errors.New(fmt.Sprintf("File download failed with status code %v", resp.StatusCode)) syslog.Errf("%v", errr) panic(errr) } // Read the body defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) // body is []byte checkerr(err) return body }
func (rt RT) authenticate(jar *cookiejar.Jar) error { client := &http.Client{ Jar: jar, } data := url.Values{} data.Add("user", rt.Username) data.Add("pass", rt.Password) client.PostForm(rt.BaseURL, data) // Check that we got back at least one cookie -> probably successful authentication! // Alternatively could check that RT_SID_url.80 exists url, err := url.Parse(rt.BaseURL) if err != nil { syslog.Errf("Unable to parse BaseURL: %v", err) panic(err) } if len(jar.Cookies(url)) < 1 { return errors.New("Authentication to RT failed!") } return nil }
func Get_CWEs(filename string) CWE { b, err := ioutil.ReadFile(filename) if err != nil { syslog.Errf("Unable to read CWE file: %v", err) panic(err) } cwes := Unmarshal_CWE(b) return cwes }
func Unmarshal_CWE(data []byte) CWE { var c CWE err := xml.Unmarshal(data, &c) if err != nil { syslog.Errf("Unable to parse CWEs: %v", err) panic(err) } return c }
func (j Jira) build_description(e nvd.Entry) string { var result bytes.Buffer err := j.Template.Execute(&result, e) if err != nil { syslog.Errf("Unable to execute Jira template file: %v", err) panic(err) } return result.String() }
func (rt RT) build_text(e nvd.Entry) string { var result bytes.Buffer err := rt.Template.Execute(&result, e) if err != nil { syslog.Errf("Unable to execute RT template file: %v", err) panic(err) } return result.String() }
func (rt *RT) Init() { // Loading RT related settings b, err := ioutil.ReadFile("/opt/cvesync/etc/rt.json") if err != nil { syslog.Errf("Unable to read RT settings file: %v", err) panic(err) } err = json.Unmarshal(b, &rt) if err != nil { syslog.Errf("Unable to unmarshal RT settings json: %v", err) panic(err) } rt.Template, err = template.New("rt.templ").ParseFiles(rt.TemplateFile) if err != nil { syslog.Errf("Unable to parse RT template file: %v", err) panic(err) } }
func rt_request(reqtype string, path string, cafile string, jar *cookiejar.Jar, ticket string) (string, error) { var client *http.Client // If https, add CA certificate checking if strings.HasPrefix(path, "https://") { capool := x509.NewCertPool() cacert, err := ioutil.ReadFile(cafile) if err != nil { syslog.Errf("Unable to read CA file: %v", err) return "", err } capool.AppendCertsFromPEM(cacert) // Check server certificate tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: capool}, } client = &http.Client{Transport: tr, Jar: jar} } else { client = &http.Client{Jar: jar} } data := url.Values{} data.Add("content", ticket) req, err := http.NewRequest(reqtype, path, strings.NewReader(data.Encode())) if err != nil { return "", err } // We are handling "form" req.Header.Set("Content-Type", "application/x-www-form-urlencoded") // Make RT's anti-XSS happy req.Header.Set("Referer", path) // Request! resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } ticketid := get_ticket_id(string(body)) return ticketid, nil }
func jira_request(reqtype string, path string, cafile string, username string, password string, jsonstr string) (string, error) { var client *http.Client // If https, add CA certificate checking if strings.HasPrefix(path, "https://") { capool := x509.NewCertPool() cacert, err := ioutil.ReadFile(cafile) if err != nil { syslog.Errf("Unable to read CA file: %v", err) return "", err } capool.AppendCertsFromPEM(cacert) // Check server certificate tr := &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: capool}, } client = &http.Client{Transport: tr} } else { client = &http.Client{} } // Build request.. jsonreader := strings.NewReader(jsonstr) req, err := http.NewRequest(reqtype, path, jsonreader) if err != nil { return "", err } // Without application/json Jira returns 415 req.Header.Set("Content-Type", "application/json") // Basic Authentication req.SetBasicAuth(username, password) // Request! resp, err := client.Do(req) if err != nil { return "", err } // If not successful, return with statuscode if (resp.StatusCode < 200) || (resp.StatusCode > 299) { return "", errors.New(fmt.Sprintf("Response contained %v", resp.StatusCode)) } ticketid := "" // Only POST returns something meaningful if reqtype == "POST" { defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } jira_response := Jira_Response{} err = json.Unmarshal(body, &jira_response) if err != nil { return "", err } ticketid = jira_response.Id } return ticketid, nil }
func main() { // Don't throw an error when encountering an unknown flag (for sendmail compat) flag.CommandLine.Init(os.Args[0], flag.ContinueOnError) flag.Parse() if config.Message_FromCronDaemon { config.Message_FromName = "CronDaemon" } if err := config.ParseFile(config.ConfigFile); err != nil { fmt.Fprintf(os.Stderr, "Error while parsing configuration: %s\n", err) os.Exit(2) } // Map all local users to Postmaster address config.Message_To = flag.Args() for i, to := range config.Message_To { if -1 == strings.Index(to, "@") { config.Message_To[i] = config.Postmaster } } if config.Verbose { fmt.Printf("%#v\n", *config) } if len(config.Message_To) == 0 && !config.ScanMessage { fmt.Fprintln(os.Stderr, "Error: no recipients supplied") os.Exit(1) } m, err := compose() if err != nil { syslog.Errf("ComposeError: %s", err) fmt.Fprintf(os.Stderr, "ComposeError: %s\n", err) os.Exit(2) } c, err := connect() if err != nil { syslog.Errf("ConnectError: %s", err) fmt.Fprintf(os.Stderr, "ConnectError: %s\n", err) os.Exit(3) } if err := send(c, m); err != nil { syslog.Errf("SendError: %s", err) fmt.Fprintf(os.Stderr, "SendError: %s\n", err) os.Exit(4) } var subject string = "(unknown)" if len(m.Header["Subject"]) > 0 { subject = m.Header["Subject"][0] } syslog.Syslogf(syslog.LOG_INFO, "[%s] Sent mail; subject \"%s\"; from %s; to %#v", m.Header["Message-Id"][0], subject, config.Message_From, config.Message_To) if config.Verbose { fmt.Println("Info: send successful") } }
func checkerr(err error) { if err != nil { syslog.Errf("Error: %v", err) panic(err) } }