Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
cf4faa49
Commit
cf4faa49
authored
May 03, 2017
by
Péter Szilágyi
Committed by
Felix Lange
May 03, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/puppeth, vendor: update ssh, manage server keys (#14398)
parent
59966255
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
701 additions
and
285 deletions
+701
-285
ssh.go
cmd/puppeth/ssh.go
+44
-5
wizard.go
cmd/puppeth/wizard.go
+12
-2
wizard_intro.go
cmd/puppeth/wizard_intro.go
+6
-3
wizard_netstats.go
cmd/puppeth/wizard_netstats.go
+2
-2
wizard_network.go
cmd/puppeth/wizard_network.go
+11
-7
cswap_amd64.s
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
+54
-77
curve25519.go
vendor/golang.org/x/crypto/curve25519/curve25519.go
+8
-15
certs.go
vendor/golang.org/x/crypto/ssh/certs.go
+1
-1
client.go
vendor/golang.org/x/crypto/ssh/client.go
+51
-5
client_auth.go
vendor/golang.org/x/crypto/ssh/client_auth.go
+28
-17
common.go
vendor/golang.org/x/crypto/ssh/common.go
+8
-6
doc.go
vendor/golang.org/x/crypto/ssh/doc.go
+3
-0
handshake.go
vendor/golang.org/x/crypto/ssh/handshake.go
+34
-19
keys.go
vendor/golang.org/x/crypto/ssh/keys.go
+71
-19
server.go
vendor/golang.org/x/crypto/ssh/server.go
+33
-0
streamlocal.go
vendor/golang.org/x/crypto/ssh/streamlocal.go
+115
-0
tcpip.go
vendor/golang.org/x/crypto/ssh/tcpip.go
+128
-70
util_solaris.go
vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
+59
-4
vendor.json
vendor/vendor.json
+33
-33
No files found.
cmd/puppeth/ssh.go
View file @
cf4faa49
...
...
@@ -17,6 +17,8 @@
package
main
import
(
"bufio"
"bytes"
"errors"
"fmt"
"io/ioutil"
...
...
@@ -37,18 +39,26 @@ import (
type
sshClient
struct
{
server
string
// Server name or IP without port number
address
string
// IP address of the remote server
pubkey
[]
byte
// RSA public key to authenticate the server
client
*
ssh
.
Client
logger
log
.
Logger
}
// dial establishes an SSH connection to a remote node using the current user and
// the user's configured private RSA key.
func
dial
(
server
string
)
(
*
sshClient
,
error
)
{
// the user's configured private RSA key. If that fails, password authentication
// is fallen back to. The caller may override the login user via user@server:port.
func
dial
(
server
string
,
pubkey
[]
byte
)
(
*
sshClient
,
error
)
{
// Figure out a label for the server and a logger
label
:=
server
if
strings
.
Contains
(
label
,
":"
)
{
label
=
label
[
:
strings
.
Index
(
label
,
":"
)]
}
login
:=
""
if
strings
.
Contains
(
server
,
"@"
)
{
login
=
label
[
:
strings
.
Index
(
label
,
"@"
)]
label
=
label
[
strings
.
Index
(
label
,
"@"
)
+
1
:
]
server
=
server
[
strings
.
Index
(
server
,
"@"
)
+
1
:
]
}
logger
:=
log
.
New
(
"server"
,
label
)
logger
.
Debug
(
"Attempting to establish SSH connection"
)
...
...
@@ -56,6 +66,9 @@ func dial(server string) (*sshClient, error) {
if
err
!=
nil
{
return
nil
,
err
}
if
login
==
""
{
login
=
user
.
Username
}
// Configure the supported authentication methods (private key and password)
var
auths
[]
ssh
.
AuthMethod
...
...
@@ -71,7 +84,7 @@ func dial(server string) (*sshClient, error) {
}
}
auths
=
append
(
auths
,
ssh
.
PasswordCallback
(
func
()
(
string
,
error
)
{
fmt
.
Printf
(
"What's the login password for %s at %s? (won't be echoed)
\n
> "
,
user
.
Username
,
server
)
fmt
.
Printf
(
"What's the login password for %s at %s? (won't be echoed)
\n
> "
,
login
,
server
)
blob
,
err
:=
terminal
.
ReadPassword
(
int
(
syscall
.
Stdin
))
fmt
.
Println
()
...
...
@@ -86,11 +99,36 @@ func dial(server string) (*sshClient, error) {
return
nil
,
errors
.
New
(
"no IPs associated with domain"
)
}
// Try to dial in to the remote server
logger
.
Trace
(
"Dialing remote SSH server"
,
"user"
,
user
.
Username
,
"key"
,
path
)
logger
.
Trace
(
"Dialing remote SSH server"
,
"user"
,
login
)
if
!
strings
.
Contains
(
server
,
":"
)
{
server
+=
":22"
}
client
,
err
:=
ssh
.
Dial
(
"tcp"
,
server
,
&
ssh
.
ClientConfig
{
User
:
user
.
Username
,
Auth
:
auths
})
keycheck
:=
func
(
hostname
string
,
remote
net
.
Addr
,
key
ssh
.
PublicKey
)
error
{
// If no public key is known for SSH, ask the user to confirm
if
pubkey
==
nil
{
fmt
.
Printf
(
"The authenticity of host '%s (%s)' can't be established.
\n
"
,
hostname
,
remote
)
fmt
.
Printf
(
"SSH key fingerprint is %s [MD5]
\n
"
,
ssh
.
FingerprintLegacyMD5
(
key
))
fmt
.
Printf
(
"Are you sure you want to continue connecting (yes/no)? "
)
text
,
err
:=
bufio
.
NewReader
(
os
.
Stdin
)
.
ReadString
(
'\n'
)
switch
{
case
err
!=
nil
:
return
err
case
strings
.
TrimSpace
(
text
)
==
"yes"
:
pubkey
=
key
.
Marshal
()
return
nil
default
:
return
fmt
.
Errorf
(
"unknown auth choice: %v"
,
text
)
}
}
// If a public key exists for this SSH server, check that it matches
if
bytes
.
Compare
(
pubkey
,
key
.
Marshal
())
==
0
{
return
nil
}
// We have a mismatch, forbid connecting
return
errors
.
New
(
"ssh key mismatch, readd the machine to update"
)
}
client
,
err
:=
ssh
.
Dial
(
"tcp"
,
server
,
&
ssh
.
ClientConfig
{
User
:
login
,
Auth
:
auths
,
HostKeyCallback
:
keycheck
})
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -98,6 +136,7 @@ func dial(server string) (*sshClient, error) {
c
:=
&
sshClient
{
server
:
label
,
address
:
addr
[
0
],
pubkey
:
pubkey
,
client
:
client
,
logger
:
logger
,
}
...
...
cmd/puppeth/wizard.go
View file @
cf4faa49
...
...
@@ -44,14 +44,24 @@ type config struct {
bootLight
[]
string
// Bootnodes to always connect to by light nodes
ethstats
string
// Ethstats settings to cache for node deploys
Servers
[]
string
`json:"servers,omitempty"`
Servers
map
[
string
][]
byte
`json:"servers,omitempty"`
}
// servers retrieves an alphabetically sorted list of servers.
func
(
c
config
)
servers
()
[]
string
{
servers
:=
make
([]
string
,
0
,
len
(
c
.
Servers
))
for
server
:=
range
c
.
Servers
{
servers
=
append
(
servers
,
server
)
}
sort
.
Strings
(
servers
)
return
servers
}
// flush dumps the contents of config to disk.
func
(
c
config
)
flush
()
{
os
.
MkdirAll
(
filepath
.
Dir
(
c
.
path
),
0755
)
sort
.
Strings
(
c
.
Servers
)
out
,
_
:=
json
.
MarshalIndent
(
c
,
""
,
" "
)
if
err
:=
ioutil
.
WriteFile
(
c
.
path
,
out
,
0644
);
err
!=
nil
{
log
.
Warn
(
"Failed to save puppeth configs"
,
"file"
,
c
.
path
,
"err"
,
err
)
...
...
cmd/puppeth/wizard_intro.go
View file @
cf4faa49
...
...
@@ -31,7 +31,10 @@ import (
// makeWizard creates and returns a new puppeth wizard.
func
makeWizard
(
network
string
)
*
wizard
{
return
&
wizard
{
network
:
network
,
network
:
network
,
conf
:
config
{
Servers
:
make
(
map
[
string
][]
byte
),
},
servers
:
make
(
map
[
string
]
*
sshClient
),
services
:
make
(
map
[
string
][]
string
),
in
:
bufio
.
NewReader
(
os
.
Stdin
),
...
...
@@ -77,9 +80,9 @@ func (w *wizard) run() {
}
else
if
err
:=
json
.
Unmarshal
(
blob
,
&
w
.
conf
);
err
!=
nil
{
log
.
Crit
(
"Previous configuration corrupted"
,
"path"
,
w
.
conf
.
path
,
"err"
,
err
)
}
else
{
for
_
,
server
:=
range
w
.
conf
.
Servers
{
for
server
,
pubkey
:=
range
w
.
conf
.
Servers
{
log
.
Info
(
"Dialing previously configured server"
,
"server"
,
server
)
client
,
err
:=
dial
(
server
)
client
,
err
:=
dial
(
server
,
pubkey
)
if
err
!=
nil
{
log
.
Error
(
"Previous server unreachable"
,
"server"
,
server
,
"err"
,
err
)
}
...
...
cmd/puppeth/wizard_netstats.go
View file @
cf4faa49
...
...
@@ -41,14 +41,14 @@ func (w *wizard) networkStats(tips bool) {
stats
.
SetHeader
([]
string
{
"Server"
,
"IP"
,
"Status"
,
"Service"
,
"Details"
})
stats
.
SetColWidth
(
128
)
for
_
,
server
:=
range
w
.
conf
.
Servers
{
for
server
,
pubkey
:=
range
w
.
conf
.
Servers
{
client
:=
w
.
servers
[
server
]
logger
:=
log
.
New
(
"server"
,
server
)
logger
.
Info
(
"Starting remote server health-check"
)
// If the server is not connected, try to connect again
if
client
==
nil
{
conn
,
err
:=
dial
(
server
)
conn
,
err
:=
dial
(
server
,
pubkey
)
if
err
!=
nil
{
logger
.
Error
(
"Failed to establish remote connection"
,
"err"
,
err
)
stats
.
Append
([]
string
{
server
,
""
,
err
.
Error
(),
""
,
""
})
...
...
cmd/puppeth/wizard_network.go
View file @
cf4faa49
...
...
@@ -28,7 +28,9 @@ import (
func
(
w
*
wizard
)
manageServers
()
{
// List all the servers we can disconnect, along with an entry to connect a new one
fmt
.
Println
()
for
i
,
server
:=
range
w
.
conf
.
Servers
{
servers
:=
w
.
conf
.
servers
()
for
i
,
server
:=
range
servers
{
fmt
.
Printf
(
" %d. Disconnect %s
\n
"
,
i
+
1
,
server
)
}
fmt
.
Printf
(
" %d. Connect another server
\n
"
,
len
(
w
.
conf
.
Servers
)
+
1
)
...
...
@@ -40,14 +42,14 @@ func (w *wizard) manageServers() {
}
// If the user selected an existing server, drop it
if
choice
<=
len
(
w
.
conf
.
Servers
)
{
server
:=
w
.
conf
.
S
ervers
[
choice
-
1
]
server
:=
s
ervers
[
choice
-
1
]
client
:=
w
.
servers
[
server
]
delete
(
w
.
servers
,
server
)
if
client
!=
nil
{
client
.
Close
()
}
w
.
conf
.
Servers
=
append
(
w
.
conf
.
Servers
[
:
choice
-
1
],
w
.
conf
.
Servers
[
choice
:
]
...
)
delete
(
w
.
conf
.
Servers
,
server
)
w
.
conf
.
flush
()
log
.
Info
(
"Disconnected existing server"
,
"server"
,
server
)
...
...
@@ -73,14 +75,14 @@ func (w *wizard) makeServer() string {
// Read and fial the server to ensure docker is present
input
:=
w
.
readString
()
client
,
err
:=
dial
(
input
)
client
,
err
:=
dial
(
input
,
nil
)
if
err
!=
nil
{
log
.
Error
(
"Server not ready for puppeth"
,
"err"
,
err
)
return
""
}
// All checks passed, start tracking the server
w
.
servers
[
input
]
=
client
w
.
conf
.
Servers
=
append
(
w
.
conf
.
Servers
,
input
)
w
.
conf
.
Servers
[
input
]
=
client
.
pubkey
w
.
conf
.
flush
()
return
input
...
...
@@ -93,7 +95,9 @@ func (w *wizard) selectServer() string {
// List the available server to the user and wait for a choice
fmt
.
Println
()
fmt
.
Println
(
"Which server do you want to interact with?"
)
for
i
,
server
:=
range
w
.
conf
.
Servers
{
servers
:=
w
.
conf
.
servers
()
for
i
,
server
:=
range
servers
{
fmt
.
Printf
(
" %d. %s
\n
"
,
i
+
1
,
server
)
}
fmt
.
Printf
(
" %d. Connect another server
\n
"
,
len
(
w
.
conf
.
Servers
)
+
1
)
...
...
@@ -105,7 +109,7 @@ func (w *wizard) selectServer() string {
}
// If the user requested connecting to a new server, go for it
if
choice
<=
len
(
w
.
conf
.
Servers
)
{
return
w
.
conf
.
S
ervers
[
choice
-
1
]
return
s
ervers
[
choice
-
1
]
}
return
w
.
makeServer
()
}
...
...
vendor/golang.org/x/crypto/curve25519/cswap_amd64.s
View file @
cf4faa49
...
...
@@ -2,87 +2,64 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This code was translated into a form compatible with 6a from the public
// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html
// +build amd64,!gccgo,!appengine
// func cswap(inout *[5]uint64, v uint64)
// func cswap(inout *[
4][
5]uint64, v uint64)
TEXT ·cswap(SB),7,$0
MOVQ inout+0(FP),DI
MOVQ v+8(FP),SI
CMPQ SI,$1
MOVQ 0(DI),SI
MOVQ 80(DI),DX
MOVQ 8(DI),CX
MOVQ 88(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,0(DI)
MOVQ DX,80(DI)
MOVQ CX,8(DI)
MOVQ R8,88(DI)
MOVQ 16(DI),SI
MOVQ 96(DI),DX
MOVQ 24(DI),CX
MOVQ 104(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,16(DI)
MOVQ DX,96(DI)
MOVQ CX,24(DI)
MOVQ R8,104(DI)
MOVQ 32(DI),SI
MOVQ 112(DI),DX
MOVQ 40(DI),CX
MOVQ 120(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,32(DI)
MOVQ DX,112(DI)
MOVQ CX,40(DI)
MOVQ R8,120(DI)
MOVQ 48(DI),SI
MOVQ 128(DI),DX
MOVQ 56(DI),CX
MOVQ 136(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,48(DI)
MOVQ DX,128(DI)
MOVQ CX,56(DI)
MOVQ R8,136(DI)
MOVQ 64(DI),SI
MOVQ 144(DI),DX
MOVQ 72(DI),CX
MOVQ 152(DI),R8
MOVQ SI,R9
CMOVQEQ DX,SI
CMOVQEQ R9,DX
MOVQ CX,R9
CMOVQEQ R8,CX
CMOVQEQ R9,R8
MOVQ SI,64(DI)
MOVQ DX,144(DI)
MOVQ CX,72(DI)
MOVQ R8,152(DI)
MOVQ DI,AX
MOVQ SI,DX
SUBQ $1, SI
NOTQ SI
MOVQ SI, X15
PSHUFD $0x44, X15, X15
MOVOU 0(DI), X0
MOVOU 16(DI), X2
MOVOU 32(DI), X4
MOVOU 48(DI), X6
MOVOU 64(DI), X8
MOVOU 80(DI), X1
MOVOU 96(DI), X3
MOVOU 112(DI), X5
MOVOU 128(DI), X7
MOVOU 144(DI), X9
MOVO X1, X10
MOVO X3, X11
MOVO X5, X12
MOVO X7, X13
MOVO X9, X14
PXOR X0, X10
PXOR X2, X11
PXOR X4, X12
PXOR X6, X13
PXOR X8, X14
PAND X15, X10
PAND X15, X11
PAND X15, X12
PAND X15, X13
PAND X15, X14
PXOR X10, X0
PXOR X10, X1
PXOR X11, X2
PXOR X11, X3
PXOR X12, X4
PXOR X12, X5
PXOR X13, X6
PXOR X13, X7
PXOR X14, X8
PXOR X14, X9
MOVOU X0, 0(DI)
MOVOU X2, 16(DI)
MOVOU X4, 32(DI)
MOVOU X6, 48(DI)
MOVOU X8, 64(DI)
MOVOU X1, 80(DI)
MOVOU X3, 96(DI)
MOVOU X5, 112(DI)
MOVOU X7, 128(DI)
MOVOU X9, 144(DI)
RET
vendor/golang.org/x/crypto/curve25519/curve25519.go
View file @
cf4faa49
...
...
@@ -8,6 +8,10 @@
package
curve25519
import
(
"encoding/binary"
)
// This code is a port of the public domain, "ref10" implementation of
// curve25519 from SUPERCOP 20130419 by D. J. Bernstein.
...
...
@@ -50,17 +54,11 @@ func feCopy(dst, src *fieldElement) {
//
// Preconditions: b in {0,1}.
func
feCSwap
(
f
,
g
*
fieldElement
,
b
int32
)
{
var
x
fieldElement
b
=
-
b
for
i
:=
range
x
{
x
[
i
]
=
b
&
(
f
[
i
]
^
g
[
i
])
}
for
i
:=
range
f
{
f
[
i
]
^=
x
[
i
]
}
for
i
:=
range
g
{
g
[
i
]
^=
x
[
i
]
t
:=
b
&
(
f
[
i
]
^
g
[
i
])
f
[
i
]
^=
t
g
[
i
]
^=
t
}
}
...
...
@@ -75,12 +73,7 @@ func load3(in []byte) int64 {
// load4 reads a 32-bit, little-endian value from in.
func
load4
(
in
[]
byte
)
int64
{
var
r
int64
r
=
int64
(
in
[
0
])
r
|=
int64
(
in
[
1
])
<<
8
r
|=
int64
(
in
[
2
])
<<
16
r
|=
int64
(
in
[
3
])
<<
24
return
r
return
int64
(
binary
.
LittleEndian
.
Uint32
(
in
))
}
func
feFromBytes
(
dst
*
fieldElement
,
src
*
[
32
]
byte
)
{
...
...
vendor/golang.org/x/crypto/ssh/certs.go
View file @
cf4faa49
...
...
@@ -268,7 +268,7 @@ type CertChecker struct {
// HostKeyFallback is called when CertChecker.CheckHostKey encounters a
// public key that is not a certificate. It must implement host key
// validation or else, if nil, all such keys are rejected.
HostKeyFallback
func
(
addr
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
HostKeyFallback
HostKeyCallback
// IsRevoked is called for each certificate so that revocation checking
// can be implemented. It should return true if the given certificate
...
...
vendor/golang.org/x/crypto/ssh/client.go
View file @
cf4faa49
...
...
@@ -5,6 +5,7 @@
package
ssh
import
(
"bytes"
"errors"
"fmt"
"net"
...
...
@@ -13,7 +14,7 @@ import (
)
// Client implements a traditional SSH client that supports shells,
// subprocesses,
port
forwarding and tunneled dialing.
// subprocesses,
TCP port/streamlocal
forwarding and tunneled dialing.
type
Client
struct
{
Conn
...
...
@@ -59,6 +60,7 @@ func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
conn
.
forwards
.
closeAll
()
}()
go
conn
.
forwards
.
handleChannels
(
conn
.
HandleChannelOpen
(
"forwarded-tcpip"
))
go
conn
.
forwards
.
handleChannels
(
conn
.
HandleChannelOpen
(
"forwarded-streamlocal@openssh.com"
))
return
conn
}
...
...
@@ -68,6 +70,11 @@ func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client {
func
NewClientConn
(
c
net
.
Conn
,
addr
string
,
config
*
ClientConfig
)
(
Conn
,
<-
chan
NewChannel
,
<-
chan
*
Request
,
error
)
{
fullConf
:=
*
config
fullConf
.
SetDefaults
()
if
fullConf
.
HostKeyCallback
==
nil
{
c
.
Close
()
return
nil
,
nil
,
nil
,
errors
.
New
(
"ssh: must specify HostKeyCallback"
)
}
conn
:=
&
connection
{
sshConn
:
sshConn
{
conn
:
c
},
}
...
...
@@ -173,6 +180,13 @@ func Dial(network, addr string, config *ClientConfig) (*Client, error) {
return
NewClient
(
c
,
chans
,
reqs
),
nil
}
// HostKeyCallback is the function type used for verifying server
// keys. A HostKeyCallback must return nil if the host key is OK, or
// an error to reject it. It receives the hostname as passed to Dial
// or NewClientConn. The remote address is the RemoteAddr of the
// net.Conn underlying the the SSH connection.
type
HostKeyCallback
func
(
hostname
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
// A ClientConfig structure is used to configure a Client. It must not be
// modified after having been passed to an SSH function.
type
ClientConfig
struct
{
...
...
@@ -188,10 +202,12 @@ type ClientConfig struct {
// be used during authentication.
Auth
[]
AuthMethod
// HostKeyCallback, if not nil, is called during the cryptographic
// handshake to validate the server's host key. A nil HostKeyCallback
// implies that all host keys are accepted.
HostKeyCallback
func
(
hostname
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
// HostKeyCallback is called during the cryptographic
// handshake to validate the server's host key. The client
// configuration must supply this callback for the connection
// to succeed. The functions InsecureIgnoreHostKey or
// FixedHostKey can be used for simplistic host key checks.
HostKeyCallback
HostKeyCallback
// ClientVersion contains the version identification string that will
// be used for the connection. If empty, a reasonable default is used.
...
...
@@ -209,3 +225,33 @@ type ClientConfig struct {
// A Timeout of zero means no timeout.
Timeout
time
.
Duration
}
// InsecureIgnoreHostKey returns a function that can be used for
// ClientConfig.HostKeyCallback to accept any host key. It should
// not be used for production code.
func
InsecureIgnoreHostKey
()
HostKeyCallback
{
return
func
(
hostname
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
{
return
nil
}
}
type
fixedHostKey
struct
{
key
PublicKey
}
func
(
f
*
fixedHostKey
)
check
(
hostname
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
{
if
f
.
key
==
nil
{
return
fmt
.
Errorf
(
"ssh: required host key was nil"
)
}
if
!
bytes
.
Equal
(
key
.
Marshal
(),
f
.
key
.
Marshal
())
{
return
fmt
.
Errorf
(
"ssh: host key mismatch"
)
}
return
nil
}
// FixedHostKey returns a function for use in
// ClientConfig.HostKeyCallback to accept only a specific host key.
func
FixedHostKey
(
key
PublicKey
)
HostKeyCallback
{
hk
:=
&
fixedHostKey
{
key
}
return
hk
.
check
}
vendor/golang.org/x/crypto/ssh/client_auth.go
View file @
cf4faa49
...
...
@@ -179,31 +179,26 @@ func (cb publicKeyCallback) method() string {
}
func
(
cb
publicKeyCallback
)
auth
(
session
[]
byte
,
user
string
,
c
packetConn
,
rand
io
.
Reader
)
(
bool
,
[]
string
,
error
)
{
// Authentication is performed
in two stages. The first stage sends an
//
enquiry to test if each key is acceptable to the remote. The second
//
stage attempts to authenticate with the valid keys obtained in the
//
first stage
.
// Authentication is performed
by sending an enquiry to test if a key is
//
acceptable to the remote. If the key is acceptable, the client will
//
attempt to authenticate with the valid key. If not the client will repeat
//
the process with the remaining keys
.
signers
,
err
:=
cb
()
if
err
!=
nil
{
return
false
,
nil
,
err
}
var
validKeys
[]
Signer
var
methods
[]
string
for
_
,
signer
:=
range
signers
{
if
ok
,
err
:=
validateKey
(
signer
.
PublicKey
(),
user
,
c
);
ok
{
validKeys
=
append
(
validKeys
,
signer
)
}
else
{
if
err
!=
nil
{
return
false
,
nil
,
err
}
ok
,
err
:=
validateKey
(
signer
.
PublicKey
(),
user
,
c
)
if
err
!=
nil
{
return
false
,
nil
,
err
}
if
!
ok
{
continue
}
}
// methods that may continue if this auth is not successful.
var
methods
[]
string
for
_
,
signer
:=
range
validKeys
{
pub
:=
signer
.
PublicKey
()
pubKey
:=
pub
.
Marshal
()
sign
,
err
:=
signer
.
Sign
(
rand
,
buildDataSignedForAuth
(
session
,
userAuthRequestMsg
{
User
:
user
,
...
...
@@ -236,13 +231,29 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
if
err
!=
nil
{
return
false
,
nil
,
err
}
if
success
{
// If authentication succeeds or the list of available methods does not
// contain the "publickey" method, do not attempt to authenticate with any
// other keys. According to RFC 4252 Section 7, the latter can occur when
// additional authentication methods are required.
if
success
||
!
containsMethod
(
methods
,
cb
.
method
())
{
return
success
,
methods
,
err
}
}
return
false
,
methods
,
nil
}
func
containsMethod
(
methods
[]
string
,
method
string
)
bool
{
for
_
,
m
:=
range
methods
{
if
m
==
method
{
return
true
}
}
return
false
}
// validateKey validates the key provided is acceptable to the server.
func
validateKey
(
key
PublicKey
,
user
string
,
c
packetConn
)
(
bool
,
error
)
{
pubKey
:=
key
.
Marshal
()
...
...
vendor/golang.org/x/crypto/ssh/common.go
View file @
cf4faa49
...
...
@@ -9,6 +9,7 @@ import (
"crypto/rand"
"fmt"
"io"
"math"
"sync"
_
"crypto/sha1"
...
...
@@ -40,7 +41,7 @@ var supportedKexAlgos = []string{
kexAlgoDH14SHA1
,
kexAlgoDH1SHA1
,
}
// supported
Kex
Algos specifies the supported host-key algorithms (i.e. methods
// supported
HostKey
Algos specifies the supported host-key algorithms (i.e. methods
// of authenticating servers) in preference order.
var
supportedHostKeyAlgos
=
[]
string
{
CertAlgoRSAv01
,
CertAlgoDSAv01
,
CertAlgoECDSA256v01
,
...
...
@@ -186,7 +187,7 @@ type Config struct {
// The maximum number of bytes sent or received after which a
// new key is negotiated. It must be at least 256. If
// unspecified,
1 gigabyte
is used.
// unspecified,
a size suitable for the chosen cipher
is used.
RekeyThreshold
uint64
// The allowed key exchanges algorithms. If unspecified then a
...
...
@@ -230,11 +231,12 @@ func (c *Config) SetDefaults() {
}
if
c
.
RekeyThreshold
==
0
{
// RFC 4253, section 9 suggests rekeying after 1G.
c
.
RekeyThreshold
=
1
<<
30
}
if
c
.
RekeyThreshold
<
minRekeyThreshold
{
// cipher specific default
}
else
if
c
.
RekeyThreshold
<
minRekeyThreshold
{
c
.
RekeyThreshold
=
minRekeyThreshold
}
else
if
c
.
RekeyThreshold
>=
math
.
MaxInt64
{
// Avoid weirdness if somebody uses -1 as a threshold.
c
.
RekeyThreshold
=
math
.
MaxInt64
}
}
...
...
vendor/golang.org/x/crypto/ssh/doc.go
View file @
cf4faa49
...
...
@@ -14,5 +14,8 @@ others.
References:
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
This package does not fall under the stability promise of the Go language itself,
so its API may be changed when pressing needs arise.
*/
package
ssh
// import "golang.org/x/crypto/ssh"
vendor/golang.org/x/crypto/ssh/handshake.go
View file @
cf4faa49
...
...
@@ -74,7 +74,7 @@ type handshakeTransport struct {
startKex
chan
*
pendingKex
// data for host key checking
hostKeyCallback
func
(
hostname
string
,
remote
net
.
Addr
,
key
PublicKey
)
error
hostKeyCallback
HostKeyCallback
dialAddress
string
remoteAddr
net
.
Addr
...
...
@@ -107,6 +107,8 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
config
:
config
,
}
t
.
resetReadThresholds
()
t
.
resetWriteThresholds
()
// We always start with a mandatory key exchange.
t
.
requestKex
<-
struct
{}{}
...
...
@@ -237,6 +239,17 @@ func (t *handshakeTransport) requestKeyExchange() {
}
}
func
(
t
*
handshakeTransport
)
resetWriteThresholds
()
{
t
.
writePacketsLeft
=
packetRekeyThreshold
if
t
.
config
.
RekeyThreshold
>
0
{
t
.
writeBytesLeft
=
int64
(
t
.
config
.
RekeyThreshold
)
}
else
if
t
.
algorithms
!=
nil
{
t
.
writeBytesLeft
=
t
.
algorithms
.
w
.
rekeyBytes
()
}
else
{
t
.
writeBytesLeft
=
1
<<
30
}
}
func
(
t
*
handshakeTransport
)
kexLoop
()
{
write
:
...
...
@@ -285,12 +298,8 @@ write:
t
.
writeError
=
err
t
.
sentInitPacket
=
nil
t
.
sentInitMsg
=
nil
t
.
writePacketsLeft
=
packetRekeyThreshold
if
t
.
config
.
RekeyThreshold
>
0
{
t
.
writeBytesLeft
=
int64
(
t
.
config
.
RekeyThreshold
)
}
else
if
t
.
algorithms
!=
nil
{
t
.
writeBytesLeft
=
t
.
algorithms
.
w
.
rekeyBytes
()
}
t
.
resetWriteThresholds
()
// we have completed the key exchange. Since the
// reader is still blocked, it is safe to clear out
...
...
@@ -344,6 +353,17 @@ write:
// key exchange itself.
const
packetRekeyThreshold
=
(
1
<<
31
)
func
(
t
*
handshakeTransport
)
resetReadThresholds
()
{
t
.
readPacketsLeft
=
packetRekeyThreshold
if
t
.
config
.
RekeyThreshold
>
0
{
t
.
readBytesLeft
=
int64
(
t
.
config
.
RekeyThreshold
)
}
else
if
t
.
algorithms
!=
nil
{
t
.
readBytesLeft
=
t
.
algorithms
.
r
.
rekeyBytes
()
}
else
{
t
.
readBytesLeft
=
1
<<
30
}
}
func
(
t
*
handshakeTransport
)
readOnePacket
(
first
bool
)
([]
byte
,
error
)
{
p
,
err
:=
t
.
conn
.
readPacket
()
if
err
!=
nil
{
...
...
@@ -391,12 +411,7 @@ func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
return
nil
,
err
}
t
.
readPacketsLeft
=
packetRekeyThreshold
if
t
.
config
.
RekeyThreshold
>
0
{
t
.
readBytesLeft
=
int64
(
t
.
config
.
RekeyThreshold
)
}
else
{
t
.
readBytesLeft
=
t
.
algorithms
.
r
.
rekeyBytes
()
}
t
.
resetReadThresholds
()
// By default, a key exchange is hidden from higher layers by
// translating it into msgIgnore.
...
...
@@ -574,7 +589,9 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
}
result
.
SessionID
=
t
.
sessionID
t
.
conn
.
prepareKeyChange
(
t
.
algorithms
,
result
)
if
err
:=
t
.
conn
.
prepareKeyChange
(
t
.
algorithms
,
result
);
err
!=
nil
{
return
err
}
if
err
=
t
.
conn
.
writePacket
([]
byte
{
msgNewKeys
});
err
!=
nil
{
return
err
}
...
...
@@ -614,11 +631,9 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
return
nil
,
err
}
if
t
.
hostKeyCallback
!=
nil
{
err
=
t
.
hostKeyCallback
(
t
.
dialAddress
,
t
.
remoteAddr
,
hostKey
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
t
.
hostKeyCallback
(
t
.
dialAddress
,
t
.
remoteAddr
,
hostKey
)
if
err
!=
nil
{
return
nil
,
err
}
return
result
,
nil
...
...
vendor/golang.org/x/crypto/ssh/keys.go
View file @
cf4faa49
...
...
@@ -824,7 +824,7 @@ func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
// Implemented based on the documentation at
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key
func
parseOpenSSHPrivateKey
(
key
[]
byte
)
(
*
ed25519
.
PrivateKey
,
error
)
{
func
parseOpenSSHPrivateKey
(
key
[]
byte
)
(
crypto
.
PrivateKey
,
error
)
{
magic
:=
append
([]
byte
(
"openssh-key-v1"
),
0
)
if
!
bytes
.
Equal
(
magic
,
key
[
0
:
len
(
magic
)])
{
return
nil
,
errors
.
New
(
"ssh: invalid openssh private key format"
)
...
...
@@ -844,14 +844,15 @@ func parseOpenSSHPrivateKey(key []byte) (*ed25519.PrivateKey, error) {
return
nil
,
err
}
if
w
.
KdfName
!=
"none"
||
w
.
CipherName
!=
"none"
{
return
nil
,
errors
.
New
(
"ssh: cannot decode encrypted private keys"
)
}
pk1
:=
struct
{
Check1
uint32
Check2
uint32
Keytype
string
Pub
[]
byte
Priv
[]
byte
Comment
string
Pad
[]
byte
`ssh:"rest"`
Rest
[]
byte
`ssh:"rest"`
}{}
if
err
:=
Unmarshal
(
w
.
PrivKeyBlock
,
&
pk1
);
err
!=
nil
{
...
...
@@ -862,24 +863,75 @@ func parseOpenSSHPrivateKey(key []byte) (*ed25519.PrivateKey, error) {
return
nil
,
errors
.
New
(
"ssh: checkint mismatch"
)
}
// we only handle ed25519 keys currently
if
pk1
.
Keytype
!=
KeyAlgoED25519
{
return
nil
,
errors
.
New
(
"ssh: unhandled key type"
)
}
// we only handle ed25519 and rsa keys currently
switch
pk1
.
Keytype
{
case
KeyAlgoRSA
:
// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
key
:=
struct
{
N
*
big
.
Int
E
*
big
.
Int
D
*
big
.
Int
Iqmp
*
big
.
Int
P
*
big
.
Int
Q
*
big
.
Int
Comment
string
Pad
[]
byte
`ssh:"rest"`
}{}
if
err
:=
Unmarshal
(
pk1
.
Rest
,
&
key
);
err
!=
nil
{
return
nil
,
err
}
for
i
,
b
:=
range
pk1
.
Pad
{
if
int
(
b
)
!=
i
+
1
{
return
nil
,
errors
.
New
(
"ssh: padding not as expected"
)
for
i
,
b
:=
range
key
.
Pad
{
if
int
(
b
)
!=
i
+
1
{
return
nil
,
errors
.
New
(
"ssh: padding not as expected"
)
}
}
}
if
len
(
pk1
.
Priv
)
!=
ed25519
.
PrivateKeySize
{
return
nil
,
errors
.
New
(
"ssh: private key unexpected length"
)
}
pk
:=
&
rsa
.
PrivateKey
{
PublicKey
:
rsa
.
PublicKey
{
N
:
key
.
N
,
E
:
int
(
key
.
E
.
Int64
()),
},
D
:
key
.
D
,
Primes
:
[]
*
big
.
Int
{
key
.
P
,
key
.
Q
},
}
pk
:=
ed25519
.
PrivateKey
(
make
([]
byte
,
ed25519
.
PrivateKeySize
))
copy
(
pk
,
pk1
.
Priv
)
return
&
pk
,
nil
if
err
:=
pk
.
Validate
();
err
!=
nil
{
return
nil
,
err
}
pk
.
Precompute
()
return
pk
,
nil
case
KeyAlgoED25519
:
key
:=
struct
{
Pub
[]
byte
Priv
[]
byte
Comment
string
Pad
[]
byte
`ssh:"rest"`
}{}
if
err
:=
Unmarshal
(
pk1
.
Rest
,
&
key
);
err
!=
nil
{
return
nil
,
err
}
if
len
(
key
.
Priv
)
!=
ed25519
.
PrivateKeySize
{
return
nil
,
errors
.
New
(
"ssh: private key unexpected length"
)
}
for
i
,
b
:=
range
key
.
Pad
{
if
int
(
b
)
!=
i
+
1
{
return
nil
,
errors
.
New
(
"ssh: padding not as expected"
)
}
}
pk
:=
ed25519
.
PrivateKey
(
make
([]
byte
,
ed25519
.
PrivateKeySize
))
copy
(
pk
,
key
.
Priv
)
return
&
pk
,
nil
default
:
return
nil
,
errors
.
New
(
"ssh: unhandled key type"
)
}
}
// FingerprintLegacyMD5 returns the user presentation of the key's
...
...
vendor/golang.org/x/crypto/ssh/server.go
View file @
cf4faa49
...
...
@@ -45,6 +45,12 @@ type ServerConfig struct {
// authenticating.
NoClientAuth
bool
// MaxAuthTries specifies the maximum number of authentication attempts
// permitted per connection. If set to a negative number, the number of
// attempts are unlimited. If set to zero, the number of attempts are limited
// to 6.
MaxAuthTries
int
// PasswordCallback, if non-nil, is called when a user
// attempts to authenticate using a password.
PasswordCallback
func
(
conn
ConnMetadata
,
password
[]
byte
)
(
*
Permissions
,
error
)
...
...
@@ -141,6 +147,10 @@ type ServerConn struct {
// Request and NewChannel channels must be serviced, or the connection
// will hang.
func
NewServerConn
(
c
net
.
Conn
,
config
*
ServerConfig
)
(
*
ServerConn
,
<-
chan
NewChannel
,
<-
chan
*
Request
,
error
)
{
if
config
.
MaxAuthTries
==
0
{
config
.
MaxAuthTries
=
6
}
fullConf
:=
*
config
fullConf
.
SetDefaults
()
s
:=
&
connection
{
...
...
@@ -267,8 +277,23 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err
var
cache
pubKeyCache
var
perms
*
Permissions
authFailures
:=
0
userAuthLoop
:
for
{
if
authFailures
>=
config
.
MaxAuthTries
&&
config
.
MaxAuthTries
>
0
{
discMsg
:=
&
disconnectMsg
{
Reason
:
2
,
Message
:
"too many authentication failures"
,
}
if
err
:=
s
.
transport
.
writePacket
(
Marshal
(
discMsg
));
err
!=
nil
{
return
nil
,
err
}
return
nil
,
discMsg
}
var
userAuthReq
userAuthRequestMsg
if
packet
,
err
:=
s
.
transport
.
readPacket
();
err
!=
nil
{
return
nil
,
err
...
...
@@ -289,6 +314,11 @@ userAuthLoop:
if
config
.
NoClientAuth
{
authErr
=
nil
}
// allow initial attempt of 'none' without penalty
if
authFailures
==
0
{
authFailures
--
}
case
"password"
:
if
config
.
PasswordCallback
==
nil
{
authErr
=
errors
.
New
(
"ssh: password auth not configured"
)
...
...
@@ -360,6 +390,7 @@ userAuthLoop:
if
isQuery
{
// The client can query if the given public key
// would be okay.
if
len
(
payload
)
>
0
{
return
nil
,
parseError
(
msgUserAuthRequest
)
}
...
...
@@ -409,6 +440,8 @@ userAuthLoop:
break
userAuthLoop
}
authFailures
++
var
failureMsg
userAuthFailureMsg
if
config
.
PasswordCallback
!=
nil
{
failureMsg
.
Methods
=
append
(
failureMsg
.
Methods
,
"password"
)
...
...
vendor/golang.org/x/crypto/ssh/streamlocal.go
0 → 100644
View file @
cf4faa49
package
ssh
import
(
"errors"
"io"
"net"
)
// streamLocalChannelOpenDirectMsg is a struct used for SSH_MSG_CHANNEL_OPEN message
// with "direct-streamlocal@openssh.com" string.
//
// See openssh-portable/PROTOCOL, section 2.4. connection: Unix domain socket forwarding
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL#L235
type
streamLocalChannelOpenDirectMsg
struct
{
socketPath
string
reserved0
string
reserved1
uint32
}
// forwardedStreamLocalPayload is a struct used for SSH_MSG_CHANNEL_OPEN message
// with "forwarded-streamlocal@openssh.com" string.
type
forwardedStreamLocalPayload
struct
{
SocketPath
string
Reserved0
string
}
// streamLocalChannelForwardMsg is a struct used for SSH2_MSG_GLOBAL_REQUEST message
// with "streamlocal-forward@openssh.com"/"cancel-streamlocal-forward@openssh.com" string.
type
streamLocalChannelForwardMsg
struct
{
socketPath
string
}
// ListenUnix is similar to ListenTCP but uses a Unix domain socket.
func
(
c
*
Client
)
ListenUnix
(
socketPath
string
)
(
net
.
Listener
,
error
)
{
m
:=
streamLocalChannelForwardMsg
{
socketPath
,
}
// send message
ok
,
_
,
err
:=
c
.
SendRequest
(
"streamlocal-forward@openssh.com"
,
true
,
Marshal
(
&
m
))
if
err
!=
nil
{
return
nil
,
err
}
if
!
ok
{
return
nil
,
errors
.
New
(
"ssh: streamlocal-forward@openssh.com request denied by peer"
)
}
ch
:=
c
.
forwards
.
add
(
&
net
.
UnixAddr
{
Name
:
socketPath
,
Net
:
"unix"
})
return
&
unixListener
{
socketPath
,
c
,
ch
},
nil
}
func
(
c
*
Client
)
dialStreamLocal
(
socketPath
string
)
(
Channel
,
error
)
{
msg
:=
streamLocalChannelOpenDirectMsg
{
socketPath
:
socketPath
,
}
ch
,
in
,
err
:=
c
.
OpenChannel
(
"direct-streamlocal@openssh.com"
,
Marshal
(
&
msg
))
if
err
!=
nil
{
return
nil
,
err
}
go
DiscardRequests
(
in
)
return
ch
,
err
}
type
unixListener
struct
{
socketPath
string
conn
*
Client
in
<-
chan
forward
}
// Accept waits for and returns the next connection to the listener.
func
(
l
*
unixListener
)
Accept
()
(
net
.
Conn
,
error
)
{
s
,
ok
:=
<-
l
.
in
if
!
ok
{
return
nil
,
io
.
EOF
}
ch
,
incoming
,
err
:=
s
.
newCh
.
Accept
()
if
err
!=
nil
{
return
nil
,
err
}
go
DiscardRequests
(
incoming
)
return
&
chanConn
{
Channel
:
ch
,
laddr
:
&
net
.
UnixAddr
{
Name
:
l
.
socketPath
,
Net
:
"unix"
,
},
raddr
:
&
net
.
UnixAddr
{
Name
:
"@"
,
Net
:
"unix"
,
},
},
nil
}
// Close closes the listener.
func
(
l
*
unixListener
)
Close
()
error
{
// this also closes the listener.
l
.
conn
.
forwards
.
remove
(
&
net
.
UnixAddr
{
Name
:
l
.
socketPath
,
Net
:
"unix"
})
m
:=
streamLocalChannelForwardMsg
{
l
.
socketPath
,
}
ok
,
_
,
err
:=
l
.
conn
.
SendRequest
(
"cancel-streamlocal-forward@openssh.com"
,
true
,
Marshal
(
&
m
))
if
err
==
nil
&&
!
ok
{
err
=
errors
.
New
(
"ssh: cancel-streamlocal-forward@openssh.com failed"
)
}
return
err
}
// Addr returns the listener's network address.
func
(
l
*
unixListener
)
Addr
()
net
.
Addr
{
return
&
net
.
UnixAddr
{
Name
:
l
.
socketPath
,
Net
:
"unix"
,
}
}
vendor/golang.org/x/crypto/ssh/tcpip.go
View file @
cf4faa49
...
...
@@ -20,12 +20,20 @@ import (
// addr. Incoming connections will be available by calling Accept on
// the returned net.Listener. The listener must be serviced, or the
// SSH connection may hang.
// N must be "tcp", "tcp4", "tcp6", or "unix".
func
(
c
*
Client
)
Listen
(
n
,
addr
string
)
(
net
.
Listener
,
error
)
{
laddr
,
err
:=
net
.
ResolveTCPAddr
(
n
,
addr
)
if
err
!=
nil
{
return
nil
,
err
switch
n
{
case
"tcp"
,
"tcp4"
,
"tcp6"
:
laddr
,
err
:=
net
.
ResolveTCPAddr
(
n
,
addr
)
if
err
!=
nil
{
return
nil
,
err
}
return
c
.
ListenTCP
(
laddr
)
case
"unix"
:
return
c
.
ListenUnix
(
addr
)
default
:
return
nil
,
fmt
.
Errorf
(
"ssh: unsupported protocol: %s"
,
n
)
}
return
c
.
ListenTCP
(
laddr
)
}
// Automatic port allocation is broken with OpenSSH before 6.0. See
...
...
@@ -116,7 +124,7 @@ func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error) {
}
// Register this forward, using the port number we obtained.
ch
:=
c
.
forwards
.
add
(
*
laddr
)
ch
:=
c
.
forwards
.
add
(
laddr
)
return
&
tcpListener
{
laddr
,
c
,
ch
},
nil
}
...
...
@@ -131,7 +139,7 @@ type forwardList struct {
// forwardEntry represents an established mapping of a laddr on a
// remote ssh server to a channel connected to a tcpListener.
type
forwardEntry
struct
{
laddr
net
.
TCP
Addr
laddr
net
.
Addr
c
chan
forward
}
...
...
@@ -139,16 +147,16 @@ type forwardEntry struct {
// arguments to add/remove/lookup should be address as specified in
// the original forward-request.
type
forward
struct
{
newCh
NewChannel
// the ssh client channel underlying this forward
raddr
*
net
.
TCPAddr
// the raddr of the incoming connection
newCh
NewChannel
// the ssh client channel underlying this forward
raddr
net
.
Addr
// the raddr of the incoming connection
}
func
(
l
*
forwardList
)
add
(
addr
net
.
TCP
Addr
)
chan
forward
{
func
(
l
*
forwardList
)
add
(
addr
net
.
Addr
)
chan
forward
{
l
.
Lock
()
defer
l
.
Unlock
()
f
:=
forwardEntry
{
addr
,
make
(
chan
forward
,
1
),
laddr
:
addr
,
c
:
make
(
chan
forward
,
1
),
}
l
.
entries
=
append
(
l
.
entries
,
f
)
return
f
.
c
...
...
@@ -176,44 +184,69 @@ func parseTCPAddr(addr string, port uint32) (*net.TCPAddr, error) {
func
(
l
*
forwardList
)
handleChannels
(
in
<-
chan
NewChannel
)
{
for
ch
:=
range
in
{
var
payload
forwardedTCPPayload
if
err
:=
Unmarshal
(
ch
.
ExtraData
(),
&
payload
);
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
"could not parse forwarded-tcpip payload: "
+
err
.
Error
())
continue
var
(
laddr
net
.
Addr
raddr
net
.
Addr
err
error
)
switch
channelType
:=
ch
.
ChannelType
();
channelType
{
case
"forwarded-tcpip"
:
var
payload
forwardedTCPPayload
if
err
=
Unmarshal
(
ch
.
ExtraData
(),
&
payload
);
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
"could not parse forwarded-tcpip payload: "
+
err
.
Error
())
continue
}
// RFC 4254 section 7.2 specifies that incoming
// addresses should list the address, in string
// format. It is implied that this should be an IP
// address, as it would be impossible to connect to it
// otherwise.
laddr
,
err
=
parseTCPAddr
(
payload
.
Addr
,
payload
.
Port
)
if
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
err
.
Error
())
continue
}
raddr
,
err
=
parseTCPAddr
(
payload
.
OriginAddr
,
payload
.
OriginPort
)
if
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
err
.
Error
())
continue
}
case
"forwarded-streamlocal@openssh.com"
:
var
payload
forwardedStreamLocalPayload
if
err
=
Unmarshal
(
ch
.
ExtraData
(),
&
payload
);
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
"could not parse forwarded-streamlocal@openssh.com payload: "
+
err
.
Error
())
continue
}
laddr
=
&
net
.
UnixAddr
{
Name
:
payload
.
SocketPath
,
Net
:
"unix"
,
}
raddr
=
&
net
.
UnixAddr
{
Name
:
"@"
,
Net
:
"unix"
,
}
default
:
panic
(
fmt
.
Errorf
(
"ssh: unknown channel type %s"
,
channelType
))
}
// RFC 4254 section 7.2 specifies that incoming
// addresses should list the address, in string
// format. It is implied that this should be an IP
// address, as it would be impossible to connect to it
// otherwise.
laddr
,
err
:=
parseTCPAddr
(
payload
.
Addr
,
payload
.
Port
)
if
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
err
.
Error
())
continue
}
raddr
,
err
:=
parseTCPAddr
(
payload
.
OriginAddr
,
payload
.
OriginPort
)
if
err
!=
nil
{
ch
.
Reject
(
ConnectionFailed
,
err
.
Error
())
continue
}
if
ok
:=
l
.
forward
(
*
laddr
,
*
raddr
,
ch
);
!
ok
{
if
ok
:=
l
.
forward
(
laddr
,
raddr
,
ch
);
!
ok
{
// Section 7.2, implementations MUST reject spurious incoming
// connections.
ch
.
Reject
(
Prohibited
,
"no forward for address"
)
continue
}
}
}
// remove removes the forward entry, and the channel feeding its
// listener.
func
(
l
*
forwardList
)
remove
(
addr
net
.
TCP
Addr
)
{
func
(
l
*
forwardList
)
remove
(
addr
net
.
Addr
)
{
l
.
Lock
()
defer
l
.
Unlock
()
for
i
,
f
:=
range
l
.
entries
{
if
addr
.
IP
.
Equal
(
f
.
laddr
.
IP
)
&&
addr
.
Port
==
f
.
laddr
.
Port
{
if
addr
.
Network
()
==
f
.
laddr
.
Network
()
&&
addr
.
String
()
==
f
.
laddr
.
String
()
{
l
.
entries
=
append
(
l
.
entries
[
:
i
],
l
.
entries
[
i
+
1
:
]
...
)
close
(
f
.
c
)
return
...
...
@@ -231,12 +264,12 @@ func (l *forwardList) closeAll() {
l
.
entries
=
nil
}
func
(
l
*
forwardList
)
forward
(
laddr
,
raddr
net
.
TCP
Addr
,
ch
NewChannel
)
bool
{
func
(
l
*
forwardList
)
forward
(
laddr
,
raddr
net
.
Addr
,
ch
NewChannel
)
bool
{
l
.
Lock
()
defer
l
.
Unlock
()
for
_
,
f
:=
range
l
.
entries
{
if
laddr
.
IP
.
Equal
(
f
.
laddr
.
IP
)
&&
laddr
.
Port
==
f
.
laddr
.
Port
{
f
.
c
<-
forward
{
ch
,
&
raddr
}
if
laddr
.
Network
()
==
f
.
laddr
.
Network
()
&&
laddr
.
String
()
==
f
.
laddr
.
String
()
{
f
.
c
<-
forward
{
newCh
:
ch
,
raddr
:
raddr
}
return
true
}
}
...
...
@@ -262,7 +295,7 @@ func (l *tcpListener) Accept() (net.Conn, error) {
}
go
DiscardRequests
(
incoming
)
return
&
tcpC
hanConn
{
return
&
c
hanConn
{
Channel
:
ch
,
laddr
:
l
.
laddr
,
raddr
:
s
.
raddr
,
...
...
@@ -277,7 +310,7 @@ func (l *tcpListener) Close() error {
}
// this also closes the listener.
l
.
conn
.
forwards
.
remove
(
*
l
.
laddr
)
l
.
conn
.
forwards
.
remove
(
l
.
laddr
)
ok
,
_
,
err
:=
l
.
conn
.
SendRequest
(
"cancel-tcpip-forward"
,
true
,
Marshal
(
&
m
))
if
err
==
nil
&&
!
ok
{
err
=
errors
.
New
(
"ssh: cancel-tcpip-forward failed"
)
...
...
@@ -293,29 +326,52 @@ func (l *tcpListener) Addr() net.Addr {
// Dial initiates a connection to the addr from the remote host.
// The resulting connection has a zero LocalAddr() and RemoteAddr().
func
(
c
*
Client
)
Dial
(
n
,
addr
string
)
(
net
.
Conn
,
error
)
{
// Parse the address into host and numeric port.
host
,
portString
,
err
:=
net
.
SplitHostPort
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
port
,
err
:=
strconv
.
ParseUint
(
portString
,
10
,
16
)
if
err
!=
nil
{
return
nil
,
err
}
// Use a zero address for local and remote address.
zeroAddr
:=
&
net
.
TCPAddr
{
IP
:
net
.
IPv4zero
,
Port
:
0
,
}
ch
,
err
:=
c
.
dial
(
net
.
IPv4zero
.
String
(),
0
,
host
,
int
(
port
))
if
err
!=
nil
{
return
nil
,
err
var
ch
Channel
switch
n
{
case
"tcp"
,
"tcp4"
,
"tcp6"
:
// Parse the address into host and numeric port.
host
,
portString
,
err
:=
net
.
SplitHostPort
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
port
,
err
:=
strconv
.
ParseUint
(
portString
,
10
,
16
)
if
err
!=
nil
{
return
nil
,
err
}
ch
,
err
=
c
.
dial
(
net
.
IPv4zero
.
String
(),
0
,
host
,
int
(
port
))
if
err
!=
nil
{
return
nil
,
err
}
// Use a zero address for local and remote address.
zeroAddr
:=
&
net
.
TCPAddr
{
IP
:
net
.
IPv4zero
,
Port
:
0
,
}
return
&
chanConn
{
Channel
:
ch
,
laddr
:
zeroAddr
,
raddr
:
zeroAddr
,
},
nil
case
"unix"
:
var
err
error
ch
,
err
=
c
.
dialStreamLocal
(
addr
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
chanConn
{
Channel
:
ch
,
laddr
:
&
net
.
UnixAddr
{
Name
:
"@"
,
Net
:
"unix"
,
},
raddr
:
&
net
.
UnixAddr
{
Name
:
addr
,
Net
:
"unix"
,
},
},
nil
default
:
return
nil
,
fmt
.
Errorf
(
"ssh: unsupported protocol: %s"
,
n
)
}
return
&
tcpChanConn
{
Channel
:
ch
,
laddr
:
zeroAddr
,
raddr
:
zeroAddr
,
},
nil
}
// DialTCP connects to the remote address raddr on the network net,
...
...
@@ -332,7 +388,7 @@ func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error)
if
err
!=
nil
{
return
nil
,
err
}
return
&
tcpC
hanConn
{
return
&
c
hanConn
{
Channel
:
ch
,
laddr
:
laddr
,
raddr
:
raddr
,
...
...
@@ -366,26 +422,26 @@ type tcpChan struct {
Channel
// the backing channel
}
//
tcpC
hanConn fulfills the net.Conn interface without
//
c
hanConn fulfills the net.Conn interface without
// the tcpChan having to hold laddr or raddr directly.
type
tcpC
hanConn
struct
{
type
c
hanConn
struct
{
Channel
laddr
,
raddr
net
.
Addr
}
// LocalAddr returns the local network address.
func
(
t
*
tcpC
hanConn
)
LocalAddr
()
net
.
Addr
{
func
(
t
*
c
hanConn
)
LocalAddr
()
net
.
Addr
{
return
t
.
laddr
}
// RemoteAddr returns the remote network address.
func
(
t
*
tcpC
hanConn
)
RemoteAddr
()
net
.
Addr
{
func
(
t
*
c
hanConn
)
RemoteAddr
()
net
.
Addr
{
return
t
.
raddr
}
// SetDeadline sets the read and write deadlines associated
// with the connection.
func
(
t
*
tcpC
hanConn
)
SetDeadline
(
deadline
time
.
Time
)
error
{
func
(
t
*
c
hanConn
)
SetDeadline
(
deadline
time
.
Time
)
error
{
if
err
:=
t
.
SetReadDeadline
(
deadline
);
err
!=
nil
{
return
err
}
...
...
@@ -396,12 +452,14 @@ func (t *tcpChanConn) SetDeadline(deadline time.Time) error {
// A zero value for t means Read will not time out.
// After the deadline, the error from Read will implement net.Error
// with Timeout() == true.
func
(
t
*
tcpChanConn
)
SetReadDeadline
(
deadline
time
.
Time
)
error
{
func
(
t
*
chanConn
)
SetReadDeadline
(
deadline
time
.
Time
)
error
{
// for compatibility with previous version,
// the error message contains "tcpChan"
return
errors
.
New
(
"ssh: tcpChan: deadline not supported"
)
}
// SetWriteDeadline exists to satisfy the net.Conn interface
// but is not implemented by this type. It always returns an error.
func
(
t
*
tcpC
hanConn
)
SetWriteDeadline
(
deadline
time
.
Time
)
error
{
func
(
t
*
c
hanConn
)
SetWriteDeadline
(
deadline
time
.
Time
)
error
{
return
errors
.
New
(
"ssh: tcpChan: deadline not supported"
)
}
vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go
View file @
cf4faa49
...
...
@@ -14,14 +14,12 @@ import (
// State contains the state of a terminal.
type
State
struct
{
termios
syscall
.
Termios
state
*
unix
.
Termios
}
// IsTerminal returns true if the given file descriptor is a terminal.
func
IsTerminal
(
fd
int
)
bool
{
// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c
var
termio
unix
.
Termio
err
:=
unix
.
IoctlSetTermio
(
fd
,
unix
.
TCGETA
,
&
termio
)
_
,
err
:=
unix
.
IoctlGetTermio
(
fd
,
unix
.
TCGETA
)
return
err
==
nil
}
...
...
@@ -71,3 +69,60 @@ func ReadPassword(fd int) ([]byte, error) {
return
ret
,
nil
}
// MakeRaw puts the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
// see http://cr.illumos.org/~webrev/andy_js/1060/
func
MakeRaw
(
fd
int
)
(
*
State
,
error
)
{
oldTermiosPtr
,
err
:=
unix
.
IoctlGetTermios
(
fd
,
unix
.
TCGETS
)
if
err
!=
nil
{
return
nil
,
err
}
oldTermios
:=
*
oldTermiosPtr
newTermios
:=
oldTermios
newTermios
.
Iflag
&^=
syscall
.
IGNBRK
|
syscall
.
BRKINT
|
syscall
.
PARMRK
|
syscall
.
ISTRIP
|
syscall
.
INLCR
|
syscall
.
IGNCR
|
syscall
.
ICRNL
|
syscall
.
IXON
newTermios
.
Oflag
&^=
syscall
.
OPOST
newTermios
.
Lflag
&^=
syscall
.
ECHO
|
syscall
.
ECHONL
|
syscall
.
ICANON
|
syscall
.
ISIG
|
syscall
.
IEXTEN
newTermios
.
Cflag
&^=
syscall
.
CSIZE
|
syscall
.
PARENB
newTermios
.
Cflag
|=
syscall
.
CS8
newTermios
.
Cc
[
unix
.
VMIN
]
=
1
newTermios
.
Cc
[
unix
.
VTIME
]
=
0
if
err
:=
unix
.
IoctlSetTermios
(
fd
,
unix
.
TCSETS
,
&
newTermios
);
err
!=
nil
{
return
nil
,
err
}
return
&
State
{
state
:
oldTermiosPtr
,
},
nil
}
// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func
Restore
(
fd
int
,
oldState
*
State
)
error
{
return
unix
.
IoctlSetTermios
(
fd
,
unix
.
TCSETS
,
oldState
.
state
)
}
// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func
GetState
(
fd
int
)
(
*
State
,
error
)
{
oldTermiosPtr
,
err
:=
unix
.
IoctlGetTermios
(
fd
,
unix
.
TCGETS
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
State
{
state
:
oldTermiosPtr
,
},
nil
}
// GetSize returns the dimensions of the given terminal.
func
GetSize
(
fd
int
)
(
width
,
height
int
,
err
error
)
{
ws
,
err
:=
unix
.
IoctlGetWinsize
(
fd
,
unix
.
TIOCGWINSZ
)
if
err
!=
nil
{
return
0
,
0
,
err
}
return
int
(
ws
.
Col
),
int
(
ws
.
Row
),
nil
}
vendor/vendor.json
View file @
cf4faa49
...
...
@@ -384,92 +384,92 @@
{
"checksumSHA1"
:
"TT1rac6kpQp2vz24m5yDGUNQ/QQ="
,
"path"
:
"golang.org/x/crypto/cast5"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"
C1KKOxFoW7/W/NFNpiXK+boguNo
="
,
"checksumSHA1"
:
"
nAu0XmCeC6WnUySyI8R7w4cxAqU
="
,
"path"
:
"golang.org/x/crypto/curve25519"
,
"revision"
:
"
459e26527287adbc2adcc5d0d49abff9a5f315a7
"
,
"revisionTime"
:
"2017-0
3-17T13:29:17
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"wGb//LjBPNxYHqk+dcLo7BjPXK8="
,
"path"
:
"golang.org/x/crypto/ed25519"
,
"revision"
:
"
459e26527287adbc2adcc5d0d49abff9a5f315a7
"
,
"revisionTime"
:
"2017-0
3-17T13:29:17
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"LXFcVx8I587SnWmKycSDEq9yvK8="
,
"path"
:
"golang.org/x/crypto/ed25519/internal/edwards25519"
,
"revision"
:
"
459e26527287adbc2adcc5d0d49abff9a5f315a7
"
,
"revisionTime"
:
"2017-0
3-17T13:29:17
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"IIhFTrLlmlc6lEFSitqi4aw2lw0="
,
"path"
:
"golang.org/x/crypto/openpgp"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"olOKkhrdkYQHZ0lf1orrFQPQrv4="
,
"path"
:
"golang.org/x/crypto/openpgp/armor"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"eo/KtdjieJQXH7Qy+faXFcF70ME="
,
"path"
:
"golang.org/x/crypto/openpgp/elgamal"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"rlxVSaGgqdAgwblsErxTxIfuGfg="
,
"path"
:
"golang.org/x/crypto/openpgp/errors"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"LWdaR8Q9yn6eBCcnGl0HvJRDUBE="
,
"path"
:
"golang.org/x/crypto/openpgp/packet"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"s2qT4UwvzBSkzXuiuMkowif1Olw="
,
"path"
:
"golang.org/x/crypto/openpgp/s2k"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"1MGpGDQqnUoRpv7VEcQrXOBydXE="
,
"path"
:
"golang.org/x/crypto/pbkdf2"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"y/oIaxq2d3WPizRZfVjo8RCRYTU="
,
"path"
:
"golang.org/x/crypto/ripemd160"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"E8pDMGySfy5Mw+jzXOkOxo35bww="
,
"path"
:
"golang.org/x/crypto/scrypt"
,
"revision"
:
"
453249f01cfeb54c3d549ddb75ff152ca243f9d8
"
,
"revisionTime"
:
"2017-0
2-08T20:51:15
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"
fsrFs762jlaILyqqQImS1GfvIvw
="
,
"checksumSHA1"
:
"
8sVsMTphul+B0sI0qAv4TE1ZxUk
="
,
"path"
:
"golang.org/x/crypto/ssh"
,
"revision"
:
"
459e26527287adbc2adcc5d0d49abff9a5f315a7
"
,
"revisionTime"
:
"2017-0
3-17T13:29:17
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"
xiderUuvye8Kpn7yX3niiJg32bE
="
,
"checksumSHA1"
:
"
ZaU56svwLgiJD0y8JOB3+/mpYBA
="
,
"path"
:
"golang.org/x/crypto/ssh/terminal"
,
"revision"
:
"
459e26527287adbc2adcc5d0d49abff9a5f315a7
"
,
"revisionTime"
:
"2017-0
3-17T13:29:17
Z"
"revision"
:
"
c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
"
,
"revisionTime"
:
"2017-0
4-25T18:31:00
Z"
},
{
"checksumSHA1"
:
"Y+HGqEkYM15ir+J93MEaHdyFy0c="
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment