func measurementObjectiveEvaluate(context *ctp.ApiContext, item *Measurement) *ctp.HttpError { item.Objective.Status = ctp.Terror ctp.Log(context, ctp.DEBUG, "Evaluating objective: %s\n", item.Objective.Condition) machine, err := jsmm.Compile(item.Objective.Condition) if err != nil { return ctp.NewBadRequestErrorf("Error in objective compilation - %s", err.Error()) } if item.Result == nil { item.Objective.Status = ctp.Ttrue return nil } if context.DebugVM { machine.DebugMode(true) } if err := importMeasurementResultInJSMM(machine, item.Result); err != nil { return ctp.NewBadRequestErrorf("Error in objective evaluation while importing result - %s", err.Error) } v, exception := machine.Execute() if exception != nil { return ctp.NewBadRequestErrorf("Error in objective evaluation - %s", exception.Error()) } if v != nil { item.Objective.Status = ctp.ToBoolErr(v.ToBoolean()) } return nil }
func (mux *CtpApiHandlerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { context, err := ctp.NewApiContext(r, mux.Configuration) if err != nil { ctp.RenderErrorResponse(w, context, ctp.NewHttpError(500, "Context creation failure")) return } defer context.Close() if handlerfunc, ok := ctpUrlMap[context.Signature]; ok { ctp.Log(context, ctp.INFO, "Serving request '%s' with signature '%s'", r.RequestURI, context.Signature) handlerfunc(w, r, context) } else { ctp.Log(nil, ctp.WARNING, "Not found: %s\n", context.Signature) http.NotFound(w, r) } }
// HandleGETBaseURI handles a request to the baseURI. // It proceeds differently from other resources, which user the 'handler' paradigm. func HandleGETBaseURI(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) { if !context.AuthenticateClient(w, r) { ctp.Log(context, "Missing access tags") return } if !context.VerifyAccessTags(w, ctp.UserAccess) { ctp.Log(context, "Mismatched access tags for API signature") return } base := new(BaseURI) base.Version = "0" base.Annotation = "ctpd prototype server" base.BuildLinks(context) ctp.RenderJsonResponse(w, context, 200, base) }
// HandleGETBaseURI handles a request to the baseURI. // It proceeds differently from other resources, which user the 'handler' paradigm. func HandleGETBaseURI(w http.ResponseWriter, r *http.Request, context *ctp.ApiContext) { if !context.AuthenticateClient(w, r) { ctp.Log(context, ctp.WARNING, "Missing access tags") return } if !context.VerifyAccessTags(w, ctp.UserRoleTag) { ctp.Log(context, ctp.WARNING, "Mismatched access tags for API signature") return } base := new(BaseURI) if !ctp.LoadResource(context, "baseuri", ctp.Base64Id("0"), base) { base.Version = "0" base.Annotation = "Unconfigured ctpd prototype server" } base.BuildLinks(context) ctp.RenderJsonResponse(w, context, 200, base) }
func triggerCheckCondition(context *ctp.ApiContext, trigger *Trigger, measurement *Measurement) (bool, error) { if measurement == nil { measurementParams, ok := ctp.ParseLink(context.CtpBase, "@/measurements/$", trigger.Measurement) if !ok { return false, fmt.Errorf("Measurement URL is incorrect") } measurement = new(Measurement) if !ctp.LoadResource(context, "measurements", ctp.Base64Id(measurementParams[0]), measurement) { return false, fmt.Errorf("Measurement %s does not exist", ctp.ExpandLink(context.CtpBase, trigger.Measurement)) } } machine, err := jsmm.Compile(trigger.Condition) if err != nil { return false, ctp.NewBadRequestErrorf("Error in condition specification - %s", err.Error()) } if context.DebugVM { machine.DebugMode(true) } if measurement.State != "activated" { return false, nil } if measurement.Result == nil { ctp.Log(context, ctp.ERROR, "In /measurements/%s, the state is activated but the value is null.", measurement.Id) return false, nil } if err := importMeasurementResultInJSMM(machine, measurement.Result); err != nil { return false, err } v, exception := machine.Execute() if exception != nil { return false, fmt.Errorf("Failed to evaluate condition: %s", exception.Error()) } return v.ToBoolean(), nil }
func main() { var ok bool var conf ctp.Configuration flag.Parse() if versionFlag { fmt.Println("ctpd version", CTPD_VERSION) fmt.Println(" Copyright 2015 Cloud Security Alliance EMEA (cloudsecurityalliance.org).") fmt.Println(" ctpd is licensed under the Apache License, Version 2.0.") fmt.Println(" see http://www.apache.org/licenses/LICENSE-2.0") fmt.Println("") return } if helpFlag { fmt.Fprintf(os.Stderr, "Usage: %s [flags]\n", path.Base(os.Args[0])) flag.PrintDefaults() return } if configFileFlag == "/path/to/file" { conf, ok = ctp.SearchAndLoadConfigurationFile() } else { conf, ok = ctp.LoadConfigurationFromFile(configFileFlag) } if !ok { ctp.Log(nil, ctp.INFO, "No configuration file was loaded, using defaults.") conf = ctp.ConfigurationDefaults } if logfileFlag != "" { conf["log-file"] = logfileFlag } if conf["log-file"] != "" { file, err := os.Create(conf["log-file"]) if err != nil { log.Fatalf("Could not open %s, %s", conf["log-file"], err.Error()) } defer file.Close() log.SetOutput(file) } if colorFlag { conf["color-logs"] = "true" } if clientFlag != "" { conf["client"] = clientFlag } if debugVMFlag { conf["debug-vm"] = "true" } if conf["client"] != "" { http.Handle("/", http.FileServer(http.Dir(conf["client"]))) } if !ctp.IsMongoRunning(conf) { log.Fatal("Missing mongodb.") } http.Handle(conf["basepath"], server.NewCtpApiHandlerMux(conf)) if conf["tls_use"] != "" && conf["tls_use"] != "no" { if conf["tls_use"] != "yes" { log.Fatal("Configuration: tls_use must be either 'yes' or 'no'") } if conf["tls_key_file"] == "" || conf["tls_cert_file"] == "" { log.Fatal("Missing tls_key_file or tls_cert_file in configuration.") } ctp.Log(nil, ctp.INFO, "Starting ctpd with TLS enabled at %s", conf["listen"]) log.Fatal(http.ListenAndServeTLS(conf["listen"], conf["tls_cert_file"], conf["tls_key_file"], nil)) } else { ctp.Log(nil, ctp.INFO, "Starting ctpd at %s", conf["listen"]) log.Fatal(http.ListenAndServe(conf["listen"], nil)) } }
func measurementTriggersEvaluate(context *ctp.ApiContext, measurement *Measurement) { var trigger Trigger now := ctp.Now() mlink := ctp.ShortenLink(context.CtpBase, measurement.Self) query := context.Session.DB("ctp").C("triggers").Find(bson.M{"measurement": mlink}) n, err := query.Count() if err == nil { ctp.Log(context, ctp.DEBUG, "Evaluating %d triggers related to measurement %s", n, measurement.Id) } else { ctp.Log(context, ctp.ERROR, "Failed to evaludate triggers related to measurement %s, %s", measurement.Id, err.Error()) return } iter := query.Iter() for iter.Next(&trigger) { var err error var err_upd error var ok bool trigger.BuildLinks(context) ctp.Log(context, ctp.DEBUG, "Evaludating trigger %s, currently with status '%s'", trigger.Id, trigger.Status.String()) switch trigger.Status { case ctp.Tfalse: ok, err = triggerCheckCondition(context, &trigger, measurement) case ctp.Ttrue: if uint(ctp.SecondsSince(trigger.StatusUpdateTime)) <= trigger.GuardTime { continue } ok, err = triggerCheckCondition(context, &trigger, measurement) case ctp.Terror: continue } switch { case err != nil: ctp.Log(context, ctp.ERROR, "Error in trigger %s for measurement %s", trigger.Id, measurement.Id) err_log := CreateErrorLogEntry(context, &trigger, err.Error()) if err_log != nil { ctp.Log(context, ctp.ERROR, "Failed to create error log: %s", err_log.Error()) } err_upd = context.Session.DB("ctp").C("triggers").Update(bson.M{"_id": trigger.Id}, bson.M{"$set": bson.M{"status": ctp.Terror, "statusUpdateTime": now.String()}}) case ok: ctp.Log(context, ctp.DEBUG, "trigger %s is TRUE", trigger.Id) err_log := CreateNormalLogEntry(context, &trigger, measurement.Result, trigger.Tags) if err_log != nil { ctp.Log(context, ctp.ERROR, "Failed to create normal log: %s", err_log.Error()) } err_upd = context.Session.DB("ctp").C("triggers").Update(bson.M{"_id": trigger.Id}, bson.M{"$set": bson.M{"status": ctp.Ttrue, "statusUpdateTime": now.String()}}) default: ctp.Log(context, ctp.DEBUG, "Trigger %s is FALSE", trigger.Id) err_upd = context.Session.DB("ctp").C("triggers").Update(bson.M{"_id": trigger.Id}, bson.M{"$set": bson.M{"status": ctp.Tfalse, "statusUpdateTime": now.String()}}) } if err_upd != nil { ctp.Log(context, ctp.ERROR, "Failed to update trigger 'status' and 'statusDateTime': %s", err_upd.Error()) } } }