Merge pull request #277 from sosedoff/fix-ssh-connections

SSH Connection Fixes
This commit is contained in:
Dan Sosedoff
2017-09-26 23:50:12 -05:00
committed by GitHub
9 changed files with 67 additions and 32 deletions

View File

@@ -115,6 +115,7 @@ func parseSshInfo(c *gin.Context) *shared.SSHInfo {
Port: c.Request.FormValue("ssh_port"), Port: c.Request.FormValue("ssh_port"),
User: c.Request.FormValue("ssh_user"), User: c.Request.FormValue("ssh_user"),
Password: c.Request.FormValue("ssh_password"), Password: c.Request.FormValue("ssh_password"),
Key: c.Request.FormValue("ssh_key"),
} }
if info.Port == "" { if info.Port == "" {

View File

@@ -14,14 +14,14 @@ import (
) )
type Bookmark struct { type Bookmark struct {
Url string `json:"url"` // Postgres connection URL Url string `json:"url"` // Postgres connection URL
Host string `json:"host"` // Server hostname Host string `json:"host"` // Server hostname
Port int `json:"port"` // Server port Port int `json:"port"` // Server port
User string `json:"user"` // Database user User string `json:"user"` // Database user
Password string `json:"password"` // User password Password string `json:"password"` // User password
Database string `json:"database"` // Database name Database string `json:"database"` // Database name
Ssl string `json:"ssl"` // Connection SSL mode Ssl string `json:"ssl"` // Connection SSL mode
Ssh shared.SSHInfo `json:"ssh"` // SSH tunnel config Ssh *shared.SSHInfo `json:"ssh"` // SSH tunnel config
} }
func (b Bookmark) SSHInfoIsEmpty() bool { func (b Bookmark) SSHInfoIsEmpty() bool {
@@ -71,6 +71,10 @@ func readServerConfig(path string) (Bookmark, error) {
bookmark.Ssl = "disable" bookmark.Ssl = "disable"
} }
if bookmark.Ssh != nil && bookmark.Ssh.Port == "" {
bookmark.Ssh.Port = "22"
}
return bookmark, err return bookmark, err
} }

View File

@@ -95,12 +95,12 @@ func Test_GetBookmark(t *testing.T) {
} }
func Test_Bookmark_SSHInfoIsEmpty(t *testing.T) { func Test_Bookmark_SSHInfoIsEmpty(t *testing.T) {
emptySSH := shared.SSHInfo{ emptySSH := &shared.SSHInfo{
Host: "", Host: "",
Port: "", Port: "",
User: "", User: "",
} }
populatedSSH := shared.SSHInfo{ populatedSSH := &shared.SSHInfo{
Host: "localhost", Host: "localhost",
Port: "8080", Port: "8080",
User: "postgres", User: "postgres",

View File

@@ -46,7 +46,7 @@ func initClientUsingBookmark(bookmarkPath, bookmarkName string) (*client.Client,
var ssh *shared.SSHInfo var ssh *shared.SSHInfo
if !bookmark.SSHInfoIsEmpty() { if !bookmark.SSHInfoIsEmpty() {
ssh = &bookmark.Ssh ssh = bookmark.Ssh
} }
return client.NewFromUrl(connStr, ssh) return client.NewFromUrl(connStr, ssh)

View File

@@ -10,6 +10,7 @@ import (
"os" "os"
"strings" "strings"
"sync" "sync"
"time"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@@ -36,6 +37,14 @@ func privateKeyPath() string {
return os.Getenv("HOME") + "/.ssh/id_rsa" return os.Getenv("HOME") + "/.ssh/id_rsa"
} }
func expandKeyPath(path string) string {
home := os.Getenv("HOME")
if home == "" {
return path
}
return strings.Replace(path, "~", home, 1)
}
func fileExists(path string) bool { func fileExists(path string) bool {
_, err := os.Stat(path) _, err := os.Stat(path)
return err == nil return err == nil
@@ -53,7 +62,14 @@ func parsePrivateKey(keyPath string) (ssh.Signer, error) {
func makeConfig(info *shared.SSHInfo) (*ssh.ClientConfig, error) { func makeConfig(info *shared.SSHInfo) (*ssh.ClientConfig, error) {
methods := []ssh.AuthMethod{} methods := []ssh.AuthMethod{}
keyPath := privateKeyPath() // Try to use user-provided key, fallback to system default key
keyPath := info.Key
if keyPath == "" {
keyPath = privateKeyPath()
} else {
keyPath = expandKeyPath(keyPath)
}
if fileExists(keyPath) { if fileExists(keyPath) {
key, err := parsePrivateKey(keyPath) key, err := parsePrivateKey(keyPath)
if err != nil { if err != nil {
@@ -65,7 +81,13 @@ func makeConfig(info *shared.SSHInfo) (*ssh.ClientConfig, error) {
methods = append(methods, ssh.Password(info.Password)) methods = append(methods, ssh.Password(info.Password))
return &ssh.ClientConfig{User: info.User, Auth: methods}, nil cfg := &ssh.ClientConfig{
User: info.User,
Auth: methods,
Timeout: time.Second * 10,
}
return cfg, nil
} }
func (tunnel *Tunnel) sshEndpoint() string { func (tunnel *Tunnel) sshEndpoint() string {

File diff suppressed because one or more lines are too long

View File

@@ -563,6 +563,10 @@
font-size: 12px; font-size: 12px;
} }
.connection-settings form .no-left-padding {
padding-left: 0;
}
.connection-scheme-group { .connection-scheme-group {
display: none; display: none;
} }

View File

@@ -147,9 +147,12 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Host</label> <label class="col-sm-3 control-label">Host</label>
<div class="col-sm-9"> <div class="col-sm-7">
<input type="text" id="pg_host" class="form-control" /> <input type="text" id="pg_host" class="form-control" />
</div> </div>
<div class="col-sm-2 no-left-padding">
<input type="text" id="pg_port" class="form-control" placeholder="5432" />
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -174,14 +177,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">Port</label> <label class="col-sm-3 control-label">SSL Mode</label>
<div class="col-sm-9">
<input type="text" id="pg_port" class="form-control" placeholder="5432" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">SSL</label>
<div class="col-sm-9"> <div class="col-sm-9">
<select class="form-control" id="connection_ssl"> <select class="form-control" id="connection_ssl">
<option value="disable">disable</option> <option value="disable">disable</option>
@@ -193,11 +189,16 @@
</div> </div>
<div class="connection-ssh-group"> <div class="connection-ssh-group">
<hr/>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">SSH Host</label> <label class="col-sm-3 control-label">SSH Host</label>
<div class="col-sm-9"> <div class="col-sm-7">
<input type="text" id="ssh_host" class="form-control" /> <input type="text" id="ssh_host" class="form-control" />
</div> </div>
<div class="col-sm-2 no-left-padding">
<input type="text" id="ssh_port" class="form-control" placeholder="22" />
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -215,9 +216,9 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">SSH Port</label> <label class="col-sm-3 control-label">SSH Key</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="text" id="ssh_port" class="form-control" placeholder="optional" /> <input type="text" id="ssh_key" class="form-control" placeholder="optional" />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1149,6 +1149,7 @@ $(document).ready(function() {
$("#ssh_port").val(item.ssh.port); $("#ssh_port").val(item.ssh.port);
$("#ssh_user").val(item.ssh.user); $("#ssh_user").val(item.ssh.user);
$("#ssh_password").val(item.ssh.password); $("#ssh_password").val(item.ssh.password);
$("#ssh_key").val(item.ssh.key);
$("#connection_ssh").click(); $("#connection_ssh").click();
} }
else { else {
@@ -1156,6 +1157,7 @@ $(document).ready(function() {
$("#ssh_port").val(""); $("#ssh_port").val("");
$("#ssh_user").val(""); $("#ssh_user").val("");
$("#ssh_password").val(""); $("#ssh_password").val("");
$("#ssh_key").val("");
$(".connection-ssh-group").hide(); $(".connection-ssh-group").hide();
} }
}); });
@@ -1178,6 +1180,7 @@ $(document).ready(function() {
params["ssh_port"] = $("#ssh_port").val(); params["ssh_port"] = $("#ssh_port").val();
params["ssh_user"] = $("#ssh_user").val(); params["ssh_user"] = $("#ssh_user").val();
params["ssh_password"] = $("#ssh_password").val(); params["ssh_password"] = $("#ssh_password").val();
params["ssh_key"] = $("#ssh_key").val();
} }
$("#connection_error").hide(); $("#connection_error").hide();