From 229522d97d6d3df1bdc64fe3ff275c4f00cd7a6f Mon Sep 17 00:00:00 2001 From: Asif Mohammad Mollah Date: Fri, 1 May 2026 22:41:58 +0400 Subject: [PATCH] vet: password and passphrase now should be in base64. --- README.md | 49 +++++++++++++++++++++++----------------------- main.go | 8 +++++++- services/server.go | 8 ++++++-- utils/encoding.go | 15 ++++++++++++++ 4 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 utils/encoding.go diff --git a/README.md b/README.md index b060c6c..8b74189 100644 --- a/README.md +++ b/README.md @@ -138,23 +138,21 @@ The configuration file is a JSON array of objects. Each object defines a tunnel. "authType": "KEY", "password": "", "key": "/etc/autossh/id_rsa", - "passphrase": "passphrase", + "passphrase": "passphrase-in-base64", "jump": { "host": "jump-1-ip", "port": 22, - "username": "user", + "username": "user1", "authType": "KEY", "password": "", "key": "/etc/autossh/id_rsa", - "passphrase": "passphrase", + "passphrase": "passphrase-in-base64", "jump": { "host": "jump-2-ip", "port": 22, - "username": "user", - "authType": "KEY", - "password": "", - "key": "/etc/autossh/id_rsa", - "passphrase": "passphrase" + "username": "user2", + "authType": "PASS", + "password": "password-in-base64" } } } @@ -164,23 +162,23 @@ The configuration file is a JSON array of objects. Each object defines a tunnel. ### Fields Description -| Field | Type | Required | Description | -|-----------------|----------------|----------|-----------------------------------------------------------------------------| -| `name` | string | ✅ | Identifier for the tunnel. | -| `type` | string | ✅ | Tunnel type: `L` for remote → local, `R` for local → remote. | -| `localPort` | number | ✅ | Port on the local machine. | -| `localHost` | string | ✅ | Local host IP or `0.0.0.0` to bind all interfaces. | -| `remotePort` | number | ✅ | Port on the remote machine. | -| `remoteHost` | string | ✅ | Remote host IP or `0.0.0.0`. | -| `server` | object | ✅ | Final destination SSH server configuration. | -| `server.host` | string | ✅ | SSH server IP or hostname. | -| `server.port` | number | ✅ | SSH server port, usually 22. | -| `server.username` | string | ✅ | SSH username. | -| `server.authType` | string | ✅ | Authentication type: `KEY` or `PASS`. | -| `server.key` | string | 🔹 | Path to SSH key file if `authType` is `KEY`. | -| `server.password` | string | 🔹 | Password if `authType` is `PASS`. | -| `server.passphrase` | string | 🔹 | Passphrase for the SSH key if required. | -| `server.jump` | object/null | - | Optional jump host configuration (recursive structure). | +| Field | Type | Required | Description | +|-----------------|--------------------|----------|-----------------------------------------------------------------------------| +| `name` | string | ✅ | Identifier for the tunnel. | +| `type` | string | ✅ | Tunnel type: `L` for remote → local, `R` for local → remote. | +| `localPort` | number | ✅ | Port on the local machine. | +| `localHost` | string | ✅ | Local host IP or `0.0.0.0` to bind all interfaces. | +| `remotePort` | number | ✅ | Port on the remote machine. | +| `remoteHost` | string | ✅ | Remote host IP or `0.0.0.0`. | +| `server` | object | ✅ | Final destination SSH server configuration. | +| `server.host` | string | ✅ | SSH server IP or hostname. | +| `server.port` | number | ✅ | SSH server port, usually 22. | +| `server.username` | string | ✅ | SSH username. | +| `server.authType` | string | ✅ | Authentication type: `KEY` or `PASS`. | +| `server.key` | string | 🔹 | Path to SSH key file if `authType` is `KEY`. | +| `server.password` | string(base64) | 🔹 | Password if `authType` is `PASS`. | +| `server.passphrase` | string(base64) | 🔹 | Passphrase for the SSH key if required. | +| `server.jump` | object/null | - | Optional jump host configuration (recursive structure). | > **Note:** Jump hosts are optional and can be nested multiple times. @@ -203,6 +201,7 @@ The configuration file is a JSON array of objects. Each object defines a tunnel. - **D:** Remote service (MongoDB, PostgreSQL, etc.) ### Authentication Flow +Authentication for Passphrase or Password both should be base64 encoded. 1. **KEY authentication** - Uses a private key (`key`) and optional `passphrase`. 2. **Password authentication** diff --git a/main.go b/main.go index 4d2e534..5539af1 100644 --- a/main.go +++ b/main.go @@ -33,12 +33,13 @@ func main() { Name: "telepath", Version: AppVersion, Description: "telepath is a cli application to forward port securly.", + Usage: "The secure tunneling tools.", Flags: []cli.Flag{ &cli.StringFlag{ Name: "config-file", Aliases: []string{"f"}, Usage: "accepts config file path.", - Required: true, + Required: false, Destination: &configPath, }, &cli.BoolFlag{ @@ -49,6 +50,10 @@ func main() { }, }, Action: func(ctx *cli.Context) error { + if len(configPath) == 0 { + fmt.Println(`Required flag "--config-file" or "-f" not set.`) + return nil + } cfgs, err := services.ParseConfig(configPath) if err != nil { return err @@ -72,6 +77,7 @@ func main() { signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) go func() { sig := <-sigCh + fmt.Println("\r\033[K") log.Printf("Received signal %s, shutting down gracefully...", sig) cancel() }() diff --git a/services/server.go b/services/server.go index 905ce19..eea68f2 100644 --- a/services/server.go +++ b/services/server.go @@ -12,6 +12,7 @@ import ( "github.com/tech-thinker/telepath/constants" "github.com/tech-thinker/telepath/models" + "github.com/tech-thinker/telepath/utils" "golang.org/x/crypto/ssh" ) @@ -292,7 +293,8 @@ func (s *srv) createSSHClient(server *models.Server, proxy *ssh.Client) (*ssh.Cl var authMethods []ssh.AuthMethod if server.AuthType == constants.CREDIENTIAL_PASS { - authMethods = append(authMethods, ssh.Password(server.Password)) + password := utils.Base64Decode(server.Password) + authMethods = append(authMethods, ssh.Password(password)) } if server.AuthType == constants.CREDIENTIAL_KEY { @@ -301,8 +303,10 @@ func (s *srv) createSSHClient(server *models.Server, proxy *ssh.Client) (*ssh.Cl return nil, fmt.Errorf("failed to read key file: %w", err) } var signer ssh.Signer + if len(server.Passphrase) > 0 { - signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(server.Passphrase)) + passphrase := utils.Base64Decode(server.Passphrase) + signer, err = ssh.ParsePrivateKeyWithPassphrase(key, []byte(passphrase)) } else { signer, err = ssh.ParsePrivateKey(key) } diff --git a/utils/encoding.go b/utils/encoding.go new file mode 100644 index 0000000..c0e30b5 --- /dev/null +++ b/utils/encoding.go @@ -0,0 +1,15 @@ +package utils + +import "encoding/base64" + +func Base64Encode(plain string) string { + return base64.StdEncoding.EncodeToString([]byte(plain)) +} + +func Base64Decode(cipher string) string { + data, err := base64.StdEncoding.DecodeString(cipher) + if err != nil { + return "" + } + return string(data) +}