func fetchFile(n string) (ret []byte, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("fetchFile() -> %v", e) } }() murl := APIURL + "manifest/fetch/" logInfo("fetching file from %v", murl) mparam := mig.ManifestParameters{} mparam.AgentIdentifier = ctx.AgentIdentifier mparam.Object = n buf, err := json.Marshal(mparam) if err != nil { panic(err) } mstring := string(buf) data := url.Values{"parameters": {mstring}} r, err := http.NewRequest("POST", murl, strings.NewReader(data.Encode())) if err != nil { panic(err) } r.Header.Set("Content-Type", "application/x-www-form-urlencoded") r.Header.Add("X-LOADERKEY", ctx.LoaderKey) client := http.Client{} resp, err := client.Do(r) if err != nil { panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } var resource *cljs.Resource err = json.Unmarshal(body, &resource) if err != nil { panic(err) } // Extract fetch response. fetchresp, err := valueToFetchResponse(resource.Collection.Items[0].Data[0].Value) if err != nil { panic(err) } // Decompress the returned file and return it as a byte slice. b := bytes.NewBuffer(fetchresp.Data) gz, err := gzip.NewReader(b) if err != nil { panic(err) } ret, err = ioutil.ReadAll(gz) if err != nil { panic(err) } return }
func requestManifest() (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("requestManifest() -> %v", e) } }() murl := APIURL + "manifest/agent/" logInfo("requesting manifest from %v", murl) mparam := mig.ManifestParameters{} mparam.AgentIdentifier = ctx.AgentIdentifier buf, err := json.Marshal(mparam) if err != nil { panic(err) } mstring := string(buf) data := url.Values{"parameters": {mstring}} r, err := http.NewRequest("POST", murl, strings.NewReader(data.Encode())) if err != nil { panic(err) } r.Header.Set("Content-Type", "application/x-www-form-urlencoded") r.Header.Add("X-LOADERKEY", ctx.LoaderKey) client := http.Client{} resp, err := client.Do(r) if err != nil { panic(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } var resource *cljs.Resource err = json.Unmarshal(body, &resource) if err != nil { panic(err) } if resp.StatusCode != http.StatusOK { err = fmt.Errorf("HTTP %v, API call failed with error '%v' (code %s)", resp.StatusCode, resource.Collection.Error.Message, resource.Collection.Error.Code) panic(err) } // Extract our manifest from the response. manifest, err := valueToManifest(resource.Collection.Items[0].Data[0].Value) if err != nil { panic(err) } apiManifest = &manifest err = apiManifest.Validate() if err != nil { panic(err) } return checkManifestSignature(apiManifest) }
// This API entry point is used by the loader to request a manifest file that // indicates the most current version of the agent to be used. The loader // sends some basic information in the request parameters so the API can decide // which manifest to send the loader. // // If the key passed in the request is not valid, the request will be rejected. func getAgentManifest(respWriter http.ResponseWriter, request *http.Request) { loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String()) opid := getOpID(request) resource := cljs.New(loc) defer func() { if e := recover(); e != nil { ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err() resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)}) respond(http.StatusInternalServerError, resource, respWriter, request) } ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getAgentManifest()"}.Debug() }() err := request.ParseForm() if err != nil { panic(err) } ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "Received manifest request"}.Debug() var manifestParam mig.ManifestParameters err = json.Unmarshal([]byte(request.FormValue("parameters")), &manifestParam) if err != nil { panic(err) } err = manifestParam.Validate() if err != nil { panic(err) } loaderid := getLoaderID(request) if loaderid == 0 { panic("Request has no valid loader ID") } // Update the loader entry with the parameters, and locate a valid manifest mf, err := locateManifestFromLoader(loaderid, manifestParam.AgentIdentifier) if err != nil { panic(err) } m, err := mf.ManifestResponse() if err != nil { panic(err) } // Include the loader ID with the response m.LoaderName, err = ctx.DB.GetLoaderName(loaderid) if err != nil { panic(err) } // Send the manifest to the loader err = resource.AddItem(cljs.Item{ Href: request.URL.String(), Data: []cljs.Data{ { Name: "manifest", Value: m, }, }}) if err != nil { panic(err) } respond(http.StatusOK, resource, respWriter, request) }