Пример #1
0
func protect(h httprouter.Handle, expire time.Duration, trigger string) httprouter.Handle {
	return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {

		secure := false
		if trigger == "read" && config.CoreConf.Secure_api_read {
			secure = true
		} else if trigger == "write" && config.CoreConf.Secure_api_write {
			secure = true
		}
		logging.Infof("trigger: %s, secure: %v, write: %v, read: %v\n", trigger, secure, config.CoreConf.Secure_api_write, config.CoreConf.Secure_api_read)

		if secure {
			hostname := r.URL.Query().Get("hostname")
			if strings.ToLower(hostname) != newcore.GetHostname() {
				logging.Errorf("hostname mismatch: %v", hostname)
				http.Error(w, "hostname mismatch", 500)
				return
			}

			time_str := r.URL.Query().Get("time")
			tm, err := utils.UTCTimeFromUnixStr(time_str)
			if err != nil {
				logging.Errorf("invalid time: %v", time_str)
				http.Error(w, "Invalid Time", 500)
				return
			}

			if time.Now().Sub(tm) > expire {
				// expired reqeust
				logging.Errorf("expired request: %v", time.Now().Sub(tm))
				http.Error(w, "expired request", 500)
				return
			}

			// we need to verify request.
			// request should put signature of this agent hostname into header HICKWALL_ADMIN_SIGN
			load_unsigner()

			signed_str := r.Header.Get("HICKWALL_ADMIN_SIGN")
			signed, err := base64.StdEncoding.DecodeString(signed_str)
			if err != nil {
				logging.Error("cannot decode sign")
				http.Error(w, "cannot decode sign", 500)
				return
			}

			toSign := fmt.Sprintf("%s%s", hostname, time_str)
			logging.Trace("unsign started")
			err = unsigner.Unsign([]byte(toSign), signed)
			logging.Trace("unsign finished")
			if err != nil {
				logging.Errorf("-> invalid signature: %v <-", string(signed))
				http.Error(w, "invalid signature", 500)
				return
			}
		}

		h(w, r, ps)
	}
}
Пример #2
0
func Test_api_registry_revoke(t *testing.T) {
	logging.SetLevel("debug")
	go serve_api()
	config.CORE_CONF_FILEPATH, _ = filepath.Abs("./test/core_config.yml")
	config.CONF_FILEPATH, _ = filepath.Abs("./test/config_wo_groups.yml")

	ioutil.WriteFile(config.REGISTRY_FILEPATH, []byte(`test`), 0644)

	uri, _ := url.Parse("http://localhost:3031/registry/revoke")

	values := url.Values{}
	values.Add("hostname", newcore.GetHostname())
	values.Encode()
	uri.RawQuery = values.Encode()

	resp, err := goreq.Request{
		Method:  "DELETE",
		Uri:     uri.String(),
		Accept:  "application/json",
		Timeout: 1 * time.Second,
	}.Do()

	if err != nil {
		t.Errorf("failed to do revoke: %s", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		t.Errorf("statuscode != 200, %d", resp.StatusCode)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Errorf("failed to read response")
	}
	t.Logf("data: %s", data)

	b, err := utils.PathExists(config.REGISTRY_FILEPATH)
	if b != false || err != nil {
		t.Errorf("revoke not working.")
	}
}
Пример #3
0
func Test_api_registry_revoke_secure(t *testing.T) {
	logging.SetLevel("debug")
	go serve_api()
	config.CORE_CONF_FILEPATH, _ = filepath.Abs("./test/core_config.yml")
	config.CONF_FILEPATH, _ = filepath.Abs("./test/config_wo_groups.yml")
	config.CoreConf.Secure_api_write = true // need to add signature

	unsigner, _ = utils.LoadPublicKey(public_key) // override interval unsigner
	signer, _ := utils.LoadPrivateKey(private_key)

	hostname := newcore.GetHostname()
	now := fmt.Sprintf("%d", time.Now().Unix())

	uri, _ := url.Parse("http://localhost:3031/registry/revoke")
	values := url.Values{}
	values.Add("hostname", newcore.GetHostname())
	values.Add("time", now)
	values.Encode()
	uri.RawQuery = values.Encode()

	go_req := goreq.Request{
		Method:  "DELETE",
		Uri:     uri.String(),
		Accept:  "application/json",
		Timeout: 1 * time.Second,
	}

	// mock registry file before call api
	ioutil.WriteFile(config.REGISTRY_FILEPATH, []byte(`test`), 0644)
	resp, _ := go_req.Do()
	//	if err == nil {
	//		t.Errorf("should fail but not.")
	//		return
	//	}

	if resp.StatusCode == 200 {
		t.Errorf("should fail but not")
		return
	}

	if b, _ := utils.PathExists(config.REGISTRY_FILEPATH); b != true {
		t.Errorf("should fail but not")
		return
	}
	resp.Body.Close()

	toSign := fmt.Sprintf("%s%s", hostname, now)
	sign, _ := signer.Sign([]byte(toSign))
	sign_str := base64.StdEncoding.EncodeToString(sign)
	go_req.AddHeader("HICKWALL_ADMIN_SIGN", sign_str)

	// mock registry file before call api
	ioutil.WriteFile(config.REGISTRY_FILEPATH, []byte(`test`), 0644)
	resp, err := go_req.Do()
	if err != nil {
		t.Errorf("should work but not: %v", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		t.Errorf("statuscode != 200, %d", resp.StatusCode)
		return
	}

	b, err := utils.PathExists(config.REGISTRY_FILEPATH)
	if b != false || err != nil {
		t.Errorf("revoke not working.")
	}
}
Пример #4
0
func GetSystemInfo() (SystemInfo, error) {
	var info = SystemInfo{}
	cs_info, err := wmi.QueryWmi("SELECT Name, Domain, NumberOfLogicalProcessors, NumberOfProcessors, TotalPhysicalMemory FROM Win32_ComputerSystem")
	logging.Tracef("err: %v, cs_info: %v", err, cs_info)
	if err != nil {
		return info, err
	}
	if len(cs_info) != 1 {
		return info, fmt.Errorf("invalid query result: %v", cs_info)
	}
	cs_info_m := cs_info[0]

	info.Name = newcore.GetHostname()

	if string_value, ok := cs_info_m["Domain"]; ok == true {
		info.Domain = string_value
	}

	if string_value, ok := cs_info_m["NumberOfLogicalProcessors"]; ok == true {
		int_value, err := strconv.Atoi(string_value)
		if err != nil {
			return info, err
		}
		info.NumberOfLogicalProcessors = int_value
	}

	if string_value, ok := cs_info_m["NumberOfProcessors"]; ok == true {
		int_value, err := strconv.Atoi(string_value)
		if err != nil {
			return info, err
		}
		info.NumberOfProcessors = int_value
	}

	if string_value, ok := cs_info_m["TotalPhysicalMemory"]; ok == true {
		int_value, err := strconv.Atoi(string_value)
		if err != nil {
			return info, err
		}
		info.TotalPhsycialMemoryKb = int_value / 1024
	}

	os_info, err := wmi.QueryWmi("Select Caption, CSDVersion, OSArchitecture, Version From Win32_OperatingSystem")
	logging.Tracef("err: %v, os_info: %v", err, os_info)
	if err != nil {
		return info, err
	}
	if len(os_info) != 1 {
		return info, fmt.Errorf("invalid query result: %v", os_info)
	}
	os_info_m := os_info[0]

	if string_value, ok := os_info_m["Caption"]; ok == true {
		info.OS = string_value
	}

	csdversion := ""
	if string_value, ok := os_info_m["CSDVersion"]; ok == true {
		csdversion = string_value
	}

	if string_value, ok := os_info_m["Version"]; ok == true {
		version := string_value
		info.OSVersion = fmt.Sprintf("%s - %s", csdversion, version)
	}

	if string_value, ok := os_info_m["OSArchitecture"]; ok == true {
		if string_value == "64-bit" {
			info.Architecture = 64
		} else {
			info.Architecture = 32
		}

	}

	//FIXME: we may not be able to get ip list.
	ipv4list, err := utils.Ipv4List()
	if err != nil {
		logging.Errorf("failed to get ipv4 list: %v", err)
		//		return info, err
	} else {
		info.IPv4 = ipv4list
	}

	return info, nil
}