func domainWithNoErrors(config ScanInjectorTestConfigFile, domainDAO dao.DomainDAO) { domain := newDomain() // Set all nameservers as configured correctly and the last check as now, this domain is // unlikely to be selected for index, _ := range domain.Nameservers { domain.Nameservers[index].LastCheckAt = time.Now() domain.Nameservers[index].LastStatus = model.NameserverStatusOK } // Set all DS records as configured correctly and the last check as now, this domain is // unlikely to be selected for index, _ := range domain.DSSet { domain.DSSet[index].LastCheckAt = time.Now() domain.DSSet[index].LastStatus = model.DSStatusOK } if err := domainDAO.Save(&domain); err != nil { utils.Fatalln("Error saving domain for scan scenario", err) } model.StartNewScan() if domains := runScan(config, domainDAO); len(domains) > 0 { utils.Fatalln(fmt.Sprintf("Selected a domain configured correctly for the scan. "+ "Expected 0 got %d", len(domains)), nil) } currentScan := model.GetCurrentScan() if currentScan.Status != model.ScanStatusRunning { utils.Fatalln("Not changing the scan info status for domain with no errors", nil) } if currentScan.DomainsToBeScanned > 0 { utils.Fatalln("Not counting the domains to be scanned for domain with no errors", nil) } if err := domainDAO.RemoveByFQDN(domain.FQDN); err != nil { utils.Fatalln("Error removing domain", err) } }
func domainWithDNSErrors(config ScanInjectorTestConfigFile, domainDAO dao.DomainDAO) { domain := newDomain() // Set all nameservers with error and the last check equal of the error check interval, // this will force the domain to be checked for index, _ := range domain.Nameservers { maxErrorHours := config.Scan.VerificationIntervals.MaxErrorDays * 24 lessThreeDays, _ := time.ParseDuration("-" + strconv.Itoa(maxErrorHours) + "h") domain.Nameservers[index].LastCheckAt = time.Now().Add(lessThreeDays) domain.Nameservers[index].LastStatus = model.NameserverStatusServerFailure } if err := domainDAO.Save(&domain); err != nil { utils.Fatalln("Error saving domain for scan scenario", err) } model.StartNewScan() if domains := runScan(config, domainDAO); len(domains) != 1 { utils.Fatalln(fmt.Sprintf("Couldn't load a domain with DNS errors for scan. "+ "Expected 1 got %d", len(domains)), nil) } currentScan := model.GetCurrentScan() if currentScan.Status != model.ScanStatusRunning { utils.Fatalln("Not changing the scan info status with DNS errors", nil) } if currentScan.DomainsToBeScanned != 1 { utils.Fatalln("Not counting the domains to be scanned with DNS errors", nil) } if err := domainDAO.RemoveByFQDN(domain.FQDN); err != nil { utils.Fatalln("Error removing domain", err) } }
func domainWithErrors(config ScanCollectorTestConfigFile, database *mgo.Database) { domainsToSave := make(chan *model.Domain, config.Scan.DomainsBufferSize) domainsToSave <- &model.Domain{ FQDN: "br.", Nameservers: []model.Nameserver{ { Host: "ns1.br", IPv4: net.ParseIP("127.0.0.1"), LastStatus: model.NameserverStatusTimeout, }, }, DSSet: []model.DS{ { Keytag: 1234, Algorithm: model.DSAlgorithmRSASHA1NSEC3, DigestType: model.DSDigestTypeSHA1, Digest: "EAA0978F38879DB70A53F9FF1ACF21D046A98B5C", LastStatus: model.DSStatusExpiredSignature, }, }, } domainsToSave <- nil model.StartNewScan() runScan(config, database, domainsToSave) domainDAO := dao.DomainDAO{ Database: database, } domain, err := domainDAO.FindByFQDN("br.") if err != nil { utils.Fatalln("Error loading domain with problems", err) } if len(domain.Nameservers) == 0 { utils.Fatalln("Error saving nameservers", nil) } if domain.Nameservers[0].LastStatus != model.NameserverStatusTimeout { utils.Fatalln("Error setting status in the nameserver", nil) } if len(domain.DSSet) == 0 { utils.Fatalln("Error saving the DS set", nil) } if domain.DSSet[0].LastStatus != model.DSStatusExpiredSignature { utils.Fatalln("Error setting status in the DS", nil) } if err := domainDAO.RemoveByFQDN("br."); err != nil { utils.Fatalln("Error removing test domain", err) } currentScan := model.GetCurrentScan() if currentScan.DomainsScanned != 1 || currentScan.DomainsWithDNSSECScanned != 1 { utils.Fatalln("Not counting domains for scan progress when there're errors", nil) } if currentScan.NameserverStatistics[model.NameserverStatusToString(model.NameserverStatusTimeout)] != 1 || currentScan.DSStatistics[model.DSStatusToString(model.DSStatusExpiredSignature)] != 1 { utils.Fatalln("Not counting statistics properly when there're errors", nil) } }
// The HEAD method is identical to GET except that the server MUST NOT return a message- // body in the response. But now the responsability for don't adding the body is from the // mux while writing the response func (h *ScansHandler) retrieveScans(w http.ResponseWriter, r *http.Request) { var pagination dao.ScanDAOPagination expand := false returnCurrent := false for key, values := range r.URL.Query() { key = strings.TrimSpace(key) key = strings.ToLower(key) // A key can have multiple values in a query string, we are going to always consider // the last one (overwrite strategy) for _, value := range values { value = strings.TrimSpace(value) value = strings.ToLower(value) switch key { case "orderby": // OrderBy parameter will store the fields that the user want to be the keys of the sort // algorithm in the result set and the direction that each sort field will have. The format // that will be used is: // // <field1>:<direction1>@<field2>:<direction2>@...@<fieldN>:<directionN> orderByParts := strings.Split(value, "@") for _, orderByPart := range orderByParts { orderByPart = strings.TrimSpace(orderByPart) orderByAndDirection := strings.Split(orderByPart, ":") var field, direction string if len(orderByAndDirection) == 1 { field, direction = orderByAndDirection[0], "asc" } else if len(orderByAndDirection) == 2 { field, direction = orderByAndDirection[0], orderByAndDirection[1] } else { if err := h.MessageResponse("invalid-query-order-by", ""); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } orderByField, err := dao.ScanDAOOrderByFieldFromString(field) if err != nil { if err := h.MessageResponse("invalid-query-order-by", ""); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } orderByDirection, err := dao.DAOOrderByDirectionFromString(direction) if err != nil { if err := h.MessageResponse("invalid-query-order-by", ""); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } pagination.OrderBy = append(pagination.OrderBy, dao.ScanDAOSort{ Field: orderByField, Direction: orderByDirection, }) } case "pagesize": var err error pagination.PageSize, err = strconv.Atoi(value) if err != nil { if err := h.MessageResponse("invalid-query-page-size", ""); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } case "page": var err error pagination.Page, err = strconv.Atoi(value) if err != nil { if err := h.MessageResponse("invalid-query-page", ""); err == nil { w.WriteHeader(http.StatusBadRequest) } else { log.Println("Error while writing response. Details:", err) w.WriteHeader(http.StatusInternalServerError) } return } case "expand": expand = true case "current": returnCurrent = true } } } scanDAO := dao.ScanDAO{ Database: h.GetDatabase(), } // As we need to inform the user about the number of items, we always try to retrieve the scan // objects even if is requested only the current object scans, err := scanDAO.FindAll(&pagination, expand) if err != nil { log.Println("Error while searching scans objects. Details:", err) w.WriteHeader(http.StatusInternalServerError) return } var scansResponse protocol.ScansResponse var current model.CurrentScan if returnCurrent { // The current page will be page zero to avoid misunderstandment pagination.Page = 0 current = model.GetCurrentScan() scansResponse = protocol.CurrentScanToScansResponse(current, pagination) } else { scansResponse = protocol.ScansToScansResponse(scans, pagination) } h.Response = &scansResponse // Last-Modified is going to be the most recent date of the list if returnCurrent { h.lastModifiedAt = current.LastModifiedAt } else { for _, scan := range scans { if scan.LastModifiedAt.After(h.lastModifiedAt) { h.lastModifiedAt = scan.LastModifiedAt } } } w.Header().Add("ETag", h.GetETag()) w.Header().Add("Last-Modified", h.lastModifiedAt.Format(time.RFC1123)) w.WriteHeader(http.StatusOK) }