예제 #1
0
// Get uses the cookie value with the given name to
// populate the out argument. If the types don't match
// (e.g. the cookie was set to a string and you try
// to get an int), an error will be returned.
func (c *Cookies) Get(name string, out interface{}) error {
	cookie, err := c.GetCookie(name)
	if err != nil {
		return err
	}
	data, err := base64.Decode(cookie.Value)
	if err != nil {
		return err
	}
	return c.c.Decode(data, out)
}
예제 #2
0
파일: signer.go 프로젝트: rainycape/gondola
// Unsign takes a string, previously returned from Sign, checks
// that its signature is valid and, in that case, returns the initial
// data. If the signature is not valid, an error is returned.
func (s *Signer) Unsign(signed string) ([]byte, error) {
	parts := strings.Split(signed, ":")
	if len(parts) != 2 {
		return nil, ErrNotSigned
	}
	data, err := base64.Decode(parts[0])
	if err != nil {
		return nil, err
	}
	signature, err := base64.Decode(parts[1])
	if err != nil {
		return nil, err
	}
	sign, err := s.sign(data)
	if err != nil {
		return nil, err
	}
	if len(sign) != len(signature) || subtle.ConstantTimeCompare(sign, signature) != 1 {
		return nil, ErrTampered
	}
	return data, nil
}
예제 #3
0
func (c *Cookies) decode(data string, arg interface{}, t transformer) error {
	b, err := base64.Decode(data)
	if err != nil {
		return err
	}
	if t != nil {
		b, err = t(b)
		if err != nil {
			return err
		}
	}
	return c.c.Decode(b, arg)
}
예제 #4
0
func requestProfile(u string, method string, values url.Values, secret string) (*profileInfo, error) {
	var req *http.Request
	var err error
	if method == "POST" {
		if len(values) > 0 {
			req, err = http.NewRequest(method, u, strings.NewReader(values.Encode()))
			if req != nil {
				req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
			}
		} else {
			req, err = http.NewRequest(method, u, nil)
		}
	} else {
		reqURL := u
		if len(values) > 0 {
			reqURL += "?" + values.Encode()
		}
		req, err = http.NewRequest(method, reqURL, nil)
	}
	if err != nil {
		return nil, err
	}
	if secret != "" {
		ts := time.Now().Unix()
		nonce := stringutil.Random(32)
		signer := cryptoutil.Signer{Salt: []byte(profile.Salt), Key: []byte(secret)}
		signed, err := signer.Sign([]byte(fmt.Sprintf("%d:%s", ts, nonce)))
		if err != nil {
			return nil, err
		}
		req.Header.Add(profile.HeaderName, signed)
	} else {
		req.Header.Add(profile.HeaderName, "true")
	}
	dump, err := httputil.DumpRequestOut(req, true)
	if err != nil {
		return nil, err
	}
	log.Debugf("Request: \n%s", string(dump))
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	value := resp.Header.Get(profile.HeaderName)
	switch value {
	case "":
		return nil, fmt.Errorf("no profiling info on %s - is profiling enabled?", u)
	case "auth":
		return nil, errAuthRequired
	case "denied":
		return nil, errAuthFailed
	}
	decoded, err := base64.Decode(value)
	if err != nil {
		return nil, err
	}
	r := flate.NewReader(bytes.NewReader(decoded))
	defer r.Close()
	dec := json.NewDecoder(r)
	var info *profileInfo
	if err := dec.Decode(&info); err != nil {
		return nil, err
	}
	return info, nil
}