text:
/*
Copyright 2015-2020 Gravitational, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package reversetunnel

import (
	"context"
	"crypto/tls"
	"fmt"
	"io"
	"net"
	"strings"
	"sync"
	"time"

	"github.com/gravitational/trace"
	"github.com/jonboulle/clockwork"
	"github.com/prometheus/client_golang/prometheus"
	log "github.com/sirupsen/logrus"
	"golang.org/x/crypto/ssh"

	"github.com/gravitational/teleport"
	"github.com/gravitational/teleport/api/breaker"
	"github.com/gravitational/teleport/api/constants"
	"github.com/gravitational/teleport/api/types"
	"github.com/gravitational/teleport/api/utils/retryutils"
	apisshutils "github.com/gravitational/teleport/api/utils/sshutils"
	"github.com/gravitational/teleport/lib/auth"
	"github.com/gravitational/teleport/lib/defaults"
	"github.com/gravitational/teleport/lib/events"
	"github.com/gravitational/teleport/lib/limiter"
	"github.com/gravitational/teleport/lib/multiplexer"
	"github.com/gravitational/teleport/lib/observability/metrics"
	"github.com/gravitational/teleport/lib/proxy/peer"
	"github.com/gravitational/teleport/lib/reversetunnelclient"
	"github.com/gravitational/teleport/lib/services"
	"github.com/gravitational/teleport/lib/srv/ingress"
	"github.com/gravitational/teleport/lib/sshca"
	"github.com/gravitational/teleport/lib/sshutils"
	"github.com/gravitational/teleport/lib/utils"
)

var (
	remoteClustersStats = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: teleport.MetricRemoteClusters,
			Help: "Number of inbound connections from remote clusters",
		},
		[]string{"cluster"},
	)

	trustedClustersStats = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: teleport.MetricTrustedClusters,
			Help: "Number of outbound connections to remote clusters",
		},
		[]string{"cluster"},
	)

	prometheusCollectors = []prometheus.Collector{remoteClustersStats, trustedClustersStats}
)

// server is a "reverse tunnel server". it exposes the cluster capabilities
// (like access to a cluster's auth) to remote trusted clients
// (also known as 'reverse tunnel agents').
type server struct {
	sync.RWMutex
	Config

	// localAuthClient provides access to the full Auth Server API for the
	// local cluster.
	localAuthClient auth.ClientI
	// localAccessPoint provides access to a cached subset of the Auth
	// Server API.
	localAccessPoint auth.ProxyAccessPoint

	// srv is the "base class" i.e. the underlying SSH server
	srv     *sshutils.Server
	limiter *limiter.Limiter

	// remoteSites is the list of connected remote clusters
	remoteSites []*remoteSite

	// localSite is the  local (our own cluster) tunnel client.
	localSite *localSite

	// clusterPeers is a map of clusters connected to peer proxies
	// via reverse tunnels
	clusterPeers map[string]*clusterPeers

	// cancel function will cancel the
	cancel context.CancelFunc

	// ctx is a context used for signaling and broadcast
	ctx context.Context

	// log specifies the logger
	log log.FieldLogger

	// proxyWatcher monitors changes to the proxies
	// and broadcasts updates
	proxyWatcher *services.ProxyWatcher

	// offlineThreshold is how long to wait for a keep alive message before
	// marking a reverse tunnel connection as invalid.
	offlineThreshold time.Duration

	// proxySigner is used to sign PROXY headers to securely propagate client IP information
	proxySigner multiplexer.PROXYHeaderSigner
}

// Config is a reverse tunnel server configuration
type Config struct {
	// ID is the ID of this server proxy
	ID string
	// ClusterName is a name of this cluster
	ClusterName string
	// ClientTLS is a TLS config associated with this proxy
	// used to connect to remote auth servers on remote clusters
	ClientTLS *tls.Config
	// Listener is a listener address for reverse tunnel server
	Listener net.Listener
	// HostSigners is a list of host signers
	HostSigners []ssh.Signer
	// HostKeyCallback
	// Limiter is optional request limiter
	Limiter *limiter.Limiter
	// LocalAuthClient provides access to a full AuthClient for the local cluster.
	LocalAuthClient auth.ClientI
	// AccessPoint provides access to a subset of AuthClient of the cluster.
	// AccessPoint caches values and can still return results during connection
	// problems.
	LocalAccessPoint auth.ProxyAccessPoint
	// NewCachingAccessPoint returns new caching access points
	// per remote cluster
	NewCachingAccessPoint auth.NewRemoteProxyCachingAccessPoint
	// Context is a signaling context
	Context context.Context
	// Clock is a clock used in the server, set up to
	// wall clock if not set
	Clock clockwork.Clock

	// KeyGen is a process wide key generator. It is shared to speed up
	// generation of public/private keypairs.
	KeyGen sshca.Authority

	// Ciphers is a list of ciphers that the server supports. If omitted,
	// the defaults will be used.
	Ciphers []string

	// KEXAlgorithms is a list of key exchange (KEX) algorithms that the
	// server supports. If omitted, the defaults will be used.
	KEXAlgorithms []string

	// MACAlgorithms is a list of message authentication codes (MAC) that
	// the server supports. If omitted the defaults will be used.
	MACAlgorithms []string

	// DataDir is a local server data directory
	DataDir string

	// PollingPeriod specifies polling period for internal sync
	// goroutines, used to speed up sync-ups in tests.
	PollingPeriod time.Duration

	// Component is a component used in logs
	Component string

	// Log specifies the logger
	Log log.FieldLogger

	// FIPS means Teleport was started in a FedRAMP/FIPS 140-2 compliant
	// configuration.
	FIPS bool

	// Emitter is event emitter
	Emitter events.StreamEmitter

	// DELETE IN: 8.0.0
	//
	// NewCachingAccessPointOldProxy is an access point that can be configured
	// with the old access point policy until all clusters are migrated to 7.0.0
	// and above.
	NewCachingAccessPointOldProxy auth.NewRemoteProxyCachingAccessPoint

	// PeerClient is a client to peer proxy servers.
	PeerClient *peer.Client

	// LockWatcher is a lock watcher.
	LockWatcher *services.LockWatcher

	// NodeWatcher is a node watcher.
	NodeWatcher *services.NodeWatcher

	// CertAuthorityWatcher is a cert authority watcher.
	CertAuthorityWatcher *services.CertAuthorityWatcher

	// CircuitBreakerConfig configures the auth client circuit breaker
	CircuitBreakerConfig breaker.Config

	// LocalAuthAddresses is a list of auth servers to use when dialing back to
	// the local cluster.
	LocalAuthAddresses []string

	// IngressReporter reports new and active connections.
	IngressReporter *ingress.Reporter

	// PROXYSigner is used to sign PROXY headers to securely propagate client IP information.
	PROXYSigner multiplexer.PROXYHeaderSigner
}

// CheckAndSetDefaults checks parameters and sets default values
func (cfg *Config) CheckAndSetDefaults() error {
	if cfg.ID == "" {
		return trace.BadParameter("missing parameter ID")
	}
	if cfg.ClusterName == "" {
		return trace.BadParameter("missing parameter ClusterName")
	}
	if cfg.ClientTLS == nil {
		return trace.BadParameter("missing parameter ClientTLS")
	}
	if cfg.Listener == nil {
		return trace.BadParameter("missing parameter Listener")
	}
	if cfg.DataDir == "" {
		return trace.BadParameter("missing parameter DataDir")
	}
	if cfg.Emitter == nil {
		return trace.BadParameter("missing parameter Emitter")
	}
	if cfg.Context == nil {
		cfg.Context = context.TODO()
	}
	if cfg.PollingPeriod == 0 {
		cfg.PollingPeriod = defaults.HighResPollingPeriod
	}
	if cfg.Limiter == nil {
		var err error
		cfg.Limiter, err = limiter.NewLimiter(limiter.Config{})
		if err != nil {
			return trace.Wrap(err)
		}
	}
	if cfg.Clock == nil {
		cfg.Clock = clockwork.NewRealClock()
	}
	if cfg.Component == "" {
		cfg.Component = teleport.Component(teleport.ComponentProxy, teleport.ComponentServer)
	}
	logger := cfg.Log
	if cfg.Log == nil {
		logger = log.StandardLogger()
	}
	cfg.Log = logger.WithFields(log.Fields{
		trace.Component: cfg.Component,
	})
	if cfg.LockWatcher == nil {
		return trace.BadParameter("missing parameter LockWatcher")
	}
	if cfg.NodeWatcher == nil {
		return trace.BadParameter("missing parameter NodeWatcher")
	}
	if cfg.CertAuthorityWatcher == nil {
		return trace.BadParameter("missing parameter CertAuthorityWatcher")
	}
	return nil
}

// NewServer creates and returns a reverse tunnel server which is fully
// initialized but hasn't been started yet
func NewServer(cfg Config) (reversetunnelclient.Server, error) {
	err := metrics.RegisterPrometheusCollectors(prometheusCollectors...)
	if err != nil {
		return nil, trace.Wrap(err)
	}

	if err := cfg.CheckAndSetDefaults(); err != nil {
		return nil, trace.Wrap(err)
	}

	netConfig, err := cfg.LocalAccessPoint.GetClusterNetworkingConfig(cfg.Context)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	offlineThreshold := time.Duration(netConfig.GetKeepAliveCountMax()) * netConfig.GetKeepAliveInterval()

	ctx, cancel := context.WithCancel(cfg.Context)

	proxyWatcher, err := services.NewProxyWatcher(ctx, services.ProxyWatcherConfig{
		ResourceWatcherConfig: services.ResourceWatcherConfig{
			Component: cfg.Component,
			Client:    cfg.LocalAccessPoint,
			Log:       cfg.Log,
		},
		ProxiesC:    make(chan []types.Server, 10),
		ProxyGetter: cfg.LocalAccessPoint,
		ProxyDiffer: func(_, _ types.Server) bool {
			return true // we always want to store the most recently heartbeated proxy
		},
	})
	if err != nil {
		cancel()
		return nil, trace.Wrap(err)
	}

	srv := &server{
		Config:           cfg,
		localAuthClient:  cfg.LocalAuthClient,
		localAccessPoint: cfg.LocalAccessPoint,
		limiter:          cfg.Limiter,
		ctx:              ctx,
		cancel:           cancel,
		proxyWatcher:     proxyWatcher,
		clusterPeers:     make(map[string]*clusterPeers),
		log:              cfg.Log,
		offlineThreshold: offlineThreshold,
		proxySigner:      cfg.PROXYSigner,
	}

	localSite, err := newLocalSite(srv, cfg.ClusterName, cfg.LocalAuthAddresses)
	if err != nil {
		return nil, trace.Wrap(err)
	}

	srv.localSite = localSite

	s, err := sshutils.NewServer(
		teleport.ComponentReverseTunnelServer,
		// TODO(klizhentas): improve interface, use struct instead of parameter list
		// this address is not used
		utils.NetAddr{Addr: "127.0.0.1:1", AddrNetwork: "tcp"},
		srv,
		cfg.HostSigners,
		sshutils.AuthMethods{
			PublicKey: srv.keyAuth,
		},
		sshutils.SetLogger(cfg.Log),
		sshutils.SetLimiter(cfg.Limiter),
		sshutils.SetCiphers(cfg.Ciphers),
		sshutils.SetKEXAlgorithms(cfg.KEXAlgorithms),
		sshutils.SetMACAlgorithms(cfg.MACAlgorithms),
		sshutils.SetFIPS(cfg.FIPS),
		sshutils.SetClock(cfg.Clock),
		sshutils.SetIngressReporter(ingress.Tunnel, cfg.IngressReporter),
	)
	if err != nil {
		return nil, err
	}
	srv.srv = s
	go srv.periodicFunctions()
	return srv, nil
}

func remoteClustersMap(rc []types.RemoteCluster) map[string]types.RemoteCluster {
	out := make(map[string]types.RemoteCluster, len(rc))
	for i := range rc {
		out[rc[i].GetName()] = rc[i]
	}
	return out
}

// disconnectClusters disconnects reverse tunnel connections from remote clusters
// that were deleted from the local cluster side and cleans up in memory objects.
// In this case all local trust has been deleted, so all the tunnel connections have to be dropped.
func (s *server) disconnectClusters(connectedRemoteClusters []*remoteSite, remoteMap map[string]types.RemoteCluster) error {
	for _, cluster := range connectedRemoteClusters {
		if _, ok := remoteMap[cluster.GetName()]; !ok {
			s.log.Infof("Remote cluster %q has been deleted. Disconnecting it from the proxy.", cluster.GetName())
			if err := s.onSiteTunnelClose(&alwaysClose{RemoteSite: cluster}); err != nil {
				s.log.Debugf("Failure closing cluster %q: %v.", cluster.GetName(), err)
			}
			remoteClustersStats.DeleteLabelValues(cluster.GetName())
		}
	}
	return nil
}

func (s *server) periodicFunctions() {
	ticker := time.NewTicker(defaults.ResyncInterval)
	defer ticker.Stop()

	if err := s.fetchClusterPeers(); err != nil {
		s.log.Warningf("Failed to fetch cluster peers: %v.", err)
	}
	for {
		select {
		case <-s.ctx.Done():
			s.log.Debugf("Closing.")
			return
		// Proxies have been updated, notify connected agents about the update.
		case proxies := <-s.proxyWatcher.ProxiesC:
			s.fanOutProxies(proxies)
		case <-ticker.C:
			if err := s.fetchClusterPeers(); err != nil {
				s.log.WithError(err).Warn("Failed to fetch cluster peers")
			}

			connectedRemoteClusters := s.getRemoteClusters()

			remoteClusters, err := s.localAccessPoint.GetRemoteClusters()
			if err != nil {
				s.log.WithError(err).Warn("Failed to get remote clusters")
			}

			remoteMap := remoteClustersMap(remoteClusters)

			if err := s.disconnectClusters(connectedRemoteClusters, remoteMap); err != nil {
				s.log.Warningf("Failed to disconnect clusters: %v.", err)
			}

			if err := s.reportClusterStats(connectedRemoteClusters, remoteMap); err != nil {
				s.log.Warningf("Failed to report cluster stats: %v.", err)
			}
		}
	}
}

// fetchClusterPeers pulls back all proxies that have registered themselves
// (created a services.TunnelConnection) in the backend and compares them to
// what was found in the previous iteration and updates the in-memory cluster
// peer map. This map is used later by GetSite(s) to return either local or
// remote site, or if no match, a cluster peer.
func (s *server) fetchClusterPeers() error {
	conns, err := s.LocalAccessPoint.GetAllTunnelConnections()
	if err != nil {
		return trace.Wrap(err)
	}
	newConns := make(map[string]types.TunnelConnection)
	for i := range conns {
		newConn := conns[i]
		// Filter out non-proxy tunnels.
		if newConn.GetType() != types.ProxyTunnel {
			continue
		}
		// Filter out peer records for own proxy.
		if newConn.GetProxyName() == s.ID {
			continue
		}

		// Filter out tunnels which are not online.
		if services.TunnelConnectionStatus(s.Clock, newConn, s.offlineThreshold) != teleport.RemoteClusterStatusOnline {
			continue
		}

		newConns[newConn.GetName()] = newConn
	}
	existingConns := s.existingConns()
	connsToAdd, connsToUpdate, connsToRemove := s.diffConns(newConns, existingConns)
	s.removeClusterPeers(connsToRemove)
	s.updateClusterPeers(connsToUpdate)
	return s.addClusterPeers(connsToAdd)
}

func (s *server) reportClusterStats(connectedRemoteClusters []*remoteSite, remoteMap map[string]types.RemoteCluster) error {
	// zero out counters for remote clusters that have a
	// resource in the backend but no associated remoteSite
	for cluster := range remoteMap {
		var exists bool
		for _, site := range connectedRemoteClusters {
			if site.GetName() == cluster {
				exists = true
				break
			}
		}

		if !exists {
			remoteClustersStats.WithLabelValues(cluster).Set(0)
		}
	}

	// update the counters for any remote clusters that have
	// both a resource in the backend AND an associated remote
	// site with connections
	for _, cluster := range connectedRemoteClusters {
		rc, ok := remoteMap[cluster.GetName()]
		if !ok {
			remoteClustersStats.WithLabelValues(cluster.GetName()).Set(0)
			continue
		}

		if rc.GetConnectionStatus() == teleport.RemoteClusterStatusOnline && cluster.GetStatus() == teleport.RemoteClusterStatusOnline {
			remoteClustersStats.WithLabelValues(cluster.GetName()).Set(float64(cluster.GetTunnelsCount()))
		} else {
			remoteClustersStats.WithLabelValues(cluster.GetName()).Set(0)
		}
	}

	return nil
}

func (s *server) addClusterPeers(conns map[string]types.TunnelConnection) error {
	for key := range conns {
		connInfo := conns[key]
		peer, err := newClusterPeer(s, connInfo, s.offlineThreshold)
		if err != nil {
			return trace.Wrap(err)
		}
		s.addClusterPeer(peer)
	}
	return nil
}

func (s *server) updateClusterPeers(conns map[string]types.TunnelConnection) {
	for key := range conns {
		connInfo := conns[key]
		s.updateClusterPeer(connInfo)
	}
}

func (s *server) addClusterPeer(peer *clusterPeer) {
	s.Lock()
	defer s.Unlock()
	clusterName := peer.connInfo.GetClusterName()
	peers, ok := s.clusterPeers[clusterName]
	if !ok {
		peers = newClusterPeers(clusterName)
		s.clusterPeers[clusterName] = peers
	}
	peers.addPeer(peer)
}

func (s *server) updateClusterPeer(conn types.TunnelConnection) bool {
	s.Lock()
	defer s.Unlock()
	clusterName := conn.GetClusterName()
	peers, ok := s.clusterPeers[clusterName]
	if !ok {
		return false
	}
	return peers.updatePeer(conn)
}

func (s *server) removeClusterPeers(conns []types.TunnelConnection) {
	s.Lock()
	defer s.Unlock()
	for _, conn := range conns {
		peers, ok := s.clusterPeers[conn.GetClusterName()]
		if !ok {
			s.log.Warningf("failed to remove cluster peer, not found peers for %v.", conn)
			continue
		}
		peers.removePeer(conn)
		s.log.Debugf("Removed cluster peer %v.", conn)
	}
}

func (s *server) existingConns() map[string]types.TunnelConnection {
	s.RLock()
	defer s.RUnlock()
	conns := make(map[string]types.TunnelConnection)
	for _, peers := range s.clusterPeers {
		for _, cluster := range peers.peers {
			conns[cluster.connInfo.GetName()] = cluster.connInfo
		}
	}
	return conns
}

func (s *server) diffConns(newConns, existingConns map[string]types.TunnelConnection) (map[string]types.TunnelConnection, map[string]types.TunnelConnection, []types.TunnelConnection) {
	connsToAdd := make(map[string]types.TunnelConnection)
	connsToUpdate := make(map[string]types.TunnelConnection)
	var connsToRemove []types.TunnelConnection

	for existingKey := range existingConns {
		conn := existingConns[existingKey]
		if _, ok := newConns[existingKey]; !ok { // tunnel was removed
			connsToRemove = append(connsToRemove, conn)
		}
	}

	for newKey := range newConns {
		conn := newConns[newKey]
		if _, ok := existingConns[newKey]; !ok { // tunnel was added
			connsToAdd[newKey] = conn
		} else {
			connsToUpdate[newKey] = conn
		}
	}

	return connsToAdd, connsToUpdate, connsToRemove
}

func (s *server) Wait(ctx context.Context) {
	s.srv.Wait(ctx)
}

func (s *server) Start() error {
	go s.srv.Serve(s.Listener)
	return nil
}

func (s *server) Close() error {
	s.cancel()
	s.proxyWatcher.Close()
	return s.srv.Close()
}

// DrainConnections closes the listener and sends reconnects to connected agents without
// closing open connections.
func (s *server) DrainConnections(ctx context.Context) error {
	// Ensure listener is closed before sending reconnects.
	err := s.srv.Close()
	s.RLock()
	s.log.Debugf("Advising reconnect to local site: %s", s.localSite.GetName())
	go s.localSite.adviseReconnect(ctx)

	for _, site := range s.remoteSites {
		s.log.Debugf("Advising reconnect to remote site: %s", site.GetName())
		go site.adviseReconnect(ctx)
	}
	s.RUnlock()

	s.srv.Wait(ctx)
	return trace.Wrap(err)
}

func (s *server) Shutdown(ctx context.Context) error {
	err := s.srv.Shutdown(ctx)

	s.proxyWatcher.Close()
	s.cancel()

	return trace.Wrap(err)
}

func (s *server) HandleNewChan(ctx context.Context, ccx *sshutils.ConnectionContext, nch ssh.NewChannel) {
	// Apply read/write timeouts to the server connection.
	conn := utils.ObeyIdleTimeout(ccx.NetConn,
		s.offlineThreshold,
		"reverse tunnel server")
	sconn := ccx.ServerConn

	channelType := nch.ChannelType()
	switch channelType {
	// Heartbeats can come from nodes or proxies.
	case chanHeartbeat:
		s.handleHeartbeat(conn, sconn, nch)
	// Transport requests come from nodes requesting a connection to the Auth
	// Server through the reverse tunnel.
	case constants.ChanTransport:
		s.handleTransport(sconn, nch)
	default:
		msg := fmt.Sprintf("reversetunnel received unknown channel request %v from %v",
			nch.ChannelType(), sconn)

		// If someone is trying to open a new SSH session by talking to a reverse
		// tunnel, they're most likely using the wrong port number. Give them an
		// explicit hint.
		if channelType == "session" {
			msg = "Cannot open new SSH session on reverse tunnel. Are you connecting to the right port?"
		}
		s.log.Warn(msg)
		s.rejectRequest(nch, ssh.ConnectionFailed, msg)
		return
	}
}

func (s *server) handleTransport(sconn *ssh.ServerConn, nch ssh.NewChannel) {
	s.log.Debugf("Transport request: %v.", nch.ChannelType())
	channel, requestCh, err := nch.Accept()
	if err != nil {
		sconn.Close()
		s.log.Warnf("Failed to accept request: %v.", err)
		return
	}

	t := &transport{
		log:              s.log,
		closeContext:     s.ctx,
		authClient:       s.LocalAccessPoint,
		authServers:      s.LocalAuthAddresses,
		channel:          channel,
		requestCh:        requestCh,
		component:        teleport.ComponentReverseTunnelServer,
		localClusterName: s.ClusterName,
		emitter:          s.Emitter,
		proxySigner:      s.proxySigner,
		sconn:            sconn,
	}
	go t.start()
}

// TODO(awly): unit test this
func (s *server) handleHeartbeat(conn net.Conn, sconn *ssh.ServerConn, nch ssh.NewChannel) {
	s.log.Debugf("New tunnel from %v.", sconn.RemoteAddr())
	if sconn.Permissions.Extensions[utils.ExtIntCertType] != utils.ExtIntCertTypeHost {
		s.log.Error(trace.BadParameter("can't retrieve certificate type in certType"))
		return
	}

	// Extract the role. For proxies, it's another cluster asking to join, for
	// nodes it's a node dialing back.
	val, ok := sconn.Permissions.Extensions[extCertRole]
	if !ok {
		s.log.Errorf("Failed to accept connection, missing %q extension", extCertRole)
		s.rejectRequest(nch, ssh.ConnectionFailed, "unknown role")
		return
	}

	role := types.SystemRole(val)
	switch role {
	// Node is dialing back.
	case types.RoleNode:
		s.handleNewService(role, conn, sconn, nch, types.NodeTunnel)
	// App is dialing back.
	case types.RoleApp:
		s.handleNewService(role, conn, sconn, nch, types.AppTunnel)
	// Kubernetes service is dialing back.
	case types.RoleKube:
		s.handleNewService(role, conn, sconn, nch, types.KubeTunnel)
	// Database proxy is dialing back.
	case types.RoleDatabase:
		s.handleNewService(role, conn, sconn, nch, types.DatabaseTunnel)
	// Proxy is dialing back.
	case types.RoleProxy:
		s.handleNewCluster(conn, sconn, nch)
	case types.RoleWindowsDesktop:
		s.handleNewService(role, conn, sconn, nch, types.WindowsDesktopTunnel)
	case types.RoleOkta:
		s.handleNewService(role, conn, sconn, nch, types.OktaTunnel)
	// Unknown role.
	default:
		s.log.Errorf("Unsupported role attempting to connect: %v", val)
		s.rejectRequest(nch, ssh.ConnectionFailed, fmt.Sprintf("unsupported role %v", val))
	}
}

func (s *server) handleNewService(role types.SystemRole, conn net.Conn, sconn *ssh.ServerConn, nch ssh.NewChannel, connType types.TunnelType) {
	cluster, rconn, err := s.upsertServiceConn(conn, sconn, connType)
	if err != nil {
		s.log.Errorf("Failed to upsert %s: %v.", role, err)
		sconn.Close()
		return
	}

	ch, req, err := nch.Accept()
	if err != nil {
		s.log.Errorf("Failed to accept on channel: %v.", err)
		sconn.Close()
		return
	}

	go cluster.handleHeartbeat(rconn, ch, req)
}

func (s *server) handleNewCluster(conn net.Conn, sshConn *ssh.ServerConn, nch ssh.NewChannel) {
	// add the incoming site (cluster) to the list of active connections:
	site, remoteConn, err := s.upsertRemoteCluster(conn, sshConn)
	if err != nil {
		s.log.Error(trace.Wrap(err))
		s.rejectRequest(nch, ssh.ConnectionFailed, "failed to accept incoming cluster connection")
		return
	}
	// accept the request and start the heartbeat on it:
	ch, req, err := nch.Accept()
	if err != nil {
		s.log.Error(trace.Wrap(err))
		sshConn.Close()
		return
	}
	go site.handleHeartbeat(remoteConn, ch, req)
}

func (s *server) requireLocalAgentForConn(sconn *ssh.ServerConn, connType types.TunnelType) error {
	// Cluster name was extracted from certificate and packed into extensions.
	clusterName := sconn.Permissions.Extensions[extAuthority]
	if strings.TrimSpace(clusterName) == "" {
		return trace.BadParameter("empty cluster name")
	}

	if s.localSite.domainName == clusterName {
		return nil
	}

	return trace.BadParameter("agent from cluster %s cannot register local service %s", clusterName, connType)
}

func (s *server) getTrustedCAKeysByID(id types.CertAuthID) ([]ssh.PublicKey, error) {
	ca, err := s.localAccessPoint.GetCertAuthority(context.TODO(), id, false)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	return sshutils.GetCheckers(ca)
}

func (s *server) keyAuth(conn ssh.ConnMetadata, key ssh.PublicKey) (perm *ssh.Permissions, err error) {
	logger := s.log.WithFields(log.Fields{
		"remote": conn.RemoteAddr(),
		"user":   conn.User(),
	})
	// The crypto/x/ssh package won't log the returned error for us, do it
	// manually.
	defer func() {
		if err != nil {
			logger.Warnf("Failed to authenticate client, err: %v.", err)
		}
	}()

	cert, ok := key.(*ssh.Certificate)
	if !ok {
		return nil, trace.BadParameter("server doesn't support provided key type")
	}

	var clusterName, certRole, certType string
	var caType types.CertAuthType
	switch cert.CertType {
	case ssh.HostCert:
		var ok bool
		clusterName, ok = cert.Extensions[utils.CertExtensionAuthority]
		if !ok || clusterName == "" {
			return nil, trace.BadParameter("certificate missing %q extension; this SSH host certificate was not issued by Teleport or issued by an older version of Teleport; try upgrading your Teleport nodes/proxies", utils.CertExtensionAuthority)
		}
		certRole, ok = cert.Extensions[utils.CertExtensionRole]
		if !ok || certRole == "" {
			return nil, trace.BadParameter("certificate missing %q extension; this SSH host certificate was not issued by Teleport or issued by an older version of Teleport; try upgrading your Teleport nodes/proxies", utils.CertExtensionRole)
		}
		certType = utils.ExtIntCertTypeHost
		caType = types.HostCA
	case ssh.UserCert:
		var ok bool
		clusterName, ok = cert.Extensions[teleport.CertExtensionTeleportRouteToCluster]
		if !ok || clusterName == "" {
			clusterName = s.ClusterName
		}
		encRoles, ok := cert.Extensions[teleport.CertExtensionTeleportRoles]
		if !ok || encRoles == "" {
			return nil, trace.BadParameter("certificate missing %q extension; this SSH user certificate was not issued by Teleport or issued by an older version of Teleport; try upgrading your Teleport proxies/auth servers and logging in again (or exporting an identity file, if that's what you used)", teleport.CertExtensionTeleportRoles)
		}
		roles, err := services.UnmarshalCertRoles(encRoles)
		if err != nil {
			return nil, trace.Wrap(err)
		}
		if len(roles) == 0 {
			return nil, trace.BadParameter("certificate missing roles in %q extension; make sure your user has some roles assigned (or ask your Teleport admin to) and log in again (or export an identity file, if that's what you used)", teleport.CertExtensionTeleportRoles)
		}
		certRole = roles[0]
		certType = utils.ExtIntCertTypeUser
		caType = types.UserCA
	default:
		return nil, trace.BadParameter("unsupported cert type: %v.", cert.CertType)
	}

	if err := s.checkClientCert(logger, conn.User(), clusterName, cert, caType); err != nil {
		return nil, trace.Wrap(err)
	}
	return &ssh.Permissions{
		Extensions: map[string]string{
			extHost:              conn.User(),
			utils.ExtIntCertType: certType,
			extCertRole:          certRole,
			extAuthority:         clusterName,
		},
	}, nil
}

// checkClientCert verifies that client certificate is signed by the recognized
// certificate authority.
func (s *server) checkClientCert(logger *log.Entry, user string, clusterName string, cert *ssh.Certificate, caType types.CertAuthType) error {
	// fetch keys of the certificate authority to check
	// if there is a match
	keys, err := s.getTrustedCAKeysByID(types.CertAuthID{
		Type:       caType,
		DomainName: clusterName,
	})
	if err != nil {
		return trace.Wrap(err)
	}

	// match key of the certificate authority with the signature key
	var match bool
	for _, k := range keys {
		if apisshutils.KeysEqual(k, cert.SignatureKey) {
			match = true
			break
		}
	}
	if !match {
		return trace.NotFound("cluster %v has no matching CA keys", clusterName)
	}

	checker := apisshutils.CertChecker{
		CertChecker: ssh.CertChecker{
			Clock: s.Clock.Now,
		},
		FIPS: s.FIPS,
	}
	if err := checker.CheckCert(user, cert); err != nil {
		return trace.BadParameter(err.Error())
	}

	return nil
}

func (s *server) upsertServiceConn(conn net.Conn, sconn *ssh.ServerConn, connType types.TunnelType) (*localSite, *remoteConn, error) {
	s.Lock()
	defer s.Unlock()

	if err := s.requireLocalAgentForConn(sconn, connType); err != nil {
		return nil, nil, trace.Wrap(err)
	}

	nodeID, ok := sconn.Permissions.Extensions[extHost]
	if !ok {
		return nil, nil, trace.BadParameter("host id not found")
	}

	rconn, err := s.localSite.addConn(nodeID, connType, conn, sconn)
	if err != nil {
		return nil, nil, trace.Wrap(err)
	}

	return s.localSite, rconn, nil
}

func (s *server) upsertRemoteCluster(conn net.Conn, sshConn *ssh.ServerConn) (*remoteSite, *remoteConn, error) {
	domainName := sshConn.Permissions.Extensions[extAuthority]
	if strings.TrimSpace(domainName) == "" {
		return nil, nil, trace.BadParameter("cannot create reverse tunnel: empty cluster name")
	}

	s.Lock()
	defer s.Unlock()

	var site *remoteSite
	for _, st := range s.remoteSites {
		if st.domainName == domainName {
			site = st
			break
		}
	}
	var err error
	var remoteConn *remoteConn
	if site != nil {
		if remoteConn, err = site.addConn(conn, sshConn); err != nil {
			return nil, nil, trace.Wrap(err)
		}
	} else {
		site, err = newRemoteSite(s, domainName, sshConn.Conn)
		if err != nil {
			return nil, nil, trace.Wrap(err)
		}
		if remoteConn, err = site.addConn(conn, sshConn); err != nil {
			return nil, nil, trace.Wrap(err)
		}
		s.remoteSites = append(s.remoteSites, site)
	}
	site.logger.Infof("Connection <- %v, clusters: %d.", conn.RemoteAddr(), len(s.remoteSites))
	// treat first connection as a registered heartbeat,
	// otherwise the connection information will appear after initial
	// heartbeat delay
	go site.registerHeartbeat(s.Clock.Now())
	return site, remoteConn, nil
}

func (s *server) GetSites() ([]reversetunnelclient.RemoteSite, error) {
	s.RLock()
	defer s.RUnlock()
	out := make([]reversetunnelclient.RemoteSite, 0, len(s.remoteSites)+len(s.clusterPeers)+1)
	out = append(out, s.localSite)

	haveLocalConnection := make(map[string]bool)
	for i := range s.remoteSites {
		site := s.remoteSites[i]
		haveLocalConnection[site.GetName()] = true
		out = append(out, site)
	}
	for i := range s.clusterPeers {
		cluster := s.clusterPeers[i]
		if _, ok := haveLocalConnection[cluster.GetName()]; !ok {
			out = append(out, cluster)
		}
	}
	return out, nil
}

func (s *server) getRemoteClusters() []*remoteSite {
	s.RLock()
	defer s.RUnlock()
	out := make([]*remoteSite, len(s.remoteSites))
	copy(out, s.remoteSites)
	return out
}

// GetSite returns a RemoteSite. The first attempt is to find and return a
// remote site and that is what is returned if a remote agent has
// connected to this proxy. Next we loop over local sites and try and try and
// return a local site. If that fails, we return a cluster peer. This happens
// when you hit proxy that has never had an agent connect to it. If you end up
// with a cluster peer your best bet is to wait until the agent has discovered
// all proxies behind a load balancer. Note, the cluster peer is a
// services.TunnelConnection that was created by another proxy.
func (s *server) GetSite(name string) (reversetunnelclient.RemoteSite, error) {
	s.RLock()
	defer s.RUnlock()
	if s.localSite.GetName() == name {
		return s.localSite, nil
	}
	for i := range s.remoteSites {
		if s.remoteSites[i].GetName() == name {
			return s.remoteSites[i], nil
		}
	}
	for i := range s.clusterPeers {
		if s.clusterPeers[i].GetName() == name {
			return s.clusterPeers[i], nil
		}
	}
	return nil, trace.NotFound("cluster %q is not found", name)
}

// GetProxyPeerClient returns the proxy peer client
func (s *server) GetProxyPeerClient() *peer.Client {
	return s.PeerClient
}

// alwaysClose forces onSiteTunnelClose to remove and close
// the site by always returning false from HasValidConnections.
type alwaysClose struct {
	reversetunnelclient.RemoteSite
}

func (a *alwaysClose) HasValidConnections() bool {
	return false
}

// siteCloser is used by onSiteTunnelClose to determine if a site should be closed
// when a tunnel is closed
type siteCloser interface {
	GetName() string
	HasValidConnections() bool
	io.Closer
}

// onSiteTunnelClose will close and stop tracking the site with the given name
// if it has 0 active tunnels. This is done here to ensure that no new tunnels
// can be established while cleaning up a site.
func (s *server) onSiteTunnelClose(site siteCloser) error {
	s.Lock()
	defer s.Unlock()

	if site.HasValidConnections() {
		return nil
	}

	for i := range s.remoteSites {
		if s.remoteSites[i].domainName == site.GetName() {
			s.remoteSites = append(s.remoteSites[:i], s.remoteSites[i+1:]...)
			return trace.Wrap(site.Close())
		}
	}

	return trace.NotFound("site %q is not found", site.GetName())
}

// fanOutProxies is a non-blocking call that updated the watches proxies
// list and notifies all clusters about the proxy list change
func (s *server) fanOutProxies(proxies []types.Server) {
	s.Lock()
	defer s.Unlock()
	s.localSite.fanOutProxies(proxies)

	for _, cluster := range s.remoteSites {
		cluster.fanOutProxies(proxies)
	}
}

func (s *server) rejectRequest(ch ssh.NewChannel, reason ssh.RejectionReason, msg string) {
	if err := ch.Reject(reason, msg); err != nil {
		s.log.Warnf("Failed rejecting new channel request: %v", err)
	}
}

// newRemoteSite helper creates and initializes 'remoteSite' instance
func newRemoteSite(srv *server, domainName string, sconn ssh.Conn) (*remoteSite, error) {
	connInfo, err := types.NewTunnelConnection(
		fmt.Sprintf("%v-%v", srv.ID, domainName),
		types.TunnelConnectionSpecV2{
			ClusterName:   domainName,
			ProxyName:     srv.ID,
			LastHeartbeat: srv.Clock.Now().UTC(),
		},
	)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	connInfo.SetExpiry(srv.Clock.Now().Add(srv.offlineThreshold))

	closeContext, cancel := context.WithCancel(srv.ctx)
	defer func() {
		if err != nil {
			cancel()
		}
	}()
	remoteSite := &remoteSite{
		srv:        srv,
		domainName: domainName,
		connInfo:   connInfo,
		logger: log.WithFields(log.Fields{
			trace.Component: teleport.ComponentReverseTunnelServer,
			trace.ComponentFields: log.Fields{
				"cluster": domainName,
			},
		}),
		ctx:               closeContext,
		cancel:            cancel,
		clock:             srv.Clock,
		offlineThreshold:  srv.offlineThreshold,
		proxySyncInterval: proxySyncInterval,
	}

	// configure access to the full Auth Server API and the cached subset for
	// the local cluster within which reversetunnelclient.Server is running.
	remoteSite.localClient = srv.localAuthClient
	remoteSite.localAccessPoint = srv.localAccessPoint

	clt, _, err := remoteSite.getRemoteClient()
	if err != nil {
		return nil, trace.Wrap(err)
	}
	remoteSite.remoteClient = clt

	remoteVersion, err := getRemoteAuthVersion(closeContext, sconn)
	if err != nil {
		return nil, trace.Wrap(err)
	}

	accessPoint, err := createRemoteAccessPoint(srv, clt, remoteVersion, domainName)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	remoteSite.remoteAccessPoint = accessPoint
	nodeWatcher, err := services.NewNodeWatcher(closeContext, services.NodeWatcherConfig{
		ResourceWatcherConfig: services.ResourceWatcherConfig{
			Component:    srv.Component,
			Client:       accessPoint,
			Log:          srv.Log,
			MaxStaleness: time.Minute,
		},
		NodesGetter: accessPoint,
	})
	if err != nil {
		return nil, trace.Wrap(err)
	}
	remoteSite.nodeWatcher = nodeWatcher
	// instantiate a cache of host certificates for the forwarding server. the
	// certificate cache is created in each site (instead of creating it in
	// reversetunnel.server and passing it along) so that the host certificate
	// is signed by the correct certificate authority.
	certificateCache, err := newHostCertificateCache(srv.Config.KeyGen, srv.localAuthClient)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	remoteSite.certificateCache = certificateCache

	caRetry, err := retryutils.NewLinear(retryutils.LinearConfig{
		First:  utils.HalfJitter(srv.Config.PollingPeriod),
		Step:   srv.Config.PollingPeriod / 5,
		Max:    srv.Config.PollingPeriod,
		Jitter: retryutils.NewHalfJitter(),
		Clock:  srv.Clock,
	})
	if err != nil {
		return nil, trace.Wrap(err)
	}

	remoteWatcher, err := services.NewCertAuthorityWatcher(srv.ctx, services.CertAuthorityWatcherConfig{
		ResourceWatcherConfig: services.ResourceWatcherConfig{
			Component: teleport.ComponentProxy,
			Log:       srv.log,
			Clock:     srv.Clock,
			Client:    remoteSite.remoteAccessPoint,
		},
		Types: []types.CertAuthType{types.HostCA},
	})
	if err != nil {
		return nil, trace.Wrap(err)
	}

	go func() {
		remoteSite.updateCertAuthorities(caRetry, remoteWatcher, remoteVersion)
	}()

	lockRetry, err := retryutils.NewLinear(retryutils.LinearConfig{
		First:  utils.HalfJitter(srv.Config.PollingPeriod),
		Step:   srv.Config.PollingPeriod / 5,
		Max:    srv.Config.PollingPeriod,
		Jitter: retryutils.NewHalfJitter(),
		Clock:  srv.Clock,
	})
	if err != nil {
		return nil, trace.Wrap(err)
	}

	go remoteSite.updateLocks(lockRetry)

	return remoteSite, nil
}

// createRemoteAccessPoint creates a new access point for the remote cluster.
// Checks if the cluster that is connecting is a pre-v13 cluster. If it is,
// we disable the watcher for resources not supported in a v12 leaf cluster:
// - (to fill when we add new resources)
//
// **WARNING**: Ensure that the version below matches the version in which backward incompatible
// changes were introduced so that the cache is created successfully. Otherwise, the remote cache may
// never become healthy due to unknown resources.
func createRemoteAccessPoint(srv *server, clt auth.ClientI, version, domainName string) (auth.RemoteProxyAccessPoint, error) {
	ok, err := utils.MinVerWithoutPreRelease(version, utils.VersionBeforeAlpha("13.0.0"))
	if err != nil {
		return nil, trace.Wrap(err)
	}

	accessPointFunc := srv.Config.NewCachingAccessPoint
	if !ok {
		srv.log.Debugf("cluster %q running %q is connecting, loading old cache policy.", domainName, version)
		accessPointFunc = srv.Config.NewCachingAccessPointOldProxy
	}

	// Configure access to the cached subset of the Auth Server API of the remote
	// cluster this remote site provides access to.
	accessPoint, err := accessPointFunc(clt, []string{"reverse", domainName})
	if err != nil {
		return nil, trace.Wrap(err)
	}

	return accessPoint, nil
}

// getRemoteAuthVersion sends a version request to the remote agent.
func getRemoteAuthVersion(ctx context.Context, sconn ssh.Conn) (string, error) {
	errorCh := make(chan error, 1)
	versionCh := make(chan string, 1)

	go func() {
		ok, payload, err := sconn.SendRequest(versionRequest, true, nil)
		if err != nil {
			errorCh <- err
			return
		}
		if !ok {
			errorCh <- trace.BadParameter("no response to %v request", versionRequest)
			return
		}

		versionCh <- string(payload)
	}()

	select {
	case ver := <-versionCh:
		return ver, nil
	case err := <-errorCh:
		return "", trace.Wrap(err)
	case <-time.After(defaults.WaitCopyTimeout):
		return "", trace.BadParameter("timeout waiting for version")
	case <-ctx.Done():
		return "", trace.Wrap(ctx.Err())
	}
}

const (
	extHost      = "host@teleport"
	extAuthority = "auth@teleport"
	extCertRole  = "role"

	versionRequest = "x-teleport-version"
)

repository: gravitational/teleport

repo_name: gravitational/teleport


text:
# Copyright 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

# This file is included to warn the user about any deprecated modules
# they are using. To create a warning, follow the pattern:
#
#     if(CONFIG_FOO)
#       message(WARNING "The foo module is deprecated. <More information>")
#     endif()
#
# This is done in a separate CMake file because the modules.cmake file
# in this same directory is evaluated before Kconfig runs.

# (No modules are currently deprecated.)

repository: sbourdelin/zephyr

license_type: permissive

repo_name: sbourdelin/zephyr

branch_name: refs/heads/main

extension: cmake


text:
package cli

import "testing"

// Note: add -v to any of these commands to enable verbose logging

func TestPayments(t *testing.T) {
	cli, _ := newTestCLI()
	cli.TestCommand("ns test")
	cli.TestCommand("set config:network fake")

	cli.TestCommand("account new master")
	cli.TestCommand("account new worker")

	expectOutput(t, cli, "error", "pay 4 --from nobody --to worker")
	expectOutput(t, cli, "", "pay 4 --from SAFOI5YIH5MXO6HCICLBG3UYOER6PDYQXHP47JUB7XNWHNT2YISAOMAQ --to worker")
	expectOutput(t, cli, "", "pay 4 --from master --to GBH6GGAPBFH6IXCQBPJ7WSN2WMUFU7PO346BIVZXS6Q22YNFBUNVJS4U")
	expectOutput(t, cli, "", "pay 4 --from master --to worker --memotext hello")

	expectOutput(t, cli, "error", "pay 4 --from master --to worker --memoid hello")
	expectOutput(t, cli, "", "pay 4 --from master --to worker --memoid 234883")

	cli.TestCommand("ns other")
	cli.TestCommand("set config:network fake")
	expectOutput(t, cli, "error", "pay 4 --from master --to worker")

	cli.TestCommand("ns test")
	expectOutput(t, cli, "", "pay 4 --from master --to worker --fund")

	cli.TestCommand("account new issuer-chase")
	cli.TestCommand("account new issuer-citi")

	cli.TestCommand("asset set USD issuer-chase")
	cli.TestCommand("asset set USD-citi issuer-citi --code USD")

	expectOutput(t, cli, "", "pay 4 USD --from master --to worker")
	expectOutput(t, cli, "", "pay 4 USD-citi --from master --to worker")
}

func TestPathPayments(t *testing.T) {
	cli, _ := newTestCLI()
	cli.TestCommand("ns test")
	cli.TestCommand("set config:network fake")

	cli.TestCommand("account new issuer")
	cli.TestCommand("account new mary")
	cli.TestCommand("account new kelly")

	cli.TestCommand("asset set XLM issuer --type native")
	cli.TestCommand("asset set USD issuer")
	cli.TestCommand("asset set EUR issuer")
	cli.TestCommand("asset set INR issuer")

	expectOutput(t, cli, "", "pay 4 USD --from mary --to kelly --with XLM --max 20 --path EUR,INR")
	expectOutput(t, cli, "error", "pay 4 USD --from mary --to kelly --with XLM --path EUR,INR")
	expectOutput(t, cli, "error", "pay 4 USD --from mary --to kelly --with XLM --path BAD")
}

license: MIT

branch_name: refs/heads/master

gha_license_id: MIT

gha_language: Go

extension: go


text:
package gee

import (
	"bytes"
	"compress/zlib"
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"reflect"

	"github.com/golang/protobuf/proto"
)

func check(e error, msg string) {
	if e != nil {
		fmt.Println(msg)
	}
}

func decompress(data []byte) []byte {
	memReader := bytes.NewReader(data)
	zData, err := zlib.NewReader(memReader)
	check(err, "failed to create zlib reader 1")
	defer zData.Close()
	bytes, err := ioutil.ReadAll(zData)
	check(err, "failed to create zlib reader 2")
	return bytes
}

func unMarshalJSONFile(filePath string, jsonObject interface{}) error {
	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		return err
	}
	return json.Unmarshal(file, jsonObject)
}

func writeFile(path string, data []byte) {
	ioutil.WriteFile(path, data, 0644)
}

func readFile(path string) []byte {
	in, err := ioutil.ReadFile(path)
	check(err, "failed to read file from disk")
	return in
}

func unProto(in []byte, pb proto.Message) {
	err := proto.Unmarshal(in, pb)
	check(err, fmt.Sprintf("failed to unmarshal protocol buffer %v\n", reflect.TypeOf(pb)))
}

func isMagic(data []byte) bool {
	return (data[0] == 116 && data[1] == 104 && data[2] == 222 && data[3] == 173) ||
		(data[3] == 116 && data[2] == 104 && data[1] == 222 && data[0] == 173)
}

//XOR encrypts / obfuscates data (in place)
func XOR(data []byte, key []byte, isDecode bool) {
	if isDecode && isMagic(data[0:4]) {
		return //this data isn't XOR encoded
	}

	var dp = 0
	var dpend = len(data)
	var dpend64 = dpend - (dpend % 8)
	var kpend = len(key)
	var kp = 0
	var off = 8

	// while we have a full uint64 (8 bytes) left to do
	// assumes buffer is 64bit aligned (or processor doesn't care)
	for dp < dpend64 {
		// rotate the key each time through by using the offets 16,0,8,16,0,8,...
		off = (off + 8) % 24
		kp = off

		// run through one key length xor'ing one uint64 at a time
		// then drop out to rotate the key for the next bit
		for (dp < dpend64) && (kp < kpend) {
			data[dp] = data[dp] ^ key[kp]
			data[dp+1] = data[dp+1] ^ key[kp+1]
			data[dp+2] = data[dp+2] ^ key[kp+2]
			data[dp+3] = data[dp+3] ^ key[kp+3]
			data[dp+4] = data[dp+4] ^ key[kp+4]
			data[dp+5] = data[dp+5] ^ key[kp+5]
			data[dp+6] = data[dp+6] ^ key[kp+6]
			data[dp+7] = data[dp+7] ^ key[kp+7]
			dp += 8
			kp += 24
		}
	}

	// now the remaining 1 to 7 bytes
	if dp < dpend {
		if kp >= kpend {
			// rotate the key one last time (if necessary)
			off = (off + 8) % 24
			kp = off
		}

		for dp < dpend {
			data[dp] = data[dp] ^ key[kp]
			dp++
			kp++
		}
	}
}

var compressedMagic uint32 = 0x7468dead
var compressedMagicSwap uint32 = 0xadde6874

func uncompressPacket(data []byte) ([]byte, error) {
	// The layout of this decoded data is
	// Magic Uint32 / Size Uint32 / [GZipped chunk of Size bytes]

	// Pullout magic and verify we have the correct data
	buf := bytes.NewBuffer(data)

	var size uint32
	var magic uint32
	var ndn binary.ByteOrder

	binary.Read(buf, binary.LittleEndian, &magic)
	if magic == compressedMagic {
		ndn = binary.LittleEndian
	} else if magic == compressedMagicSwap {
		fmt.Println("SWAP!")
		ndn = binary.BigEndian
	} else {
		fmt.Printf("Bad magic %d %d %d\n", magic, compressedMagic, compressedMagicSwap)
		return []byte{}, fmt.Errorf("bad magic")
	}
	binary.Read(buf, ndn, &size)
	memReader := bytes.NewReader(data[8:])
	zData, err := zlib.NewReader(memReader)
	defer zData.Close()
	if err != nil {
		return []byte{}, fmt.Errorf("failed to create zlib reader")
	}
	bytes, err := ioutil.ReadAll(zData)
	if err != nil {
		return []byte{}, fmt.Errorf("failed to read from zlib stream")
	}

	if size != uint32(len(bytes)) {
		return []byte{}, fmt.Errorf("zlib uncompress returned unexpected length")
	}
	return bytes, nil
}

func compressPacket(data []byte) ([]byte, error) {
	// pack as Magic Uint32 / Size Uint32 / [GZipped chunk of Size bytes]
	var b bytes.Buffer
	binary.Write(&b, binary.LittleEndian, compressedMagic)
	binary.Write(&b, binary.LittleEndian, uint32(len(data)))
	wz := zlib.NewWriter(&b)
	wz.Write(data)
	wz.Flush()
	wz.Close() //not sure why this can't be deferred
	return b.Bytes(), nil
}

repository: wthorp/AGES

repo_name: wthorp/AGES


text:
if(DEFINED HUNTER_CMAKE_PROJECTS_LIBGIT2_HUNTER_CMAKE_)
  return()
else()
  set(HUNTER_CMAKE_PROJECTS_LIBGIT2_HUNTER_CMAKE_ 1)
endif()

include(hunter_add_version)
include(hunter_download)
include(hunter_pick_scheme)

hunter_add_version(
    PACKAGE_NAME Libgit2
    VERSION "0.23.1"
    URL "https://github.com/libgit2/libgit2/archive/v0.23.1.tar.gz"
    SHA1 ebe7c592506dc82a2c0c1011723e8477f31b4aa8
)

hunter_cmake_args(Libgit2 CMAKE_ARGS BUILD_SHARED_LIBS=ON)

hunter_pick_scheme(DEFAULT url_sha1_cmake)
hunter_download(PACKAGE_NAME Libgit2)

repository: daminetreg/hunter

repo_name: daminetreg/hunter


text:
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package secure

import (
	"net/http/httptest"
	"testing"

	"github.com/google/go-safeweb/safehttp"
)

func TestNewMuxConfig(t *testing.T) {
	mux := NewMuxConfig(nil, "foo:8080").Mux()
	mux.Handle("/", safehttp.MethodGet, nil)
	req := httptest.NewRequest(safehttp.MethodGet, "http://foo:8080/", nil)
	rw := httptest.NewRecorder()
	mux.ServeHTTP(rw, req)
}

repository: google/go-safeweb

repo_name: google/go-safeweb


text:
require recipes-kernel/linux-libc-headers/linux-libc-headers.inc

RENESAS_BSP_URL = " \
    git://github.com/renesas-rcar/linux-bsp.git"
BRANCH = "v5.10.41/rcar-5.1.7.rc12"
SRCREV = "e1ca7cab5340e3cb99f9875f482738b241856103"

SRC_URI = "${RENESAS_BSP_URL};branch=${BRANCH};protocol=https"

LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"

S = "${WORKDIR}/git"

repository: renesas-rcar/meta-renesas

repo_name: renesas-rcar/meta-renesas

branch_name: refs/heads/dunfell

gha_language: BitBake

extension: bb


text:
DESCRIPTION = "A library for controlling the SH-Mobile VIO/VEU"
AUTHOR = "Phil Edworthy <phil.edworthy@renesas.com>"
BUGTRACKER = ""

SECTION = "libs"
PRIORITY = "optional"

PR = "r0"

inherit autotools pkgconfig

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://COPYING;md5=838c366f69b72c5df05c96dff79b35f2"

SRCREV = "3cebf3b073c2f22c60109e345670641a77c5981f"
SRC_URI = "git://github.com/renesas-devel/libshvio.git;branch=vio6"
S = "${WORKDIR}/git/"

DEPENDS = "libuiomux libshmeram"
EXTRA_OECONF = "--enable-meram"

do_configure() {
	autoreconf -ivf ${S}
	oe_runconf
}

gha_language: Python


text:
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: taskservice.proto

package service

import (
	fmt "fmt"
	simplcrypto "github.com/cohix/simplcrypto"
	proto "github.com/golang/protobuf/proto"
	auth "github.com/taask/taask-server/auth"
	model "github.com/taask/taask-server/model"
	context "golang.org/x/net/context"
	grpc "google.golang.org/grpc"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package

type QueueTaskRequest struct {
	Task                 *model.Task   `protobuf:"bytes,1,opt,name=Task,proto3" json:"Task,omitempty"`
	Session              *auth.Session `protobuf:"bytes,2,opt,name=Session,proto3" json:"Session,omitempty"`
	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
	XXX_unrecognized     []byte        `json:"-"`
	XXX_sizecache        int32         `json:"-"`
}

func (m *QueueTaskRequest) Reset()         { *m = QueueTaskRequest{} }
func (m *QueueTaskRequest) String() string { return proto.CompactTextString(m) }
func (*QueueTaskRequest) ProtoMessage()    {}
func (*QueueTaskRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_2f9f4b593773f8c1, []int{0}
}

func (m *QueueTaskRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_QueueTaskRequest.Unmarshal(m, b)
}
func (m *QueueTaskRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_QueueTaskRequest.Marshal(b, m, deterministic)
}
func (m *QueueTaskRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_QueueTaskRequest.Merge(m, src)
}
func (m *QueueTaskRequest) XXX_Size() int {
	return xxx_messageInfo_QueueTaskRequest.Size(m)
}
func (m *QueueTaskRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_QueueTaskRequest.DiscardUnknown(m)
}

var xxx_messageInfo_QueueTaskRequest proto.InternalMessageInfo

func (m *QueueTaskRequest) GetTask() *model.Task {
	if m != nil {
		return m.Task
	}
	return nil
}

func (m *QueueTaskRequest) GetSession() *auth.Session {
	if m != nil {
		return m.Session
	}
	return nil
}

type QueueTaskResponse struct {
	UUID                 string   `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *QueueTaskResponse) Reset()         { *m = QueueTaskResponse{} }
func (m *QueueTaskResponse) String() string { return proto.CompactTextString(m) }
func (*QueueTaskResponse) ProtoMessage()    {}
func (*QueueTaskResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_2f9f4b593773f8c1, []int{1}
}

func (m *QueueTaskResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_QueueTaskResponse.Unmarshal(m, b)
}
func (m *QueueTaskResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_QueueTaskResponse.Marshal(b, m, deterministic)
}
func (m *QueueTaskResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_QueueTaskResponse.Merge(m, src)
}
func (m *QueueTaskResponse) XXX_Size() int {
	return xxx_messageInfo_QueueTaskResponse.Size(m)
}
func (m *QueueTaskResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_QueueTaskResponse.DiscardUnknown(m)
}

var xxx_messageInfo_QueueTaskResponse proto.InternalMessageInfo

func (m *QueueTaskResponse) GetUUID() string {
	if m != nil {
		return m.UUID
	}
	return ""
}

type CheckTaskRequest struct {
	UUID                 string        `protobuf:"bytes,1,opt,name=UUID,proto3" json:"UUID,omitempty"`
	Session              *auth.Session `protobuf:"bytes,2,opt,name=Session,proto3" json:"Session,omitempty"`
	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
	XXX_unrecognized     []byte        `json:"-"`
	XXX_sizecache        int32         `json:"-"`
}

func (m *CheckTaskRequest) Reset()         { *m = CheckTaskRequest{} }
func (m *CheckTaskRequest) String() string { return proto.CompactTextString(m) }
func (*CheckTaskRequest) ProtoMessage()    {}
func (*CheckTaskRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_2f9f4b593773f8c1, []int{2}
}

func (m *CheckTaskRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CheckTaskRequest.Unmarshal(m, b)
}
func (m *CheckTaskRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CheckTaskRequest.Marshal(b, m, deterministic)
}
func (m *CheckTaskRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CheckTaskRequest.Merge(m, src)
}
func (m *CheckTaskRequest) XXX_Size() int {
	return xxx_messageInfo_CheckTaskRequest.Size(m)
}
func (m *CheckTaskRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_CheckTaskRequest.DiscardUnknown(m)
}

var xxx_messageInfo_CheckTaskRequest proto.InternalMessageInfo

func (m *CheckTaskRequest) GetUUID() string {
	if m != nil {
		return m.UUID
	}
	return ""
}

func (m *CheckTaskRequest) GetSession() *auth.Session {
	if m != nil {
		return m.Session
	}
	return nil
}

type CheckTaskResponse struct {
	Status               string               `protobuf:"bytes,1,opt,name=Status,proto3" json:"Status,omitempty"`
	Progress             int32                `protobuf:"varint,2,opt,name=Progress,proto3" json:"Progress,omitempty"`
	EncTaskKey           *simplcrypto.Message `protobuf:"bytes,3,opt,name=EncTaskKey,proto3" json:"EncTaskKey,omitempty"`
	Result               *simplcrypto.Message `protobuf:"bytes,4,opt,name=Result,proto3" json:"Result,omitempty"`
	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
	XXX_unrecognized     []byte               `json:"-"`
	XXX_sizecache        int32                `json:"-"`
}

func (m *CheckTaskResponse) Reset()         { *m = CheckTaskResponse{} }
func (m *CheckTaskResponse) String() string { return proto.CompactTextString(m) }
func (*CheckTaskResponse) ProtoMessage()    {}
func (*CheckTaskResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_2f9f4b593773f8c1, []int{3}
}

func (m *CheckTaskResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_CheckTaskResponse.Unmarshal(m, b)
}
func (m *CheckTaskResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_CheckTaskResponse.Marshal(b, m, deterministic)
}
func (m *CheckTaskResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_CheckTaskResponse.Merge(m, src)
}
func (m *CheckTaskResponse) XXX_Size() int {
	return xxx_messageInfo_CheckTaskResponse.Size(m)
}
func (m *CheckTaskResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_CheckTaskResponse.DiscardUnknown(m)
}

var xxx_messageInfo_CheckTaskResponse proto.InternalMessageInfo

func (m *CheckTaskResponse) GetStatus() string {
	if m != nil {
		return m.Status
	}
	return ""
}

func (m *CheckTaskResponse) GetProgress() int32 {
	if m != nil {
		return m.Progress
	}
	return 0
}

func (m *CheckTaskResponse) GetEncTaskKey() *simplcrypto.Message {
	if m != nil {
		return m.EncTaskKey
	}
	return nil
}

func (m *CheckTaskResponse) GetResult() *simplcrypto.Message {
	if m != nil {
		return m.Result
	}
	return nil
}

func init() {
	proto.RegisterType((*QueueTaskRequest)(nil), "taask.server.service.QueueTaskRequest")
	proto.RegisterType((*QueueTaskResponse)(nil), "taask.server.service.QueueTaskResponse")
	proto.RegisterType((*CheckTaskRequest)(nil), "taask.server.service.CheckTaskRequest")
	proto.RegisterType((*CheckTaskResponse)(nil), "taask.server.service.CheckTaskResponse")
}

func init() { proto.RegisterFile("taskservice.proto", fileDescriptor_2f9f4b593773f8c1) }

var fileDescriptor_2f9f4b593773f8c1 = []byte{
	// 401 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0x5f, 0x8f, 0xd2, 0x40,
	0x10, 0x4f, 0x11, 0x50, 0x86, 0x17, 0xd8, 0x08, 0x69, 0xfa, 0x64, 0x9a, 0x28, 0x3e, 0xc8, 0x96,
	0xa0, 0x7e, 0x00, 0x44, 0x1f, 0x8c, 0x9a, 0x68, 0x91, 0xc4, 0x18, 0x63, 0x52, 0xea, 0x84, 0x36,
	0xfd, 0xb3, 0xb5, 0xb3, 0x4b, 0xe4, 0x83, 0xf8, 0x31, 0xee, 0x3b, 0x5e, 0xba, 0xdd, 0x23, 0x85,
	0x83, 0xbb, 0xe4, 0x5e, 0x9a, 0xee, 0xec, 0xef, 0xdf, 0xce, 0x0c, 0x0c, 0x65, 0x40, 0x09, 0x61,
	0xb9, 0x8b, 0x43, 0xe4, 0x45, 0x29, 0xa4, 0x60, 0x4f, 0x65, 0x10, 0x50, 0xc2, 0xab, 0x22, 0x96,
	0xdc, 0xdc, 0x39, 0xa3, 0x40, 0xc9, 0xc8, 0xd3, 0x08, 0xaf, 0xfa, 0xad, 0xc1, 0xce, 0x38, 0x13,
	0x7f, 0x30, 0x35, 0xf5, 0x4a, 0xcb, 0xd4, 0x67, 0xdb, 0x58, 0x46, 0x6a, 0xc3, 0x43, 0x91, 0x79,
	0xa1, 0x88, 0xe2, 0x7f, 0x1e, 0xc5, 0x59, 0x91, 0x86, 0xe5, 0xbe, 0x90, 0xc2, 0xc0, 0x33, 0x24,
	0x0a, 0xb6, 0xc6, 0xd6, 0xdd, 0xc1, 0xe0, 0x9b, 0x42, 0x85, 0xdf, 0x03, 0x4a, 0x7c, 0xfc, 0xab,
	0x90, 0x24, 0x7b, 0x05, 0xed, 0xea, 0x68, 0x5b, 0xcf, 0xac, 0x97, 0xfd, 0xb9, 0xcd, 0x8f, 0x92,
	0x69, 0x67, 0xae, 0xe1, 0x1a, 0xc5, 0xde, 0xc0, 0xe3, 0x15, 0x12, 0xc5, 0x22, 0xb7, 0x5b, 0x9a,
	0xe0, 0x1c, 0x13, 0x74, 0x6c, 0x83, 0xf0, 0x6f, 0xa0, 0xee, 0x04, 0x86, 0x0d, 0x5f, 0x2a, 0x44,
	0x4e, 0xc8, 0x18, 0xb4, 0xd7, 0xeb, 0x8f, 0xef, 0xb5, 0x71, 0xcf, 0xd7, 0xff, 0xee, 0x2f, 0x18,
	0x2c, 0x23, 0x0c, 0x93, 0x66, 0xc0, 0x33, 0xb8, 0x07, 0xc6, 0xb8, 0xb2, 0x60, 0xd8, 0x90, 0x37,
	0x39, 0xc6, 0xd0, 0x5d, 0xc9, 0x40, 0x2a, 0x32, 0x0e, 0xe6, 0xc4, 0x1c, 0x78, 0xf2, 0xb5, 0x14,
	0xdb, 0x12, 0x89, 0xb4, 0x49, 0xc7, 0x3f, 0x9c, 0xd9, 0x5b, 0x80, 0x0f, 0x79, 0x58, 0xc9, 0x7c,
	0xc2, 0xbd, 0xfd, 0x48, 0x47, 0x18, 0x71, 0xdd, 0x7e, 0x5e, 0xf7, 0x9f, 0x7f, 0xa9, 0x3b, 0xef,
	0x37, 0x80, 0x6c, 0x0a, 0x5d, 0x1f, 0x49, 0xa5, 0xd2, 0x6e, 0xdf, 0x45, 0x31, 0xa0, 0xf9, 0xff,
	0x16, 0xf4, 0x2b, 0xea, 0xaa, 0xde, 0x0f, 0xf6, 0x19, 0x60, 0xa1, 0x64, 0xb4, 0x4c, 0x63, 0xcc,
	0x25, 0x3b, 0xf7, 0xe4, 0x85, 0x94, 0x98, 0x15, 0xd2, 0x71, 0x2f, 0xdf, 0x1d, 0xde, 0xfd, 0x03,
	0x3a, 0x7a, 0x28, 0xec, 0x05, 0x3f, 0xb7, 0x8d, 0xfc, 0x74, 0x53, 0x9c, 0xc9, 0xbd, 0x38, 0xa3,
	0xfc, 0x1b, 0x7a, 0x87, 0x36, 0x5f, 0x52, 0x3f, 0x1d, 0xf3, 0x25, 0xf5, 0x5b, 0xf3, 0x9a, 0x59,
	0xef, 0x26, 0x3f, 0x9f, 0x37, 0x56, 0x5f, 0xd3, 0xea, 0xef, 0xb4, 0x26, 0x7b, 0x86, 0xbc, 0xe9,
	0xea, 0xb5, 0x7f, 0x7d, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x91, 0xfa, 0x43, 0x82, 0x03, 0x00,
	0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// TaskServiceClient is the client API for TaskService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type TaskServiceClient interface {
	AuthClient(ctx context.Context, in *auth.Attempt, opts ...grpc.CallOption) (*auth.AttemptResponse, error)
	Queue(ctx context.Context, in *QueueTaskRequest, opts ...grpc.CallOption) (*QueueTaskResponse, error)
	CheckTask(ctx context.Context, in *CheckTaskRequest, opts ...grpc.CallOption) (TaskService_CheckTaskClient, error)
}

type taskServiceClient struct {
	cc *grpc.ClientConn
}

func NewTaskServiceClient(cc *grpc.ClientConn) TaskServiceClient {
	return &taskServiceClient{cc}
}

func (c *taskServiceClient) AuthClient(ctx context.Context, in *auth.Attempt, opts ...grpc.CallOption) (*auth.AttemptResponse, error) {
	out := new(auth.AttemptResponse)
	err := c.cc.Invoke(ctx, "/taask.server.service.TaskService/AuthClient", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *taskServiceClient) Queue(ctx context.Context, in *QueueTaskRequest, opts ...grpc.CallOption) (*QueueTaskResponse, error) {
	out := new(QueueTaskResponse)
	err := c.cc.Invoke(ctx, "/taask.server.service.TaskService/Queue", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *taskServiceClient) CheckTask(ctx context.Context, in *CheckTaskRequest, opts ...grpc.CallOption) (TaskService_CheckTaskClient, error) {
	stream, err := c.cc.NewStream(ctx, &_TaskService_serviceDesc.Streams[0], "/taask.server.service.TaskService/CheckTask", opts...)
	if err != nil {
		return nil, err
	}
	x := &taskServiceCheckTaskClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type TaskService_CheckTaskClient interface {
	Recv() (*CheckTaskResponse, error)
	grpc.ClientStream
}

type taskServiceCheckTaskClient struct {
	grpc.ClientStream
}

func (x *taskServiceCheckTaskClient) Recv() (*CheckTaskResponse, error) {
	m := new(CheckTaskResponse)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// TaskServiceServer is the server API for TaskService service.
type TaskServiceServer interface {
	AuthClient(context.Context, *auth.Attempt) (*auth.AttemptResponse, error)
	Queue(context.Context, *QueueTaskRequest) (*QueueTaskResponse, error)
	CheckTask(*CheckTaskRequest, TaskService_CheckTaskServer) error
}

func RegisterTaskServiceServer(s *grpc.Server, srv TaskServiceServer) {
	s.RegisterService(&_TaskService_serviceDesc, srv)
}

func _TaskService_AuthClient_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(auth.Attempt)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TaskServiceServer).AuthClient(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/taask.server.service.TaskService/AuthClient",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TaskServiceServer).AuthClient(ctx, req.(*auth.Attempt))
	}
	return interceptor(ctx, in, info, handler)
}

func _TaskService_Queue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(QueueTaskRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TaskServiceServer).Queue(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/taask.server.service.TaskService/Queue",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TaskServiceServer).Queue(ctx, req.(*QueueTaskRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _TaskService_CheckTask_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(CheckTaskRequest)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(TaskServiceServer).CheckTask(m, &taskServiceCheckTaskServer{stream})
}

type TaskService_CheckTaskServer interface {
	Send(*CheckTaskResponse) error
	grpc.ServerStream
}

type taskServiceCheckTaskServer struct {
	grpc.ServerStream
}

func (x *taskServiceCheckTaskServer) Send(m *CheckTaskResponse) error {
	return x.ServerStream.SendMsg(m)
}

var _TaskService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "taask.server.service.TaskService",
	HandlerType: (*TaskServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "AuthClient",
			Handler:    _TaskService_AuthClient_Handler,
		},
		{
			MethodName: "Queue",
			Handler:    _TaskService_Queue_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "CheckTask",
			Handler:       _TaskService_CheckTask_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "taskservice.proto",
}

repository: taask/taask-server

repo_name: taask/taask-server


text:
SUMMARY = "library for REVerses ENGineered formats filters"
HOMEPAGE = "http://sf.net/p/libwpd/librevenge/"
LICENSE = "MPL-2.0"
LIC_FILES_CHKSUM = " \
    file://COPYING.MPL;md5=815ca599c9df247a0c7f619bab123dad \
"

SRC_URI = "http://dev-www.libreoffice.org/src/${BPN}-${PV}.tar.bz2"
SRC_URI[md5sum] = "2d4183bf17aea1a71842468a71a68c47"
SRC_URI[sha256sum] = "dedd6fe1f643fc2f254f2ad3719547084bd86bcc482104b995caf3b828368b18"

inherit autotools pkgconfig

DEPENDS = "cppunit zlib boost"

BBCLASSEXTEND = "native"

do_install_append() {
    sed -i '/^Libs:/ s/$/ -lboost_system/' ${D}${libdir}/pkgconfig/librevenge-0.0.pc
}

repository: OSSystems/meta-office

repo_name: OSSystems/meta-office


text:
@InProceedings{lovell12a,
  title = {Exploration and Exploitation with Insufficient Resources},
  author = {Chris Lovell and Gareth Jones and Klaus-Peter Zauner and Steve R. Gunn},
  pages = {37--61},
  abstract = {In physical experimentation, the resources available to discover new knowledge are typically extremely small in comparison to the size and dimensionality of the parameter spaces that can be searched. Additionally, due to the nature of physical experimentation, experimental errors will occur, particularly in biochemical experimentation where the reactants may undetectably denature, or reactant contamination could occur or equipment failure. These errors mean that not all experimental measurements and observations will be accurate or representative of the system being investigated. As the validity of observations is not guaranteed, resources must be split between exploration to discover new knowledge and exploitation to test the validity of the new knowledge. Currently we are investigating the automation of discovery in physical experimentation, with the aim of producing a fully autonomous closed-loop robotic machine capable of autonomous experimentation. This machine will build and evaluate hypotheses, determine experiments to perform and then perform them on an automated lab-on-chip experimentation platform for biochemical response characterisation. In the present work we examine how the trade-off between exploration and exploitation can occur in a situation where the number of experiments that can be performed is extremely small and where the observations returned are sometimes erroneous or unrepresentative of the behaviour being examined. To manage this trade-off we consider the use of a Bayesian notion of surprise, which is used to perform exploration experiments whilst observations are unsurprising from the predictions that can be made and exploits when observations are surprising as they do not match the predicted response.},
  pdf = {http://jmlr.org/proceedings/papers/v26/lovell12a/lovell12a.pdf},
}

repository: mreid/papersite

repo_name: mreid/papersite

gha_language: TeX

extension: bib


text:
include(vcpkg_common_functions)

vcpkg_check_linkage(ONLY_STATIC_LIBRARY)

vcpkg_download_distfile(ARCHIVE
    URLS "http://gamma.cs.unc.edu/software/downloads/SSV/pqp-1.3.tar.gz"
    FILENAME "pqp-1.3.tar.gz"
    SHA512 baad7b050b13a6d13de5110cdec443048a3543b65b0d3b30d1b5f737b46715052661f762ef71345d39978c0c788a30a3a935717664806b4729722ee3594ebdc1
)

vcpkg_extract_source_archive_ex(
    OUT_SOURCE_PATH SOURCE_PATH
    ARCHIVE ${ARCHIVE}
    PATCHES
        fix-math-functions.patch
)

file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH})

vcpkg_configure_cmake(
    SOURCE_PATH ${SOURCE_PATH}
    PREFER_NINJA
)

vcpkg_install_cmake()

# Handle copyright
file(COPY ${CMAKE_CURRENT_LIST_DIR}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/pqp)
file(RENAME ${CURRENT_PACKAGES_DIR}/share/pqp/LICENSE ${CURRENT_PACKAGES_DIR}/share/pqp/copyright)

repository: JackBoos/vcpkg

repo_name: JackBoos/vcpkg

gha_license_id: NOASSERTION


text:
DESCRIPTION = "This module copies and moves directories recursively (or single files, \
well... singley) to an optional depth and attempts to preserve each file or \
directory's mode."

SECTION = "libs"
LICENSE = "Artisticv1 | GPLv1+"
PR = "r0"

MAINTAINER=	"Poky <poky@yoctoproject.org>"
HOMEPAGE=	"https://metacpan.org/release/File-Copy-Recursive"

LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Artistic-1.0;md5=cda03bbdc3c1951996392b872397b798 \
file://${COMMON_LICENSE_DIR}/GPL-1.0;md5=e9e36a9de734199567a4d769498f743d"

SRC_URI = "https://cpan.metacpan.org/authors/id/D/DM/DMUEY/File-Copy-Recursive-0.44.tar.gz"

SRC_URI[md5sum] = "6a89eb075d15df85da1778755c72ba6b"
SRC_URI[sha256sum] = "ae19a0b58dc1b3cded9ba9cfb109288d8973d474c0b4bfd28b27cf60e8ca6ee4"
DEPENDS += "path-tiny-perl-native"
DEPENDS += "test-deep-perl-native"
DEPENDS += "test-fatal-perl-native"
DEPENDS += "test-file-perl-native"
DEPENDS += "test-warnings-perl-native"

S = "${WORKDIR}/File-Copy-Recursive-${PV}"

inherit cpan allarch

BBCLASSEXTEND = "native"

repository: CELLINKAB/meta-cpan

repo_name: CELLINKAB/meta-cpan


text:
SUMMARY = "u-boot uEnv.txt"
DESCRIPTION = "u-boot uEnv.txt"
SECTION = "base"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI += " \
   file://uEnv.txt \
"
S = "${WORKDIR}"

inherit deploy

do_deploy() {
	install -d ${DEPLOYDIR}
	install ${S}/uEnv.txt ${DEPLOYDIR}/uEnv.txt
}

addtask deploy after do_install before do_build

PACKAGE_ARCH = "${MACHINE_ARCH}"
COMPATIBLE_MACHINE = "mx6"


text:
int pressureSensor = A2;
int pressureValue;

void setup() {
    pinMode(pressureSensor, INPUT);
    Particle.variable("pressure", &pressureValue, INT);
}

void loop() {
    pressureValue = analogRead(pressureSensor);
    delay(200);
}

repository: leglars/wakeup

repo_name: leglars/wakeup

extension: ino


text:
@article{Abbott:GW170817Kilonova,
 abstract = {The source of the gravitational-wave (GW) signal GW170817, very likely a binary neutron star merger, was also observed electromagnetically, providing the first multi-messenger observations of this type. The two-week-long electromagnetic (EM) counterpart had a signature indicative of an r -process-induced optical transient known as a kilonova. This Letter examines how the mass of the dynamical ejecta can be estimated without a direct electromagnetic observation of the kilonova, using GW measurements and a phenomenological model calibrated to numerical simulations of mergers with dynamical ejecta. Specifically, we apply the model to the binary masses inferred from the GW measurements, and use the resulting mass of the dynamical ejecta to estimate its contribution (without the effects of wind ejecta) to the corresponding kilonova light curves from various models. The distributions of dynamical ejecta mass range between ##IMG## [http://ej.iop.org/images/2041-8205/850/2/L39/apjlaa9478ieqn1.gif] $M_\mathrmej=10^-3-10^-2\,M_⊙$ for various equations of state, assuming that the neutron stars are rotating slowly. In addition, we use our estimates of the dynamical ejecta mass and the neutron star merger rates inferred from GW170817 to constrain the contribution of events like this to the r -process element abundance in the Galaxy when ejecta mass from post-merger winds is neglected. We find that if ≳10% of the matter dynamically ejected from binary neutron star (BNS) mergers is converted to r -process elements, GW170817-like BNS mergers could fully account for the amount of r -process material observed in the Milky Way.},
 author = {B. P. Abbott et al.},
 journal = {The Astrophysical Journal Letters},
 number = {2},
 pages = {L39},
 title = {Estimating the Contribution of Dynamical Ejecta in the Kilonova Associated with GW170817},
 url = {http://stacks.iop.org/2041-8205/850/i=2/a=L39},
 volume = {850},
 year = {2017}
}

repository: mcoughlin/personal-website

repo_name: mcoughlin/personal-website


text:
@article{https://doi.org/10.1002/2016WR019858,
author = {Heimhuber, V. and Tulbure, M. G. and Broich, M.},
title = {Modeling multidecadal surface water inundation dynamics and key drivers on large river basin scale using multiple time series of Earth-observation and river flow data},
journal = {Water Resources Research},
volume = {53},
number = {2},
pages = {1251-1269},
keywords = {flood modeling, Landsat satellite, Murray-Darling Basin, floodplains, GAM},
doi = {https://doi.org/10.1002/2016WR019858},
url = {https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1002/2016WR019858},
eprint = {https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1002/2016WR019858},
abstract = {Abstract Periodically inundated floodplain areas are hot spots of biodiversity and provide a broad range of ecosystem services but have suffered alarming declines in recent history. Despite their importance, their long-term surface water (SW) dynamics and hydroclimatic drivers remain poorly quantified on continental scales. In this study, we used a 26 year time series of Landsat-derived SW maps in combination with river flow data from 68 gauges and spatial time series of rainfall, evapotranspiration and soil moisture to statistically model SW dynamics as a function of key drivers across Australia's Murray-Darling Basin (∼1 million km2). We fitted generalized additive models for 18,521 individual modeling units made up of 10 × 10 km grid cells, each split into floodplain, floodplain-lake, and nonfloodplain area. Average goodness of fit of models was high across floodplains and floodplain-lakes (r2 > 0.65), which were primarily driven by river flow, and was lower for nonfloodplain areas (r2 > 0.24), which were primarily driven by rainfall. Local climate conditions were more relevant for SW dynamics in the northern compared to the southern basin and had the highest influence in the least regulated and most extended floodplains. We further applied the models of two contrasting floodplain areas to predict SW extents of cloud-affected time steps in the Landsat series during the large 2010 floods with high validated accuracy (r2 > 0.97). Our framework is applicable to other complex river basins across the world and enables a more detailed quantification of large floods and drivers of SW dynamics compared to existing methods.},
year = {2017}
}


text:
package router

import (
	"bytes"
	"fmt"
	"html/template"
	"net/http"
	"os"
	"strings"

	"github.com/andrewarrow/feedback/util"
)

func (r *Router) PlaceContentInLayoutMap(layoutMap map[string]any, flash string, user map[string]any, filename string, vars any) {
	content := new(bytes.Buffer)

	contentVars, ok := vars.(map[string]any)
	if ok {
		contentVars["user"] = user
		vars = contentVars
	}
	r.Template.ExecuteTemplate(content, filename, vars)

	layoutMap["content_vars"] = vars
	layoutMap["footer"] = r.Site.Footer
	layoutMap["site_name"] = r.Site.Title
	layoutMap["flash"] = flash
	layoutMap["user"] = user
	layoutMap["dev_mode"] = os.Getenv("DEV_MODE") != ""
	layoutMap["content"] = template.HTML(content.String())
}

func (r *Router) SendContentInLayout(doZip bool, layout string, layoutMap map[string]any, flash string, user map[string]any, writer http.ResponseWriter,
	filename string, contentVars any, status int) {
	r.PlaceContentInLayoutMap(layoutMap, flash, user, filename, contentVars)
	r.sendZippy(doZip, layout, layoutMap, writer, status)
}

func (r *Router) cookieAuth(c *Context) map[string]any {
	cookie, err := c.Request.Cookie("user_v2")
	var user map[string]any
	if err == nil && cookie.Value != "" {
		user = r.LookupUserByToken(cookie.Value)
	}
	return user
}

func (r *Router) bearerAuth(c *Context) map[string]any {
	var user map[string]any
	auth := util.GetHeader("Authorization", c.Request)
	if auth != "" {
		tokens := strings.Split(auth, " ")
		if len(tokens) == 2 {
			guid := tokens[1]
			user = r.LookupUserByToken(guid)
		}
	}
	return user
}

func (r *Router) RouteFromRequest(writer http.ResponseWriter, request *http.Request) {
	path := request.URL.Path

	c := PrepareContext(r, nil, "/", "", writer, request)
	r.BeforeAll(c)

	var user map[string]any
	if r.CookieAuthFunc != nil {
		user = r.CookieAuthFunc(c)
	}
	if user == nil && r.BearerAuthFunc != nil {
		user = r.BearerAuthFunc(c)
	}

	cookie, err := request.Cookie("flash")
	flash := ""
	if err == nil && cookie.Value != "" {
		flash = cookie.Value
		removeFlash(writer)
	}

	if path == "/" || path == "/"+r.Prefix || path == r.Prefix {
		c := PrepareContext(r, user, "/", flash, writer, request)
		r.pathFuncToRun("/")(c, "", "")
	} else if strings.HasPrefix(path, "/robots.txt") {
		r.HandleAsset("/assets/other/robots.txt", writer, request)
	} else if strings.HasPrefix(path, "/favicon.ico") {
		r.HandleAsset("/assets/other/favicon.ico", writer, request)
	} else if strings.HasPrefix(path, "/assets") {
		r.HandleAsset(path, writer, request)
	} else if strings.HasPrefix(path, "/bucket") {
		r.HandleBucketAsset(path, writer, request)
	} else if strings.HasPrefix(path, "/"+r.Prefix+"/assets") {
		c.tokens = strings.Split(path, "/")
		newPath := "/" + strings.Join(c.tokens[2:], "/")
		fmt.Println(newPath)
		r.HandleAsset(newPath, writer, request)
	} else if strings.HasSuffix(path, "/") {
		http.Redirect(writer, request, path[0:len(path)-1], 301)
	} else if c.Method == "OPTIONS" {
		writer.Header().Set("Allow", "GET,POST,PUT,PATCH")
		writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
		writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		writer.Header().Set("Access-Control-Allow-Headers", "authorization,content-type")
		writer.Header().Set("Access-Control-Allow-Credentials", "true")
		writer.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-inline' http://localhost")
		writer.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
		writer.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubdomains")

	} else {
		writer.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
		writer.Header().Set("Access-Control-Allow-Credentials", "true")
		fmt.Println(request.Method, path)
		path = path + "/"
		if r.Prefix != "" {
			c.tokens = strings.Split(path, "/")
			path = "/" + strings.Join(c.tokens[2:], "/")
		}
		c := PrepareContext(r, user, path, flash, writer, request)
		c.tokens = strings.Split(path, "/")
		contentType := util.GetHeader("Content-Type", request)
		if c.Method == "POST" && contentType == "application/x-www-form-urlencoded" {
			c.ReadFormPost()
		}
		handleContext(c)
		if c.UserRequired && len(c.User) == 0 {
			returnPath := "/sessions/new"
			if r.Prefix != "" {
				returnPath = "/" + r.Prefix + "/sessions/new"
			}
			http.Redirect(c.Writer, c.Request, returnPath, 302)
			return
		}
		if c.NotFound && c.Layout != "json" {
			c.LayoutMap["title"] = "404 not found"
			r.SendContentInLayout(false, c.Layout, c.LayoutMap, "", user, writer, "404.html", nil, 404)
		} else if c.NotFound && c.Layout == "json" {
			c.SendContentAsJsonMessage("not found", 404)
		}
	}
}

func PrepareContext(r *Router, user map[string]any, path, flash string, writer http.ResponseWriter, request *http.Request) *Context {
	c := Context{}
	c.Writer = writer
	c.Request = request
	c.flash = flash
	c.Method = request.Method
	c.Router = r
	c.User = user
	c.path = path
	c.Db = r.Db
	c.Layout = r.DefaultLayout
	c.LayoutMap = map[string]any{}
	return &c
}

repository: andrewarrow/feedback

repo_name: andrewarrow/feedback


text:
package conf

import (
	"github.com/hashicorp/go-hclog"
	"github.com/leonardochaia/vendopunkto/errors"
)

// Manager is in charge of handling config logics
type Manager struct {
	logger  hclog.Logger
	runtime *Runtime
}

// SaveConfiguration updates conf.Runtime with the new key/value pair.
// it will also save the file to disk.
func (m Manager) SaveConfiguration(key string, newValue interface{}) error {
	const op errors.Op = "conf.manager.saveConfiguration"

	logger := m.logger.With("key", key, "value", newValue)
	logger.Info("Updating configuration")
	m.runtime.Set(key, newValue)

	// TODO: validate that the provided values make sense.

	if key == PricingCurrenciesKey {
		pricingCurrencies := m.runtime.GetPricingCurrencies()
		defaultCurrency := m.runtime.GetDefaultPricingCurrency()
		found := false
		for _, c := range pricingCurrencies {
			if c == defaultCurrency {
				found = true
				continue
			}
		}

		if !found {
			logger.Info("The "+DefaultPricingCurrencyKey+" is no longer present in "+PricingCurrenciesKey+
				". Falling back to first pricing currency", "newDefault", pricingCurrencies[0])
			m.runtime.Set(DefaultPricingCurrencyKey, pricingCurrencies[0])
		}
	}

	err := m.runtime.WriteConfig()
	if err != nil {
		return errors.E(op, errors.Parameters, err)
	}

	return nil
}

repository: leonardochaia/vendopunkto

repo_name: leonardochaia/vendopunkto


text:
require cornucopia.inc
DESCRIPTION = "freesmartphone.org dbus resource library"
DEPENDS += "libfso-glib"
SRCREV = "${FSO_CORNUCOPIA_SRCREV}"
PV = "0.1.1+gitr${SRCPV}"
PE = "1"
PR = "${INC_PR}.0"

repository: overo/overo-oe-natty

repo_name: overo/overo-oe-natty

branch_name: HEAD


text:
# Copyright (C) 2014 O.S. Systems Software LTDA.
# Copyright (C) 2014-2016 Freescale Semiconductor
# Copyright 2017-2020 NXP

require u-boot-imx_${PV}.bb
require u-boot-mfgtool.inc

SPL_IMAGE = "${SPL_BINARYNAME}-${MACHINE}-mfgtool-${PV}-${PR}"
SPL_SYMLINK = "${SPL_BINARYNAME}-mfgtool-${MACHINE}"

repository: kevinior/meta-kobo-clara-hd

repo_name: kevinior/meta-kobo-clara-hd


text:
package native

import (
	"fmt"
	"strings"
)

//ruby:nomain
//ruby:module Gorb

type NativeFloatArray struct {
	//ruby:ignore
	List *[]float64
}

func (a *NativeFloatArray) Each(fn func(float64)) {
	for _, v := range *a.List {
		fn(v)
	}
}

//ruby []
func (a *NativeFloatArray) Get(idx int) float64 {
	return (*a.List)[idx]
}

//ruby []=
func (a *NativeFloatArray) Set(idx int, value float64) {
	(*a.List)[idx] = value
}

func (a *NativeFloatArray) Push(value float64) {
	*a.List = append(*a.List, value)
}

func (a *NativeFloatArray) Size() int {
	return len(*a.List)
}

func (a *NativeFloatArray) Length() int {
	return a.Size()
}

func (a *NativeFloatArray) String() string {
	return a.Inspect()
}

func (a *NativeFloatArray) Inspect() string {
	mapped := make([]string, a.Size())
	for i, v := range *a.List {
		mapped[i] = fmt.Sprintf("%f", v)
	}
	return "[" + strings.Join(mapped, ", ") + "]"
}

repository: lsegal/gorb

repo_name: lsegal/gorb


text:
@article{bib:int8_white_paper,
  author    = {Andres Rodriguez and Haihao Shen and et al.},
  title     = {Lower Numerical Precision Deep Learning Inference and Training},
  journal   = {Intel AI Academy},
  year      = {2018},
}

% Ristretto
@article{DBLP:journals/corr/Gysel16,
  author    = {Philipp Gysel},
  title     = {Ristretto: Hardware-Oriented Approximation of Convolutional Neural
               Networks},
  journal   = {CoRR},
  volume    = {abs/1605.06402},
  year      = {2016},
  url       = {http://arxiv.org/abs/1605.06402},
  archivePrefix = {arXiv},
  eprint    = {1605.06402},
  timestamp = {Wed, 07 Jun 2017 14:43:03 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/Gysel16},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@article{DBLP:journals/corr/IoffeS15,
  author    = {Sergey Ioffe and
               Christian Szegedy},
  title     = {Batch Normalization: Accelerating Deep Network Training by Reducing
               Internal Covariate Shift},
  journal   = {CoRR},
  volume    = {abs/1502.03167},
  year      = {2015},
  url       = {http://arxiv.org/abs/1502.03167},
  archivePrefix = {arXiv},
  eprint    = {1502.03167},
  timestamp = {Wed, 07 Jun 2017 14:40:49 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/IoffeS15},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@article{DBLP:journals/corr/HeZRS15,
  author    = {Kaiming He and et al.},
  title     = {Deep Residual Learning for Image Recognition},
  journal   = {CoRR},
  volume    = {abs/1512.03385},
  year      = {2015},
  url       = {http://arxiv.org/abs/1512.03385},
  archivePrefix = {arXiv},
  eprint    = {1512.03385},
  timestamp = {Wed, 07 Jun 2017 14:41:17 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/HeZRS15},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@article{DBLP:journals/corr/SzegedyVISW15,
  author    = {Christian Szegedy and et al.},
  title     = {Rethinking the Inception Architecture for Computer Vision},
  journal   = {CoRR},
  volume    = {abs/1512.00567},
  year      = {2015},
  url       = {http://arxiv.org/abs/1512.00567},
  archivePrefix = {arXiv},
  eprint    = {1512.00567},
  timestamp = {Wed, 07 Jun 2017 14:40:22 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/SzegedyVISW15},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@article{DBLP:journals/corr/LiuAESR15,
  author    = {Wei Liu and et al.},
  title     = {{SSD:} Single Shot MultiBox Detector},
  journal   = {CoRR},
  volume    = {abs/1512.02325},
  year      = {2015},
  url       = {http://arxiv.org/abs/1512.02325},
  archivePrefix = {arXiv},
  eprint    = {1512.02325},
  timestamp = {Wed, 07 Jun 2017 14:42:54 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/LiuAESR15},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@article{ILSVRC15,
Author = {Olga Russakovsky and et al.},
Title = {{ImageNet Large Scale Visual Recognition Challenge}},
Year = {2015},
journal   = {International Journal of Computer Vision (IJCV)},
doi = {10.1007/s11263-015-0816-y},
volume={115},
number={3},
pages={211-252}
}

@Article{Everingham15,
   author = "Everingham, M. and et al.",
   title = "The Pascal Visual Object Classes Challenge: A Retrospective",
   journal = "International Journal of Computer Vision",
   volume = "111",
   year = "2015",
   number = "1",
   month = jan,
   pages = "98--136",
}

@article{DBLP:journals/corr/XuWCL15,
  author    = {Bing Xu and et al.},
  title     = {Empirical Evaluation of Rectified Activations in Convolutional Network},
  journal   = {CoRR},
  volume    = {abs/1505.00853},
  year      = {2015},
  url       = {http://arxiv.org/abs/1505.00853},
  archivePrefix = {arXiv},
  eprint    = {1505.00853},
  timestamp = {Wed, 07 Jun 2017 14:41:27 +0200},
  biburl    = {http://dblp.org/rec/bib/journals/corr/XuWCL15},
  bibsource = {dblp computer science bibliography, http://dblp.org}
}

@misc{request-asplos18,
    title={{ReQuEST at ASPLOS'18:} 1st Reproducible Tournament on Pareto-efficient Image Classification},
    howpublished="\url{http://cknowledge.org/request-cfp-asplos2018.html}",
    year="2018"
}

@inproceedings{cm:29db2248aba45e59:0c7348dfbadd5b95,

   author = {{Moreau}, Thierry and {Lokhmotov}, Anton and {Fursin}, Grigori},
    title = "{Introducing ReQuEST: an Open Platform for Reproducible and Quality-Efficient Systems-ML Tournaments}",
  journal = {ArXiv e-prints},
archivePrefix = "arXiv",
   eprint = {1801.06378},
 primaryClass = "stat.ML",
 keywords = {Statistics - Machine Learning, Computer Science - Learning, Computer Science - Software Engineering},
     year = 2018,
    month = jan,
   adsurl = {http://adsabs.harvard.edu/abs/2018arXiv180106378M},
  adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}


text:
package main

import (
    "fmt"
    "sort"
    "strconv"
)

func calculateSmallestNumber(numList []string, query []int) int {
    var nums []string
    smallestIndex := query[0]
    leftIndex := query[1]
    if leftIndex < 1 {
        return -1
    }
    for _, numStr := range numList {
        if len(numStr) < leftIndex {
            return -1
        }
        numStr = numStr[len(numStr)-leftIndex:]
        nums = append(nums, numStr)
    }
    //fmt.Printf("clean data:%+v\n", nums)

    sortedNum := make([][]interface{}, 0, len(nums))
    var index int
    var num string
    var item []interface{}
    for index, num = range nums {
        item = make([]interface{}, 0)
        item = append(item, num)
        item = append(item, index)
        sortedNum = append(sortedNum, item)
    }
    //fmt.Printf("left data:%+v\n", sortedNum)

    sort.SliceStable(sortedNum, func(i, j int) bool {
        numi := sortedNum[i][0].(string)
        numj := sortedNum[j][0].(string)

        indexi := sortedNum[i][1].(int)
        indexj := sortedNum[j][1].(int)
        return compareMax(numi, numj, indexi, indexj)
    })

    //fmt.Printf("sorted nums:%+v\n", sortedNum)
    var numPair []interface{}
    for index, numPair = range sortedNum {
        if index+1 == smallestIndex {
            return numPair[1].(int)
        }
    }

    return 0
}

func compareMax(a, b string, i, j int) bool {
    if len(a) != len(b) {
        return false
    }
    for index := range a {
        if a[index] < b[index] {
            return true
        } else if a[index] > b[index] {
            return false
        }
    }
    return i < j
}

func calculateSmallestNumber2(numList []string, query []int) int {
    // 找到剪裁之后的第 k 小的数的下标
    // 因为数字太长，不能转成数字去做
    var nums []int64
    smallestIndex := query[0]
    leftIndex := query[1]
    if leftIndex < 1 {
        return -1
    }
    var num int64
    var err error
    for _, numStr := range numList {
        if len(numStr) < leftIndex {
            return -1
        }
        numStr = numStr[len(numStr)-leftIndex:]
        num, err = strconv.ParseInt(numStr, 10, 0)
        if err != nil {
            num = 2 ^ 63
            //return -1
        }
        nums = append(nums, num)
    }
    fmt.Printf("clean data:%+v\n", nums)

    sortedNum := make([][]int64, 0, len(nums))
    var index int
    for index, num = range nums {
        sortedNum = append(sortedNum, []int64{num, int64(index)})
    }
    sort.SliceStable(sortedNum, func(i, j int) bool {
        return sortedNum[i][0] < sortedNum[j][0] || sortedNum[i][1] < sortedNum[j][1]
    })
    //fmt.Printf("sorted nums:%+v\n", sortedNum)
    var numPair []int64
    for index, numPair = range sortedNum {
        if index+1 == smallestIndex {
            return int(numPair[1])
        }
    }
    // 总算把数据都清洗出来了，然后再计算最 k 小的树的下标
    //sortedNum := make([]int, 0, len(nums))
    //for _, num = range nums {
    //    sortedNum = append(sortedNum, num)
    //}
    //sort.Ints(sortedNum)
    //
    //if smallestIndex > len(nums) {
    //    return -1
    //}
    //fmt.Printf("sorted nums:%+v\n", sortedNum)
    //
    //targetNum := sortedNum[smallestIndex-1]
    //var index int
    //fmt.Printf("small index:%d, target num:%+v\n", smallestIndex, targetNum)
    //
    //// 有相同的话，也不是取第一个，也不是取最后一个，而是按下标的先后顺序，取指定位数个
    //for index, num = range nums {
    //    if num == targetNum {
    //        return index
    //    }
    //}
    return -1
}

func smallestTrimmedNumbers(nums []string, queries [][]int) []int {
    // 题目都很难懂
    // 先要把题目做批量操作
    // 找到剪裁之后的第 k 小的数的下标
    // 所以还是排序问题？
    result := make([]int, 0, len(queries))
    for _, query := range queries {
        result = append(result, calculateSmallestNumber(nums, query))
    }
    return result
}

func main() {
    // 做到吐血，真的就是再考各种排序算法的，主要能否 AC，就看排序稳不稳
    // 以及直接暴力的话，看编程语言快不快，（Python 🌶🐔
    s := "123"
    fmt.Printf("3>2:%+v\n", s[2] > s[1])
    fmt.Printf("2>1:%+v\n", s[1] > s[0])
    fmt.Printf("3>1:%+v\n", s[2] > s[0])
    // [2,2,1,0]
    fmt.Println(smallestTrimmedNumbers([]string{"102", "473", "251", "814"}, [][]int{{1, 1}, {2, 3}, {4, 2}, {1, 2}}))
    // {3,0}
    fmt.Println(smallestTrimmedNumbers([]string{"24", "37", "96", "04"}, [][]int{{2, 1}, {2, 2}}))
    // [10,0,9,9,1,6,5,0,9]
    fmt.Println(smallestTrimmedNumbers(
        []string{"325240361872", "440618160237", "785744447413", "820980201297", "470082520306", "874146483840", "425300857082", "088636787077", "813218016629", "459000328006", "188683382600"},
        [][]int{{6, 7}, {4, 4}, {1, 8}, {11, 10}, {4, 8}, {11, 6}, {1, 1}, {3, 1}, {11, 10}},
    ))
    // [26,16,16,13,12,19,13,22,25,11,0,10,19,3,11,10,0,13,3,2,13,5,10,13,2,12,3,12,20]
    fmt.Println(smallestTrimmedNumbers(
        []string{"8331019423839036903", "2215783497319194533", "3244863164120264914", "2723857887888553250", "1069645833408356268", "3799170975306313470", "3300849027471666477", "8896469467436127218", "9595084104356246555", "4601424390471226348", "2777623221871959897", "2660664761264162910", "4830224756337097853", "2239177595019260973", "5704104074606481922", "5158962343348888307", "4957489822885409209", "5533958195540658313", "6712811206814843536", "9775503283462317096", "1975389311819120035", "1292135637676764140", "9838972337538013522", "7609294617007602893", "0186572359592634437", "9236053726818307461", "7264888050655615544", "4990296885039745852", "1417868535147288083"},
        [][]int{{22, 19}, {16, 17}, {10, 7}, {27, 16}, {9, 9}, {21, 4}, {24, 2}, {12, 11}, {2, 5}, {24, 12}, {25, 7}, {7, 13}, {14, 9}, {23, 15}, {18, 17}, {22, 16}, {4, 14}, {14, 17}, {25, 11}, {12, 16}, {29, 3}, {22, 11}, {29, 2}, {24, 2}, {24, 15}, {7, 14}, {7, 3}, {7, 14}, {1, 3}},
    ))
}

repository: windard/leeeeee

repo_name: windard/leeeeee


text:
package null

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
)

// String represents a string that may be null.
// String implements the Scanner interface so
// it can be used as a scan destination.
// String implements the Marshaller interface
// so it can be used to read and write null
// values.
type String struct {
	String string
	Valid  bool // Valid is true if String is not ""
}

func (nt *String) Scan(value interface{}) error {
	if value == nil {
		nt.String = ""
		nt.Valid = false
		return nil
	}
	switch v := value.(type) {
	case string:
		nt.String = v
		nt.Valid = nt.String != ""
	case []byte:
		nt.String = string(v)
		nt.Valid = nt.String != ""
	default:
		return fmt.Errorf("unable to scan into null.String from type %T", value)
	}
	return nil
}

func (nt String) Value() (driver.Value, error) {
	if !nt.Valid {
		return nil, nil
	}
	return nt.String, nil
}

func (nt String) MarshalJSON() ([]byte, error) {
	if !nt.Valid {
		return json.Marshal(nil)
	}
	return json.Marshal(nt.String)
}

func (nt *String) UnmarshalJSON(data []byte) error {
	if data == nil {
		nt.String = ""
	} else if err := json.Unmarshal(data, &nt.String); err != nil {
		return err
	}
	nt.Valid = nt.String != ""
	return nil
}

func NewString(t string) String {
	return String{
		String: t,
		Valid:  t != "",
	}
}

repository: TomWright/null

repo_name: TomWright/null


text:
#include "testApp.h"
#include <GLUT/GLUT.h>
#include <iostream.h>

//--------------------------------------------------------------
void testApp::setRnadColor(int n) {

	switch (n) {
		case 0:
			sf::setColor(.8f, .8f, 0);
			break;
		case 1:
			sf::setColor(.8f, 0, .8f);
			break;
		case 2:
			sf::setColor(0, .8f, .8f);
			break;
		case 3:
			sf::setColor(.8f, .8f, .8f);
			break;
	}
}

//--------------------------------------------------------------
void testApp::setup(){

}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){

	// FILTER_MITCHELL is nice filter
	sf::setFilter(SF_FILTER_MITCHELL);

	// apply anti-aliasing
	sf::smooth();

	int n = 31;

	sf::translate(-12, 0, -12);

	for (int i = -n; i <= n; i++) {
		for (int j = -n; j <= n; j++) {
			setRnadColor(abs((i + j) % 4));
			sf::pushMatrix();
			sf::translate(i, .5f, j);
			sf::scale(.7f, .7f, .7f);
			sf::box(1);
			sf::popMatrix();
		}
	}

	sf::setColor(0, .8f, .8f);
	sf::floor();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){

	if (key == 'r') {
		sf::render();
	}
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

	float dist = h  * 0.5f / tan(ofDegToRad(camera.fovy * 0.5f));
	float aspect = (float)w / h;
	float z = dist / camera.scale * 2;

	sf::setupScreenPerspective(vec3f(z, 28, z), vec3f(0, 0, 0), vec3f(0, 1, 0), 30, aspect, camera.near, camera.far);
}

extension: cpp


text:
DESCRIPTION = "Bootlogo support"
SECTION = "base"
PRIORITY = "required"
LICENSE = "proprietary"
MAINTAINER = "Felix Domke <tmbinc@elitedvb.net>"

BINARY_VERSION = "1"
BINARY_VERSION_mipsel = "8"

IMAGES_VERSION = "1"
IMAGES_VERSION_dm500hd = "2"
IMAGES_VERSION_dm800se = "2"
IMAGES_VERSION_dm7020hd= "2"
IMAGES_VERSION_dm8000 = "2"

PV = "${BINARY_VERSION}.${IMAGES_VERSION}"
PR = "r3"

SRC_URI = "http://sources.dreamboxupdate.com/download/7020/bootlogo-${MACHINE}-${BINARY_VERSION}.elf \
			http://www.upload.metabox.ru/dm800/source/bootlogo.tar.gz"

S = "${WORKDIR}/"

MVI = "bootlogo backdrop bootlogo_wait"
MVI_append_dm800 = " switchoff"

do_install() {
	install -d ${D}/boot
	install -m 0755 ${S}/bootlogo-${MACHINE}-${BINARY_VERSION}.elf ${D}/boot/bootlogo.elf
	for i in ${MVI}; do
		install -m 0755 ${S}/$i.mvi ${D}/boot/$i.mvi;
	done;
}

do_install_dm800() {
	install -d ${D}/boot
	install -d ${D}/usr/share
	install -m 0755 ${S}/bootlogo-${MACHINE}-${BINARY_VERSION}.elf ${D}/boot/bootlogo.elf
	install -m 0755 ${S}/bootlogo.jpg ${D}/boot/bootlogo.jpg
	for i in ${MVI}; do
		install -m 0755 ${S}/$i.mvi ${D}/usr/share/$i.mvi;
		ln -sf /usr/share/$i.mvi ${D}/boot/$i.mvi;
	done;
}

do_install_dm500hd() {
	do_install_dm800
}

do_install_dm800se() {
	do_install_dm800
}

do_install_dm7020hd() {
	do_install_dm800
}

do_install_dm8000() {
	do_install_dm800
}

pkg_preinst() {
	[ -d /proc/stb ] && mount -o rw,remount /boot
}

pkg_postinst() {
	[ -d /proc/stb ] && mount -o ro,remount /boot
}

pkg_prerm() {
	[ -d /proc/stb ] && mount -o rw,remount /boot
}

pkg_postrm() {
	[ -d /proc/stb ] && mount -o ro,remount /boot
}

PACKAGE_ARCH := "${MACHINE_ARCH}"
FILES_${PN} = "/boot /usr/share"

repository: sblavier/openembedded

repo_name: sblavier/openembedded