AUTH-7480 update fed callback url for login helper
* AUTH-7480 update fed callback url for login helper
This commit is contained in:
parent
50104548cf
commit
8825ceecb5
|
|
@ -32,6 +32,7 @@ type StartOptions struct {
|
||||||
Host string
|
Host string
|
||||||
TLSClientConfig *tls.Config
|
TLSClientConfig *tls.Config
|
||||||
AutoCloseInterstitial bool
|
AutoCloseInterstitial bool
|
||||||
|
IsFedramp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connection wraps up all the needed functions to forward over the tunnel
|
// Connection wraps up all the needed functions to forward over the tunnel
|
||||||
|
|
@ -139,7 +140,7 @@ func BuildAccessRequest(options *StartOptions, log *zerolog.Logger) (*http.Reque
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := token.FetchTokenWithRedirect(req.URL, options.AppInfo, options.AutoCloseInterstitial, log)
|
token, err := token.FetchTokenWithRedirect(req.URL, options.AppInfo, options.AutoCloseInterstitial, options.IsFedramp, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ func StartForwarder(forwarder config.Forwarder, shutdown <-chan struct{}, log *z
|
||||||
options := &carrier.StartOptions{
|
options := &carrier.StartOptions{
|
||||||
OriginURL: forwarder.URL,
|
OriginURL: forwarder.URL,
|
||||||
Headers: headers, //TODO: TUN-2688 support custom headers from config file
|
Headers: headers, //TODO: TUN-2688 support custom headers from config file
|
||||||
|
IsFedramp: forwarder.IsFedramp,
|
||||||
}
|
}
|
||||||
|
|
||||||
// we could add a cmd line variable for this bool if we want the SOCK5 server to be on the client side
|
// we could add a cmd line variable for this bool if we want the SOCK5 server to be on the client side
|
||||||
|
|
@ -92,6 +93,7 @@ func ssh(c *cli.Context) error {
|
||||||
OriginURL: url.String(),
|
OriginURL: url.String(),
|
||||||
Headers: headers,
|
Headers: headers,
|
||||||
Host: url.Host,
|
Host: url.Host,
|
||||||
|
IsFedramp: c.Bool(fedrampFlag),
|
||||||
}
|
}
|
||||||
|
|
||||||
if connectTo := c.String(sshConnectTo); connectTo != "" {
|
if connectTo := c.String(sshConnectTo); connectTo != "" {
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ Host {{.Hostname}}
|
||||||
ProxyCommand {{.Cloudflared}} access ssh --hostname %h
|
ProxyCommand {{.Cloudflared}} access ssh --hostname %h
|
||||||
{{end}}
|
{{end}}
|
||||||
`
|
`
|
||||||
|
fedrampFlag = "fedramp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const sentryDSN = "https://56a9c9fa5c364ab28f34b14f35ea0f1b@sentry.io/189878"
|
const sentryDSN = "https://56a9c9fa5c364ab28f34b14f35ea0f1b@sentry.io/189878"
|
||||||
|
|
@ -79,6 +80,10 @@ func Commands() []*cli.Command {
|
||||||
Aliases: []string{"forward"},
|
Aliases: []string{"forward"},
|
||||||
Category: "Access",
|
Category: "Access",
|
||||||
Usage: "access <subcommand>",
|
Usage: "access <subcommand>",
|
||||||
|
Flags: []cli.Flag{&cli.BoolFlag{
|
||||||
|
Name: fedrampFlag,
|
||||||
|
Usage: "use when performing operations in fedramp account",
|
||||||
|
}},
|
||||||
Description: `Cloudflare Access protects internal resources by securing, authenticating and monitoring access
|
Description: `Cloudflare Access protects internal resources by securing, authenticating and monitoring access
|
||||||
per-user and by application. With Cloudflare Access, only authenticated users with the required permissions are
|
per-user and by application. With Cloudflare Access, only authenticated users with the required permissions are
|
||||||
able to reach sensitive resources. The commands provided here allow you to interact with Access protected
|
able to reach sensitive resources. The commands provided here allow you to interact with Access protected
|
||||||
|
|
@ -326,7 +331,7 @@ func curl(c *cli.Context) error {
|
||||||
log.Info().Msg("You don't have an Access token set. Please run access token <access application> to fetch one.")
|
log.Info().Msg("You don't have an Access token set. Please run access token <access application> to fetch one.")
|
||||||
return run("curl", cmdArgs...)
|
return run("curl", cmdArgs...)
|
||||||
}
|
}
|
||||||
tok, err = token.FetchToken(appURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), log)
|
tok, err = token.FetchToken(appURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), c.Bool(fedrampFlag), log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Err(err).Msg("Failed to refresh token")
|
log.Err(err).Msg("Failed to refresh token")
|
||||||
return err
|
return err
|
||||||
|
|
@ -446,7 +451,7 @@ func sshGen(c *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cfdToken, err := token.FetchTokenWithRedirect(fetchTokenURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), log)
|
cfdToken, err := token.FetchTokenWithRedirect(fetchTokenURL, appInfo, c.Bool(cfdflags.AutoCloseInterstitial), c.Bool(fedrampFlag), log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -546,7 +551,7 @@ func verifyTokenAtEdge(appUrl *url.URL, appInfo *token.AppInfo, c *cli.Context,
|
||||||
if c.IsSet(sshTokenSecretFlag) {
|
if c.IsSet(sshTokenSecretFlag) {
|
||||||
headers.Add(cfAccessClientSecretHeader, c.String(sshTokenSecretFlag))
|
headers.Add(cfAccessClientSecretHeader, c.String(sshTokenSecretFlag))
|
||||||
}
|
}
|
||||||
options := &carrier.StartOptions{AppInfo: appInfo, OriginURL: appUrl.String(), Headers: headers, AutoCloseInterstitial: c.Bool(cfdflags.AutoCloseInterstitial)}
|
options := &carrier.StartOptions{AppInfo: appInfo, OriginURL: appUrl.String(), Headers: headers, AutoCloseInterstitial: c.Bool(cfdflags.AutoCloseInterstitial), IsFedramp: c.Bool(fedrampFlag)}
|
||||||
|
|
||||||
if valid, err := isTokenValid(options, log); err != nil {
|
if valid, err := isTokenValid(options, log); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
baseLoginURL = "https://dash.cloudflare.com/argotunnel"
|
baseLoginURL = "https://dash.cloudflare.com/argotunnel"
|
||||||
callbackURL = "https://login.cloudflareaccess.org/"
|
callbackURL = "https://login.cloudflareaccess.org/"
|
||||||
// For now these are the same but will change in the future once we know which URLs to use (TUN-8872)
|
fedBaseLoginURL = "https://dash.fed.cloudflare.com/argotunnel"
|
||||||
fedBaseLoginURL = "https://dash.cloudflare.com/argotunnel"
|
fedCallbackStoreURL = "https://login.fed.cloudflareaccess.org/"
|
||||||
fedCallbackStoreURL = "https://login.cloudflareaccess.org/"
|
|
||||||
fedRAMPParamName = "fedramp"
|
fedRAMPParamName = "fedramp"
|
||||||
loginURLParamName = "loginURL"
|
loginURLParamName = "loginURL"
|
||||||
callbackURLParamName = "callbackURL"
|
callbackURLParamName = "callbackURL"
|
||||||
|
|
@ -99,6 +98,7 @@ func login(c *cli.Context) error {
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
c.Bool(cfdflags.AutoCloseInterstitial),
|
c.Bool(cfdflags.AutoCloseInterstitial),
|
||||||
|
isFEDRamp,
|
||||||
log,
|
log,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -16,6 +16,7 @@ type Forwarder struct {
|
||||||
TokenClientID string `json:"service_token_id" yaml:"serviceTokenID"`
|
TokenClientID string `json:"service_token_id" yaml:"serviceTokenID"`
|
||||||
TokenSecret string `json:"secret_token_id" yaml:"serviceTokenSecret"`
|
TokenSecret string `json:"secret_token_id" yaml:"serviceTokenSecret"`
|
||||||
Destination string `json:"destination"`
|
Destination string `json:"destination"`
|
||||||
|
IsFedramp bool `json:"is_fedramp" yaml:"isFedramp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tunnel represents a tunnel that should be started
|
// Tunnel represents a tunnel that should be started
|
||||||
|
|
@ -46,24 +47,24 @@ type Root struct {
|
||||||
|
|
||||||
// Hash returns the computed values to see if the forwarder values change
|
// Hash returns the computed values to see if the forwarder values change
|
||||||
func (f *Forwarder) Hash() string {
|
func (f *Forwarder) Hash() string {
|
||||||
h := md5.New()
|
h := sha256.New()
|
||||||
io.WriteString(h, f.URL)
|
_, _ = io.WriteString(h, f.URL)
|
||||||
io.WriteString(h, f.Listener)
|
_, _ = io.WriteString(h, f.Listener)
|
||||||
io.WriteString(h, f.TokenClientID)
|
_, _ = io.WriteString(h, f.TokenClientID)
|
||||||
io.WriteString(h, f.TokenSecret)
|
_, _ = io.WriteString(h, f.TokenSecret)
|
||||||
io.WriteString(h, f.Destination)
|
_, _ = io.WriteString(h, f.Destination)
|
||||||
return fmt.Sprintf("%x", h.Sum(nil))
|
return fmt.Sprintf("%x", h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash returns the computed values to see if the forwarder values change
|
// Hash returns the computed values to see if the forwarder values change
|
||||||
func (r *DNSResolver) Hash() string {
|
func (r *DNSResolver) Hash() string {
|
||||||
h := md5.New()
|
h := sha256.New()
|
||||||
io.WriteString(h, r.Address)
|
_, _ = io.WriteString(h, r.Address)
|
||||||
io.WriteString(h, strings.Join(r.Bootstraps, ","))
|
_, _ = io.WriteString(h, strings.Join(r.Bootstraps, ","))
|
||||||
io.WriteString(h, strings.Join(r.Upstreams, ","))
|
_, _ = io.WriteString(h, strings.Join(r.Upstreams, ","))
|
||||||
io.WriteString(h, fmt.Sprintf("%d", r.Port))
|
_, _ = io.WriteString(h, fmt.Sprintf("%d", r.Port))
|
||||||
io.WriteString(h, fmt.Sprintf("%d", r.MaxUpstreamConnections))
|
_, _ = io.WriteString(h, fmt.Sprintf("%d", r.MaxUpstreamConnections))
|
||||||
io.WriteString(h, fmt.Sprintf("%v", r.Enabled))
|
_, _ = io.WriteString(h, fmt.Sprintf("%v", r.Enabled))
|
||||||
return fmt.Sprintf("%x", h.Sum(nil))
|
return fmt.Sprintf("%x", h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,18 +185,18 @@ func Init(version string) {
|
||||||
|
|
||||||
// FetchTokenWithRedirect will either load a stored token or generate a new one
|
// FetchTokenWithRedirect will either load a stored token or generate a new one
|
||||||
// it appends the full url as the redirect URL to the access cli request if opening the browser
|
// it appends the full url as the redirect URL to the access cli request if opening the browser
|
||||||
func FetchTokenWithRedirect(appURL *url.URL, appInfo *AppInfo, autoClose bool, log *zerolog.Logger) (string, error) {
|
func FetchTokenWithRedirect(appURL *url.URL, appInfo *AppInfo, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {
|
||||||
return getToken(appURL, appInfo, false, autoClose, log)
|
return getToken(appURL, appInfo, false, autoClose, isFedramp, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchToken will either load a stored token or generate a new one
|
// FetchToken will either load a stored token or generate a new one
|
||||||
// it appends the host of the appURL as the redirect URL to the access cli request if opening the browser
|
// it appends the host of the appURL as the redirect URL to the access cli request if opening the browser
|
||||||
func FetchToken(appURL *url.URL, appInfo *AppInfo, autoClose bool, log *zerolog.Logger) (string, error) {
|
func FetchToken(appURL *url.URL, appInfo *AppInfo, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {
|
||||||
return getToken(appURL, appInfo, true, autoClose, log)
|
return getToken(appURL, appInfo, true, autoClose, isFedramp, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getToken will either load a stored token or generate a new one
|
// getToken will either load a stored token or generate a new one
|
||||||
func getToken(appURL *url.URL, appInfo *AppInfo, useHostOnly bool, autoClose bool, log *zerolog.Logger) (string, error) {
|
func getToken(appURL *url.URL, appInfo *AppInfo, useHostOnly bool, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {
|
||||||
if token, err := GetAppTokenIfExists(appInfo); token != "" && err == nil {
|
if token, err := GetAppTokenIfExists(appInfo); token != "" && err == nil {
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
@ -249,19 +249,19 @@ func getToken(appURL *url.URL, appInfo *AppInfo, useHostOnly bool, autoClose boo
|
||||||
return appToken, nil
|
return appToken, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return getTokensFromEdge(appURL, appInfo.AppAUD, appTokenPath, orgTokenPath, useHostOnly, autoClose, log)
|
return getTokensFromEdge(appURL, appInfo.AppAUD, appTokenPath, orgTokenPath, useHostOnly, autoClose, isFedramp, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTokensFromEdge will attempt to use the transfer service to retrieve an app and org token, save them to disk,
|
// getTokensFromEdge will attempt to use the transfer service to retrieve an app and org token, save them to disk,
|
||||||
// and return the app token.
|
// and return the app token.
|
||||||
func getTokensFromEdge(appURL *url.URL, appAUD, appTokenPath, orgTokenPath string, useHostOnly bool, autoClose bool, log *zerolog.Logger) (string, error) {
|
func getTokensFromEdge(appURL *url.URL, appAUD, appTokenPath, orgTokenPath string, useHostOnly bool, autoClose bool, isFedramp bool, log *zerolog.Logger) (string, error) {
|
||||||
fmt.Println("Get tokens from edge ", autoClose)
|
fmt.Println("Get tokens from edge ", autoClose)
|
||||||
// If no org token exists or if it couldn't be exchanged for an app token, then run the transfer service flow.
|
// If no org token exists or if it couldn't be exchanged for an app token, then run the transfer service flow.
|
||||||
|
|
||||||
// this weird parameter is the resource name (token) and the key/value
|
// this weird parameter is the resource name (token) and the key/value
|
||||||
// we want to send to the transfer service. the key is token and the value
|
// we want to send to the transfer service. the key is token and the value
|
||||||
// is blank (basically just the id generated in the transfer service)
|
// is blank (basically just the id generated in the transfer service)
|
||||||
resourceData, err := RunTransfer(appURL, appAUD, keyName, keyName, "", true, useHostOnly, autoClose, log)
|
resourceData, err := RunTransfer(appURL, appAUD, keyName, keyName, "", true, useHostOnly, autoClose, isFedramp, log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "failed to run transfer service")
|
return "", errors.Wrap(err, "failed to run transfer service")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
baseStoreURL = "https://login.cloudflareaccess.org/"
|
baseStoreURL = "https://login.cloudflareaccess.org/"
|
||||||
|
fedStoreURL = "https://login.fed.cloudflareaccess.org/"
|
||||||
clientTimeout = time.Second * 60
|
clientTimeout = time.Second * 60
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ const (
|
||||||
// The "dance" we refer to is building a HTTP request, opening that in a browser waiting for
|
// The "dance" we refer to is building a HTTP request, opening that in a browser waiting for
|
||||||
// the user to complete an action, while it long polls in the background waiting for an
|
// the user to complete an action, while it long polls in the background waiting for an
|
||||||
// action to be completed to download the resource.
|
// action to be completed to download the resource.
|
||||||
func RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string, shouldEncrypt bool, useHostOnly bool, autoClose bool, log *zerolog.Logger) ([]byte, error) {
|
func RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string, shouldEncrypt bool, useHostOnly bool, autoClose bool, fedramp bool, log *zerolog.Logger) ([]byte, error) {
|
||||||
encrypterClient, err := NewEncrypter("cloudflared_priv.pem", "cloudflared_pub.pem")
|
encrypterClient, err := NewEncrypter("cloudflared_priv.pem", "cloudflared_pub.pem")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -45,8 +46,14 @@ func RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string,
|
||||||
|
|
||||||
var resourceData []byte
|
var resourceData []byte
|
||||||
|
|
||||||
|
storeURL := baseStoreURL
|
||||||
|
|
||||||
|
if fedramp {
|
||||||
|
storeURL = fedStoreURL
|
||||||
|
}
|
||||||
|
|
||||||
if shouldEncrypt {
|
if shouldEncrypt {
|
||||||
buf, key, err := transferRequest(baseStoreURL+"transfer/"+encrypterClient.PublicKey(), log)
|
buf, key, err := transferRequest(storeURL+"transfer/"+encrypterClient.PublicKey(), log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +69,7 @@ func RunTransfer(transferURL *url.URL, appAUD, resourceName, key, value string,
|
||||||
|
|
||||||
resourceData = decrypted
|
resourceData = decrypted
|
||||||
} else {
|
} else {
|
||||||
buf, _, err := transferRequest(baseStoreURL+encrypterClient.PublicKey(), log)
|
buf, _, err := transferRequest(storeURL+encrypterClient.PublicKey(), log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +138,12 @@ func poll(client *http.Client, requestURL string, log *zerolog.Logger) ([]byte,
|
||||||
// ignore everything other than server errors as the resource
|
// ignore everything other than server errors as the resource
|
||||||
// may not exist until the user does the interaction
|
// may not exist until the user does the interaction
|
||||||
if resp.StatusCode >= 500 {
|
if resp.StatusCode >= 500 {
|
||||||
return nil, "", fmt.Errorf("error on request %d", resp.StatusCode)
|
buf := new(bytes.Buffer)
|
||||||
|
if _, err := io.Copy(buf, resp.Body); err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, "", fmt.Errorf("error on request %d: %s", resp.StatusCode, buf.String())
|
||||||
}
|
}
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Info().Msg("Waiting for login...")
|
log.Info().Msg("Waiting for login...")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue