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) } }
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.") } }
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.") } }
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 }