Пример #1
0
func (h *DeployHandler) serveSetup(w http.ResponseWriter, r *http.Request) {
	if r.FormValue("mode") != "setupproject" {
		h.serveError(w, r, errors.New("bad form"))
		return
	}
	ck, err := r.Cookie("user")
	if err != nil {
		h.serveFormError(w, errors.New("Cookie expired, or CSRF attempt. Please reload and retry."))
		h.logger.Printf("Cookie expired, or CSRF attempt on form.")
		return
	}

	instConf, err := h.confFromForm(r)
	if err != nil {
		h.serveFormError(w, err)
		return
	}

	br, err := h.storeInstanceConf(instConf)
	if err != nil {
		h.serveError(w, r, fmt.Errorf("could not store instance configuration: %v", err))
		return
	}

	xsrfToken := xsrftoken.Generate(h.xsrfKey, ck.Value, br.String())
	state := fmt.Sprintf("%s:%x", br.String(), xsrfToken)
	redirectURL := h.oAuthConfig().AuthCodeURL(state)
	http.Redirect(w, r, redirectURL, http.StatusFound)
	return
}
Пример #2
0
func sendWizard(rw http.ResponseWriter, req *http.Request, hasChanged bool) {
	config, err := jsonconfig.ReadFile(osutil.UserServerConfigPath())
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	err = flattenPublish(config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}

	funcMap := template.FuncMap{
		"printWizard": printWizard,
		"showField": func(inputName string) bool {
			if _, ok := ignoredFields[inputName]; ok {
				return false
			}
			return true
		},
		"genXSRF": func() string {
			return xsrftoken.Generate(serverKey, "user", "wizardSave")
		},
	}

	body := `
	<form id="WizardForm" method="POST" enctype="multipart/form-data">
	<table>
	{{range $k,$v := .}}{{if showField $k}}<tr><td>{{printf "%v" $k}}</td><td><input type="text" size="30" name ="{{printf "%v" $k}}" value="{{printWizard $v}}" ></td></tr>{{end}}{{end}}
	</table>
	<input type="hidden" name="token" value="{{genXSRF}}">
	<input type="submit" form="WizardForm" value="Save"> (Will restart server.)</form>`

	if hasChanged {
		body += `<p> Configuration succesfully rewritten </p>`
	}

	tmpl, err := template.New("wizard").Funcs(funcMap).Parse(topWizard + body + bottomWizard)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
	err = tmpl.Execute(rw, config)
	if err != nil {
		httputil.ServeError(rw, req, err)
		return
	}
}
Пример #3
0
func xsrfMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	session, _ := store.Get(r, cfg.SessionName)
	//TODO aabb234 is not a good value for the function Generate
	session.Values["xsrf"] = xsrftoken.Generate("aabb234", "1", "login")
	next(rw, r)
}
Пример #4
0
// Generate maps CSRF to each request. If this request is a Get request, it will generate a new token.
// Additionally, depending on options set, generated tokens will be sent via Header and/or Cookie.
func Generate(opts *Options) martini.Handler {
	return func(s sessions.Session, c martini.Context, r *http.Request, w http.ResponseWriter) {
		if opts.Header == "" {
			opts.Header = "X-CSRFToken"
		}
		if opts.Form == "" {
			opts.Form = "_csrf"
		}
		if opts.Cookie == "" {
			opts.Cookie = "_csrf"
		}
		if opts.ErrorFunc == nil {
			opts.ErrorFunc = func(w http.ResponseWriter) {
				http.Error(w, "Invalid csrf token.", http.StatusBadRequest)
			}
		}

		x := &csrf{
			Secret:    opts.Secret,
			Header:    opts.Header,
			Form:      opts.Form,
			Cookie:    opts.Cookie,
			ErrorFunc: opts.ErrorFunc,
		}
		c.MapTo(x, (*CSRF)(nil))

		uid := s.Get(opts.SessionKey)
		if uid == nil {
			return
		}
		switch uid.(type) {
		case string:
			x.ID = uid.(string)
		case int64:
			x.ID = strconv.FormatInt(uid.(int64), 10)
		default:
			return
		}

		if r.Method != "GET" || r.Header.Get("Origin") != "" {
			return
		}

		// If cookie present, map existing token, else generate a new one.
		if ex, err := r.Cookie(opts.Cookie); err == nil && ex.Value != "" {
			x.Token = ex.Value
		} else {
			x.Token = xsrftoken.Generate(x.Secret, x.ID, "POST")
			if opts.SetCookie {
				expire := time.Now().AddDate(0, 0, 1)
				// Verify the domain is valid. If it is not, set as empty.
				domain := strings.Split(r.Host, ":")[0]
				if ok, err := regexp.Match(domainReg, []byte(domain)); !ok || err != nil {
					domain = ""
				}

				cookie := &http.Cookie{
					Name:       opts.Cookie,
					Value:      x.Token,
					Path:       "/",
					Domain:     domain,
					Expires:    expire,
					RawExpires: expire.Format(time.UnixDate),
					MaxAge:     0,
					Secure:     opts.Secure,
					HttpOnly:   false,
					Raw:        fmt.Sprintf("%s=%s", opts.Cookie, x.Token),
					Unparsed:   []string{fmt.Sprintf("token=%s", x.Token)},
				}
				http.SetCookie(w, cookie)
			}
		}

		if opts.SetHeader {
			w.Header().Add(opts.Header, x.Token)
		}
	}

}
Пример #5
0
func (sh *SyncHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		if req.FormValue("mode") == "validate" {
			token := req.FormValue("token")
			if xsrftoken.Valid(token, auth.Token(), "user", "runFullValidate") {
				sh.startFullValidation()
				http.Redirect(rw, req, "./", http.StatusFound)
				return
			}
		}
		http.Error(rw, "Bad POST request", http.StatusBadRequest)
		return
	}

	// TODO: remove this lock and instead just call currentStatus,
	// and transition to using that here.
	sh.mu.Lock()
	defer sh.mu.Unlock()
	f := func(p string, a ...interface{}) {
		fmt.Fprintf(rw, p, a...)
	}
	now := time.Now()
	f("<h1>Sync Status (for %s to %s)</h1>", sh.fromName, sh.toName)
	f("<p><b>Current status: </b>%s</p>", html.EscapeString(sh.status))
	if sh.idle {
		return
	}

	f("<h2>Stats:</h2><ul>")
	f("<li>Source: %s</li>", html.EscapeString(storageDesc(sh.from)))
	f("<li>Target: %s</li>", html.EscapeString(storageDesc(sh.to)))
	f("<li>Blobs synced: %d</li>", sh.totalCopies)
	f("<li>Bytes synced: %d</li>", sh.totalCopyBytes)
	f("<li>Blobs yet to copy: %d</li>", len(sh.needCopy))
	f("<li>Bytes yet to copy: %d</li>", sh.bytesRemain)
	if !sh.recentCopyTime.IsZero() {
		f("<li>Most recent copy: %s (%v ago)</li>", sh.recentCopyTime.Format(time.RFC3339), now.Sub(sh.recentCopyTime))
	}
	clarification := ""
	if len(sh.needCopy) == 0 && sh.totalErrors > 0 {
		clarification = "(all since resolved)"
	}
	f("<li>Previous copy errors: %d %s</li>", sh.totalErrors, clarification)
	f("</ul>")

	f("<h2>Validation</h2>")
	if len(sh.vshards) == 0 {
		f("Validation disabled")
		token := xsrftoken.Generate(auth.Token(), "user", "runFullValidate")
		f("<form method='POST'><input type='hidden' name='mode' value='validate'><input type='hidden' name='token' value='%s'><input type='submit' value='Start validation'></form>", token)
	} else {
		f("<p>Background scan of source and destination to ensure that the destination has everything the source does, or is at least enqueued to sync.</p>")
		f("<ul>")
		f("<li>Shards complete: %d/%d (%.1f%%)</li>",
			sh.vshardDone,
			len(sh.vshards),
			100*float64(sh.vshardDone)/float64(len(sh.vshards)))
		f("<li>Source blobs seen: %d</li>", sh.vsrcCount)
		f("<li>Source bytes seen: %d</li>", sh.vsrcBytes)
		f("<li>Dest blobs seen: %d</li>", sh.vdestCount)
		f("<li>Dest bytes seen: %d</li>", sh.vdestBytes)
		f("<li>Blobs found missing &amp; enqueued: %d</li>", sh.vmissing)
		if len(sh.vshardErrs) > 0 {
			f("<li>Validation errors:<ul>\n")
			for _, e := range sh.vshardErrs {
				f("  <li>%s</li>\n", html.EscapeString(e))
			}
			f("</li>\n")
		}
		f("</ul>")
	}

	if len(sh.copying) > 0 {
		f("<h2>Currently Copying</h2><ul>")
		copying := make([]blob.Ref, 0, len(sh.copying))
		for br := range sh.copying {
			copying = append(copying, br)
		}
		sort.Sort(blob.ByRef(copying))
		for _, br := range copying {
			f("<li>%s</li>\n", sh.copying[br])
		}
		f("</ul>")
	}

	recentErrors := make([]blob.Ref, 0, len(sh.recentErrors))
	for _, br := range sh.recentErrors {
		if _, ok := sh.needCopy[br]; ok {
			// Only show it in the web UI if it's still a problem. Blobs that
			// have since succeeded just confused people.
			recentErrors = append(recentErrors, br)
		}
	}
	if len(recentErrors) > 0 {
		f("<h2>Recent Errors</h2><p>Blobs that haven't successfully copied over yet, and their last errors:</p><ul>")
		for _, br := range recentErrors {
			fail := sh.lastFail[br]
			f("<li>%s: %s: %s</li>\n",
				br,
				fail.when.Format(time.RFC3339),
				html.EscapeString(fail.err.Error()))
		}
		f("</ul>")
	}
}
Пример #6
0
func auth(c web.C, w http.ResponseWriter, r *http.Request) {

	session, err := store.Get(r, "p2drive")
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	csrfResponse := r.URL.Query().Get("state")
	code := r.URL.Query().Get("code")
	error := r.URL.Query().Get("error")

	if error == "access_denied" {
		http.Redirect(w, r, "/projects/p2drive/intro", 302)
	}

	b, err := ioutil.ReadFile("client_secret.json")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	config, err := google.ConfigFromJSON(b,
		drive.DriveMetadataReadonlyScope,
		drive.DriveFileScope,
		plus.UserinfoProfileScope)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	config.RedirectURL = redirectUrl

	if csrfResponse == "" || code == "" {
		csrfId, err := uuid.NewV4()
		if err != nil {
			http.Error(w, "couldn't generate uuid", http.StatusInternalServerError)
		}

		session.Values["id"] = csrfId.String()

		csrfToken := xsrftoken.Generate(secretKey, session.Values["id"].(string), "/projects/p2drive/auth")
		session.Values["csrf"] = csrfToken
		session.Save(r, w)

		authURL := config.AuthCodeURL(csrfToken, oauth2.AccessTypeOffline, oauth2.ApprovalForce)

		http.Redirect(w, r, authURL, 302)
		return
	}

	if session.Values["csrf"] != csrfResponse {
		http.Redirect(w, r, "/projects", 400)
	}

	if !xsrftoken.Valid(session.Values["csrf"].(string), secretKey, session.Values["id"].(string), "/projects/p2drive/auth") {
		http.Redirect(w, r, "/projects", 400)
	}

	tok, err := config.Exchange(oauth2.NoContext, code)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

	session.Values["access-token"] = tok
	session.Save(r, w)
	http.Redirect(w, r, "/projects/p2drive/input", 302)
}
Пример #7
0
func csrf(r *http.Request) string {
	user := r.RemoteAddr
	action := r.Method + r.URL.Path
	return xsrftoken.Generate(siteSecret, user, action)
}
Пример #8
0
func (u *User) GenerateNonce(actionID string) string {
	return xsrftoken.Generate(string(xsrfSalt), u.LoginName, actionID)
}