Пример #1
0
// CreatePkiDirectories creates the directory structures for storing the public and private keys.
func CreatePkiDirectories(logger log.Logger, root string) error {
	pki := path.Join(root, "pki")

	// Create pki directory
	if err := os.MkdirAll(pki, os.ModeDir|0755); err != nil {
		logger.Warn("Could not create pki/ directory", "err", err.Error())
		return err
	}

	// Create public directory
	if err := os.MkdirAll(path.Join(pki, "public"), os.ModeDir|0755); err != nil {
		logger.Warn("Could not create pki/public/ directory", "err", err.Error())
		return err
	}

	// Create private directory
	if err := os.MkdirAll(path.Join(pki, "private"), os.ModeDir|0755); err != nil {
		logger.Warn("Could not create pki/private/ directory", "err", err.Error())
		return err
	}

	// Create reqs directory
	if err := os.MkdirAll(path.Join(pki, "reqs"), os.ModeDir|0755); err != nil {
		logger.Warn("Could not create pki/reqs/ directory", "err", err.Error())
		return err
	}

	return nil
}
Пример #2
0
// ReadPrivateKey reads a private key file
func ReadPrivateKey(logger log.Logger, keyFile string) (privateKey ssh.Signer, err error) {

	// Read SSH Key
	keyBytes, err := ioutil.ReadFile(keyFile)
	if err != nil {
		logger.Warn("Private key could not be read", "error", string(err.Error()))
		return
	}

	// Get private key
	privateKey, err = ssh.ParsePrivateKey(keyBytes)
	if err != nil {
		logger.Warn("Private key could not be parsed", "error", err.Error())
	}
	return
}
Пример #3
0
// InitializeMainConfig sets up the config options for the kappa command
func InitializeMainConfig(logger log.Logger) error {
	viper.SetConfigFile("config")
	viper.AddConfigPath(ConfigPath)

	// Read configuration file
	logger.Info("Reading configuration file")
	err := viper.ReadInConfig()
	if err != nil {
		logger.Warn("Unable to locate configuration file.")
	}

	if kappaCmd.PersistentFlags().Lookup("config").Changed {
		logger.Info("", "ConfigPath", ConfigPath)
		viper.Set("ConfigPath", ConfigPath)
	}

	return nil
}
Пример #4
0
func handleTCPConnection(logger log.Logger, conn net.Conn, sshConfig *ssh.ServerConfig, system datamodel.System) {

	// Open SSH connection
	sshConn, channels, requests, err := ssh.NewServerConn(conn, sshConfig)
	if err != nil {
		logger.Warn("SSH handshake failed")
		return
	}

	// Get user if exists, otherwise return error
	users, _ := system.Users()
	user, _ := users.Get(sshConn.Permissions.Extensions["username"])

	logger.Debug("Handshake successful")
	defer sshConn.Conn.Close()

	// Discard requests
	go ssh.DiscardRequests(requests)

	for ch := range channels {
		t := ch.ChannelType()

		if t != "session" && t != "kappa-client" {
			logger.Info("UnknownChannelType", "type", t)
			ch.Reject(ssh.UnknownChannelType, t)
			break
		}

		// Accept channel
		channel, requests, err := ch.Accept()
		if err != nil {
			logger.Warn("Error creating channel")
			continue
		}

		if t == "session" {
			go handleSessionRequests(logger, channel, requests, system, user)
		} else if t == "kappa-client" {
			go handleChannelRequests(logger, channel, requests, system, user)
		}
	}
}
Пример #5
0
func reject(chType string, uri *url.URL, ch ssh.NewChannel, logger log.Logger) bool {
	if uri.Scheme != "" {
		logger.Warn("URI schemes not supported", "type", chType)
		ch.Reject(SchemeNotSupported, "schemes are not supported in the channel URI")
		return true
	} else if uri.User != nil {
		logger.Warn("URI users not supported", "type", chType)
		ch.Reject(UserNotSupported, "users are not supported in the channel URI")
		return true
	} else if uri.Host != "" {
		logger.Warn("URI hosts not supported", "type", chType)
		ch.Reject(HostNotSupported, "hosts are not supported in the channel URI")
		return true
	}
	return false
}
Пример #6
0
// newConsulBackend constructs a Consul backend using the given API client
// and the prefix in the KV store.
func newConsulBackend(conf map[string]string, logger log.Logger) (Backend, error) {
	// Get the path in Consul
	path, ok := conf["path"]
	if !ok {
		path = "vault/"
	}
	if logger.IsDebug() {
		logger.Debug("physical/consul: config path set", "path", path)
	}

	// Ensure path is suffixed but not prefixed
	if !strings.HasSuffix(path, "/") {
		logger.Warn("physical/consul: appending trailing forward slash to path")
		path += "/"
	}
	if strings.HasPrefix(path, "/") {
		logger.Warn("physical/consul: trimming path of its forward slash")
		path = strings.TrimPrefix(path, "/")
	}

	// Allow admins to disable consul integration
	disableReg, ok := conf["disable_registration"]
	var disableRegistration bool
	if ok && disableReg != "" {
		b, err := strconv.ParseBool(disableReg)
		if err != nil {
			return nil, errwrap.Wrapf("failed parsing disable_registration parameter: {{err}}", err)
		}
		disableRegistration = b
	}
	if logger.IsDebug() {
		logger.Debug("physical/consul: config disable_registration set", "disable_registration", disableRegistration)
	}

	// Get the service name to advertise in Consul
	service, ok := conf["service"]
	if !ok {
		service = DefaultServiceName
	}
	if logger.IsDebug() {
		logger.Debug("physical/consul: config service set", "service", service)
	}

	// Get the additional tags to attach to the registered service name
	tags := conf["service_tags"]

	if logger.IsDebug() {
		logger.Debug("physical/consul: config service_tags set", "service_tags", tags)
	}

	checkTimeout := defaultCheckTimeout
	checkTimeoutStr, ok := conf["check_timeout"]
	if ok {
		d, err := time.ParseDuration(checkTimeoutStr)
		if err != nil {
			return nil, err
		}

		min, _ := lib.DurationMinusBufferDomain(d, checkMinBuffer, checkJitterFactor)
		if min < checkMinBuffer {
			return nil, fmt.Errorf("Consul check_timeout must be greater than %v", min)
		}

		checkTimeout = d
		if logger.IsDebug() {
			logger.Debug("physical/consul: config check_timeout set", "check_timeout", d)
		}
	}

	// Configure the client
	consulConf := api.DefaultConfig()

	if addr, ok := conf["address"]; ok {
		consulConf.Address = addr
		if logger.IsDebug() {
			logger.Debug("physical/consul: config address set", "address", addr)
		}
	}
	if scheme, ok := conf["scheme"]; ok {
		consulConf.Scheme = scheme
		if logger.IsDebug() {
			logger.Debug("physical/consul: config scheme set", "scheme", scheme)
		}
	}
	if token, ok := conf["token"]; ok {
		consulConf.Token = token
		logger.Debug("physical/consul: config token set")
	}

	if consulConf.Scheme == "https" {
		tlsClientConfig, err := setupTLSConfig(conf)
		if err != nil {
			return nil, err
		}

		transport := cleanhttp.DefaultPooledTransport()
		transport.MaxIdleConnsPerHost = 4
		transport.TLSClientConfig = tlsClientConfig
		consulConf.HttpClient.Transport = transport
		logger.Debug("physical/consul: configured TLS")
	}

	client, err := api.NewClient(consulConf)
	if err != nil {
		return nil, errwrap.Wrapf("client setup failed: {{err}}", err)
	}

	maxParStr, ok := conf["max_parallel"]
	var maxParInt int
	if ok {
		maxParInt, err = strconv.Atoi(maxParStr)
		if err != nil {
			return nil, errwrap.Wrapf("failed parsing max_parallel parameter: {{err}}", err)
		}
		if logger.IsDebug() {
			logger.Debug("physical/consul: max_parallel set", "max_parallel", maxParInt)
		}
	}

	// Setup the backend
	c := &ConsulBackend{
		path:                path,
		logger:              logger,
		client:              client,
		kv:                  client.KV(),
		permitPool:          NewPermitPool(maxParInt),
		serviceName:         service,
		serviceTags:         strutil.ParseDedupAndSortStrings(tags, ","),
		checkTimeout:        checkTimeout,
		disableRegistration: disableRegistration,
	}
	return c, nil
}
Пример #7
0
func startTerminal(logger log.Logger, channel ssh.Channel, system datamodel.System, user datamodel.User) {
	defer channel.Close()

	prompt := "kappa> "
	term := terminal.NewTerminal(channel, prompt)

	// // Try to make the terminal raw
	// oldState, err := terminal.MakeRaw(0)
	// if err != nil {
	//     logger.Warn("Error making terminal raw: ", err.Error())
	// }
	// defer terminal.Restore(0, oldState)

	// Write ascii text
	term.Write([]byte("\r\n"))
	for _, line := range ASCII {
		term.Write([]byte(line))
		term.Write([]byte("\r\n"))
	}

	// Write login message
	term.Write([]byte("\r\n\n"))
	GetMessage(channel, DefaultColorCodes)
	term.Write([]byte("\n"))

	// Create query executor
	executor := Executor{
		session: Session{
			namespace: "",
			user:      user,
		},
		terminal: NewTerminal(term, prompt),
		system:   system,
	}

	// Start REPL
	for {
		input, err := term.ReadLine()
		if err != nil {
			fmt.Errorf("Readline() error")
			break
		}

		// Process line
		line := strings.TrimSpace(input)
		if len(line) > 0 {

			// Log input and handle exit requests
			if line == "exit" || line == "quit" {
				logger.Info("Closing connection")
				break
			} else if line == "quote me" {
				term.Write([]byte("\r\n"))
				GetMessage(channel, DefaultColorCodes)
				term.Write([]byte("\r\n"))
				continue
			} else if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "--") {

				channel.Write(DefaultColorCodes.LightGrey)
				channel.Write([]byte(line + "\r\n"))
				channel.Write(DefaultColorCodes.Reset)
				continue
			}

			// Parse statement
			stmt, err := skl.ParseStatement(line)

			// Return parse error in red
			if err != nil {
				logger.Warn("Bad Statement", "statement", line, "error", err)
				channel.Write(DefaultColorCodes.LightRed)
				channel.Write([]byte(err.Error()))
				channel.Write([]byte("\r\n"))
				channel.Write(DefaultColorCodes.Reset)
				continue
			}

			// Execute statements
			w := ResponseWriter{DefaultColorCodes, channel}
			executor.Execute(&w, stmt)
		}
	}
}