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
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
// 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)
}
Beispiel #4
0
// 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)
}
Beispiel #5
0
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
}
Beispiel #6
0
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())
		}
	}
}