Example #1
0
// resetAuth is called to reset the authorization on an MDServer
// connection.
func (md *MDServerRemote) resetAuth(ctx context.Context, c keybase1.MetadataClient) (int, error) {

	md.log.Debug("MDServerRemote: resetAuth called")

	isAuthenticated := false
	defer func() {
		md.authenticatedMtx.Lock()
		md.isAuthenticated = isAuthenticated
		md.authenticatedMtx.Unlock()
	}()

	_, _, err := md.config.KBPKI().GetCurrentUserInfo(ctx)
	if err != nil {
		md.log.Debug("MDServerRemote: User logged out, skipping resetAuth")
		return MdServerDefaultPingIntervalSeconds, NoCurrentSessionError{}
	}

	challenge, err := c.GetChallenge(ctx)
	if err != nil {
		md.log.Warning("MDServerRemote: challenge request error: %v", err)
		return 0, err
	}
	md.log.Debug("MDServerRemote: received challenge")

	// get a new signature
	signature, err := md.authToken.Sign(ctx, challenge)
	if err != nil {
		md.log.Warning("MDServerRemote: error signing authentication token: %v", err)
		return 0, err
	}
	md.log.Debug("MDServerRemote: authentication token signed")

	// authenticate
	pingIntervalSeconds, err := c.Authenticate(ctx, signature)
	if err != nil {
		md.log.Warning("MDServerRemote: authentication error: %v", err)
		return 0, err
	}
	md.log.Debug("MDServerRemote: authentication successful; ping interval: %ds", pingIntervalSeconds)

	isAuthenticated = true

	md.authenticatedMtx.Lock()
	if !md.isAuthenticated {
		defer func() {
			// request a list of folders needing rekey action
			if err := md.getFoldersForRekey(ctx, c); err != nil {
				md.log.Warning("MDServerRemote: getFoldersForRekey failed with %v", err)
			}
			md.log.Debug("MDServerRemote: requested list of folders for rekey")
		}()
	}
	// Need to ensure that any conflicting thread gets the updated value
	md.isAuthenticated = true
	md.authenticatedMtx.Unlock()

	return pingIntervalSeconds, nil
}
Example #2
0
// getFoldersForRekey registers to receive updates about folders needing rekey actions.
func (md *MDServerRemote) getFoldersForRekey(ctx context.Context,
	client keybase1.MetadataClient) error {
	// get this device's crypt public key
	cryptKey, err := md.config.KBPKI().GetCurrentCryptPublicKey(ctx)
	if err != nil {
		return err
	}
	return client.GetFoldersForRekey(ctx, cryptKey.kid)
}
Example #3
0
// OnConnect implements the ConnectionHandler interface.
func (md *MDServerRemote) OnConnect(ctx context.Context,
	conn *Connection, client keybase1.GenericClient,
	server *rpc.Server) error {

	md.log.Debug("MDServerRemote: OnConnect called with a new connection")

	// request a challenge -- using md.client here would cause problematic recursion.
	c := keybase1.MetadataClient{Cli: cancelableClient{client}}
	challenge, err := c.GetChallenge(ctx)
	if err != nil {
		md.log.Warning("MDServerRemote: challenge request error: %v", err)
		return err
	}
	md.log.Debug("MDServerRemote: received challenge")

	// get a new signature
	signature, err := md.authToken.Sign(ctx, challenge)
	if err != nil {
		md.log.Warning("MDServerRemote: error signing authentication token: %v", err)
		return err
	}
	md.log.Debug("MDServerRemote: authentication token signed")

	// authenticate
	pingIntervalSeconds, err := c.Authenticate(ctx, signature)
	if err != nil {
		md.log.Warning("MDServerRemote: authentication error: %v", err)
		return err
	}
	md.log.Debug("MDServerRemote: authentication successful; ping interval: %ds", pingIntervalSeconds)

	// we'll get replies asynchronously as to not block the connection
	// for doing other active work for the user. they will be sent to
	// the FolderNeedsRekey handler.
	if err := server.Register(keybase1.MetadataUpdateProtocol(md)); err != nil {
		if _, ok := err.(rpc.AlreadyRegisteredError); !ok {
			return err
		}
	}
	// request a list of folders needing rekey action
	if err := md.getFoldersForRekey(ctx, c); err != nil {
		md.log.Warning("MDServerRemote: getFoldersForRekey failed with %v", err)
	}
	md.log.Debug("MDServerRemote: requested list of folders for rekey")

	// start pinging
	md.resetPingTicker(pingIntervalSeconds)
	return nil
}