Example #1
0
// authenticateLoader is used to authenticate requests that are made to the
// loader API endpoints. Rather than operate on GPG signatures, the
// authentication instead uses the submitted loader key
func authenticateLoader(pass handler) handler {
	return func(w http.ResponseWriter, r *http.Request) {
		var (
			loaderid float64
			err      error
		)
		opid := getOpID(r)
		context.Set(r, opID, opid)
		lkey := r.Header.Get("X-LOADERKEY")
		if lkey == "" {
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: "X-LOADERKEY header not found"})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
		// Do a sanity check here on the submitted loader string before
		// we attempt the authentication
		err = mig.ValidateLoaderKey(lkey)
		if err == nil {
			loaderid, err = ctx.DB.GetLoaderEntryID(lkey)
		}
		if err != nil {
			resource := cljs.New(fmt.Sprintf("%s%s", ctx.Server.Host, r.URL.String()))
			resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("Loader authorization failed")})
			respond(http.StatusUnauthorized, resource, w, r)
			return
		}
		context.Set(r, loaderID, loaderid)
		// accept request
		pass(w, r)
	}
}
Example #2
0
// Attempt to obtain the loader key from the file system and override the
// built-in secret
func loadLoaderKey() error {
	fd, err := os.Open(getLoaderKeyfile())
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return err
	}
	defer fd.Close()
	buf, _, err := bufio.NewReader(fd).ReadLine()
	if err != nil {
		// Nothing in the loader key file
		if err == io.EOF {
			return nil
		}
		return err
	}
	// Also trim any leading and trailing spaces from the loader key
	LOADERKEY = strings.Trim(string(buf), " ")
	err = mig.ValidateLoaderKey(LOADERKEY)
	if err != nil {
		return err
	}
	ctx.LoaderKey = LOADERKEY
	return nil
}
Example #3
0
// Change key set on a loader entry
func keyLoader(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 keyLoader()"}.Debug()
	}()

	err := request.ParseForm()
	if err != nil {
		panic(err)
	}

	ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received loader key change request")}.Debug()

	loaderid, err := strconv.ParseFloat(request.FormValue("loaderid"), 64)
	if err != nil {
		panic(err)
	}
	lkey := request.FormValue("loaderkey")
	if lkey == "" {
		// bad request, return 400
		resource.SetError(cljs.Error{
			Code:    fmt.Sprintf("%.0f", opid),
			Message: "Invalid key specified"})
		respond(http.StatusBadRequest, resource, respWriter, request)
		return
	}
	err = mig.ValidateLoaderKey(lkey)
	if err != nil {
		panic(err)
	}
	hashkey, salt, err := hashLoaderKey(lkey, nil)
	if err != nil {
		panic(err)
	}
	err = ctx.DB.LoaderUpdateKey(loaderid, hashkey, salt)
	if err != nil {
		panic(err)
	}

	respond(http.StatusOK, resource, respWriter, request)
}
Example #4
0
// Change the key on an existing loader entry
func (cli Client) LoaderEntryKey(le mig.LoaderEntry, key string) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("LoaderEntryKey() -> %v", e)
		}
	}()
	if key == "" {
		panic("invalid loader key specified")
	}
	err = mig.ValidateLoaderKey(key)
	if err != nil {
		panic(err)
	}
	data := url.Values{"loaderid": {fmt.Sprintf("%.0f", le.ID)}, "loaderkey": {key}}
	r, err := http.NewRequest("POST", cli.Conf.API.URL+"loader/key/",
		strings.NewReader(data.Encode()))
	if err != nil {
		panic(err)
	}
	r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := cli.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
	if len(body) > 1 {
		err = json.Unmarshal(body, &resource)
		if err != nil {
			panic(err)
		}
	}
	if resp.StatusCode != http.StatusOK {
		err = fmt.Errorf("error: HTTP %d. Key update failed with error '%v' (code %s).",
			resp.StatusCode, resource.Collection.Error.Message, resource.Collection.Error.Code)
		panic(err)
	}
	return
}