// 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 }
// 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 }
// 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 }
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) } } }
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 }
// 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 }
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) } } }