Moved from using logging default logger to a package wide logger that is disabled by default.

This commit is contained in:
Justin Judd 2016-07-30 21:35:10 +09:00
parent 3bc1eb83dd
commit 0919fef40d
9 changed files with 56 additions and 43 deletions

View File

@ -1,7 +1,6 @@
package easyssh package easyssh
import ( import (
"log"
"net" "net"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -34,7 +33,7 @@ func (c *Client) LocalForward(laddr, raddr *net.TCPAddr) error {
println(err.Error()) println(err.Error())
return err return err
} }
log.Println("Listening on address: ", ln.Addr().String()) logger.Println("Listening on address: ", ln.Addr().String())
quit := make(chan bool) quit := make(chan bool)

View File

@ -2,12 +2,25 @@ package easyssh
import ( import (
"fmt" "fmt"
"io"
"io/ioutil"
"log" "log"
"sync" "sync"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
var logger *log.Logger
func init() {
logger = log.New(ioutil.Discard, "easyssh", 0)
}
// EnableLogging enables logging for the easyssh library
func EnableLogging(output io.Writer) {
logger.SetOutput(output)
}
// A ConnHandler is a top level SSH Manager. Objects implementing the ConnHandler are responsible for managing incoming Channels and Global Requests // A ConnHandler is a top level SSH Manager. Objects implementing the ConnHandler are responsible for managing incoming Channels and Global Requests
type ConnHandler interface { type ConnHandler interface {
HandleSSHConn(ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request) HandleSSHConn(ssh.Conn, <-chan ssh.NewChannel, <-chan *ssh.Request)
@ -168,7 +181,7 @@ func (s *GlobalMultipleRequestsMux) HandleRequest(requestType string, handler Gl
} }
// HandleRequestFunc registers the Channel Handler function for the provided Request Type // HandleRequestFunc registers the Channel Handler function for the provided Request Type
func (s *GlobalMultipleRequestsMux) HandleRequestFunc(requestType string, f GlobalRequestHandlerFunc) { func (s *GlobalMultipleRequestsMux) HandleRequestFunc(requestType string, f func(*ssh.Request, ssh.Conn)) {
s.HandleRequest(requestType, GlobalRequestHandlerFunc(f)) s.HandleRequest(requestType, GlobalRequestHandlerFunc(f))
} }
@ -186,7 +199,7 @@ func (s *ChannelsMux) HandleChannel(channelType string, handler ChannelHandler)
} }
// HandleChannelFunc registers the Channel Handler function for the provided Channel Type // HandleChannelFunc registers the Channel Handler function for the provided Channel Type
func (s *ChannelsMux) HandleChannelFunc(channelType string, f ChannelHandlerFunc) { func (s *ChannelsMux) HandleChannelFunc(channelType string, f func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn ssh.Conn)) {
s.HandleChannel(channelType, ChannelHandlerFunc(f)) s.HandleChannel(channelType, ChannelHandlerFunc(f))
} }
@ -211,7 +224,7 @@ func (s *GlobalMultipleRequestsMux) HandleRequests(reqs <-chan *ssh.Request, ssh
func (s *ChannelsMux) HandleChannels(chans <-chan ssh.NewChannel, sshConn ssh.Conn) { func (s *ChannelsMux) HandleChannels(chans <-chan ssh.NewChannel, sshConn ssh.Conn) {
for newChannel := range chans { for newChannel := range chans {
log.Printf("Received channel: %v", newChannel.ChannelType()) logger.Printf("Received channel: %v", newChannel.ChannelType())
// Check the type of channel // Check the type of channel
t := newChannel.ChannelType() t := newChannel.ChannelType()
@ -220,14 +233,14 @@ func (s *ChannelsMux) HandleChannels(chans <-chan ssh.NewChannel, sshConn ssh.Co
s.channelMutex.RUnlock() s.channelMutex.RUnlock()
if !ok { if !ok {
log.Printf("Unknown channel type: %s", t) logger.Printf("Unknown channel type: %s", t)
newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t)) newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
continue continue
} }
channel, requests, err := newChannel.Accept() channel, requests, err := newChannel.Accept()
if err != nil { if err != nil {
log.Printf("could not accept channel (%s)", err) logger.Printf("could not accept channel (%s)", err)
continue continue
} }
go handler.HandleChannel(newChannel, channel, requests, sshConn) go handler.HandleChannel(newChannel, channel, requests, sshConn)
@ -251,8 +264,8 @@ func HandleRequest(requestType string, handler GlobalRequestHandler) {
} }
// HandleRequestFunc registers the given handler function with the DefaultGlobalMultipleRequestsHandler // HandleRequestFunc registers the given handler function with the DefaultGlobalMultipleRequestsHandler
func HandleRequestFunc(requestType string, handler GlobalRequestHandlerFunc) { func HandleRequestFunc(requestType string, handler func(*ssh.Request, ssh.Conn)) {
DefaultGlobalMultipleRequestsHandler.HandleRequestFunc(requestType, handler) DefaultGlobalMultipleRequestsHandler.HandleRequestFunc(requestType, GlobalRequestHandlerFunc(handler))
} }
// HandleChannel registers the given handler under the channelType with the DefaultMultipleChannelsHandler // HandleChannel registers the given handler under the channelType with the DefaultMultipleChannelsHandler
@ -261,8 +274,8 @@ func HandleChannel(channelType string, handler ChannelHandler) {
} }
// HandleChannelFunc registers the given handler function under the channelType with the DefaultMultipleChannelsHandler // HandleChannelFunc registers the given handler function under the channelType with the DefaultMultipleChannelsHandler
func HandleChannelFunc(channelType string, handler ChannelHandlerFunc) { func HandleChannelFunc(channelType string, handler func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn ssh.Conn)) {
DefaultMultipleChannelsHandler.HandleChannelFunc(channelType, handler) DefaultMultipleChannelsHandler.HandleChannelFunc(channelType, ChannelHandlerFunc(handler))
} }
type channelsHandler struct { type channelsHandler struct {

View File

@ -2,6 +2,7 @@ package easyssh_test
import ( import (
"log" "log"
"net"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -35,7 +36,9 @@ func ExampleClient_LocalForward() {
} }
defer conn.Close() defer conn.Close()
err = conn.LocalForward("localhost:8000", "localhost:6060") laddr, _ := net.ResolveTCPAddr("tcp", "localhost:8000")
raddr, _ := net.ResolveTCPAddr("tcp", "localhost:6060")
err = conn.LocalForward(laddr, raddr)
if err != nil { if err != nil {
log.Fatalf("unable to forward local port: %s", err) log.Fatalf("unable to forward local port: %s", err)
} }

View File

@ -8,7 +8,7 @@ import (
type testHandler struct{} type testHandler struct{}
func (testHandler) HandleChannel(nCh ssh.NewChannel, ch ssh.Channel, reqs <-chan *ssh.Request, conn *ssh.ServerConn) { func (testHandler) HandleChannel(nCh ssh.NewChannel, ch ssh.Channel, reqs <-chan *ssh.Request, conn ssh.Conn) {
defer ch.Close() defer ch.Close()
// Do something // Do something
} }
@ -18,7 +18,7 @@ func ExampleChannelsMux_HandleChannel() {
handler.HandleChannel("test", testHandler{}) handler.HandleChannel("test", testHandler{})
test2Handler := func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn *ssh.ServerConn) { test2Handler := func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn ssh.Conn) {
defer channel.Close() defer channel.Close()
ssh.DiscardRequests(reqs) ssh.DiscardRequests(reqs)
} }

View File

@ -34,7 +34,7 @@ func ExampleDirectPortForwardChannel() {
s.Config = config s.Config = config
handler := easyssh.NewServerHandler() handler := easyssh.NewStandardSSHServerHandler()
channelHandler := easyssh.NewChannelsMux() channelHandler := easyssh.NewChannelsMux()
channelHandler.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler()) channelHandler.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler())

View File

@ -34,7 +34,7 @@ func ExampleServer_ListenAndServe() {
s.Config = config s.Config = config
handler := easyssh.NewServerHandler() handler := easyssh.NewStandardSSHServerHandler()
channelHandler := easyssh.NewChannelsMux() channelHandler := easyssh.NewChannelsMux()
channelHandler.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler()) channelHandler.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler())
@ -46,6 +46,7 @@ func ExampleServer_ListenAndServe() {
} }
func ExampleListenAndServe() { func ExampleListenAndServe() {
config := &ssh.ServerConfig{}
easyssh.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler()) easyssh.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler())
easyssh.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler()) easyssh.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler())
easyssh.HandleRequestFunc(easyssh.RemoteForwardRequest, easyssh.TCPIPForwardRequest) easyssh.HandleRequestFunc(easyssh.RemoteForwardRequest, easyssh.TCPIPForwardRequest)
@ -56,7 +57,7 @@ func ExampleListenAndServe() {
func ExampleChannelsMux_HandleChannelFunc() { func ExampleChannelsMux_HandleChannelFunc() {
handler := easyssh.NewChannelsMux() handler := easyssh.NewChannelsMux()
testHandler := func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn *ssh.ServerConn) { testHandler := func(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan *ssh.Request, sshConn ssh.Conn) {
defer channel.Close() defer channel.Close()
ssh.DiscardRequests(reqs) ssh.DiscardRequests(reqs)
} }

View File

@ -1,7 +1,6 @@
package easyssh package easyssh
import ( import (
"log"
"net" "net"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -31,7 +30,7 @@ func (s *Server) ListenAndServe() error {
// Serve accepts incoming connections on the provided listener.and reads global SSH Channel and Out-of-band requests and calls s,ConnHandler to handle them // Serve accepts incoming connections on the provided listener.and reads global SSH Channel and Out-of-band requests and calls s,ConnHandler to handle them
func (s *Server) Serve(l net.Listener) error { func (s *Server) Serve(l net.Listener) error {
defer l.Close() defer l.Close()
log.Print("SSH Server started listening on: ", l.Addr()) logger.Print("SSH Server started listening on: ", l.Addr())
for { for {
tcpConn, err := l.Accept() tcpConn, err := l.Accept()
if err != nil { if err != nil {
@ -59,7 +58,7 @@ func (s *Server) HandleOpenChannel(channelName string, handler ChannelMultipleRe
// HandleOpenChannelFunc requests that the remote end accept a channel request and if accepted, // HandleOpenChannelFunc requests that the remote end accept a channel request and if accepted,
// passes the newly opened channel and requests to the provided handler function // passes the newly opened channel and requests to the provided handler function
func (s *Server) HandleOpenChannelFunc(channelName string, handler ChannelMultipleRequestsHandlerFunc, data ...byte) error { func (s *Server) HandleOpenChannelFunc(channelName string, handler func(reqs <-chan *ssh.Request, sshConn ssh.Conn, channelType string, channel ssh.Channel), data ...byte) error {
return s.HandleOpenChannel(channelName, ChannelMultipleRequestsHandlerFunc(handler), data...) return s.HandleOpenChannel(channelName, ChannelMultipleRequestsHandlerFunc(handler), data...)
} }
@ -76,11 +75,11 @@ func (c *conn) serve() {
return return
} }
c.server.ServerConn = sshConn c.server.ServerConn = sshConn
log.Print("New ssh connection from: ", c.conn.RemoteAddr()) logger.Print("New ssh connection from: ", c.conn.RemoteAddr())
go func() { go func() {
sshConn.Wait() sshConn.Wait()
log.Print("Closing ssh connection from: ", c.conn.RemoteAddr()) logger.Print("Closing ssh connection from: ", c.conn.RemoteAddr())
if c.conn != nil { if c.conn != nil {
c.conn.Close() c.conn.Close()
//c.conn = nil //c.conn = nil

View File

@ -4,7 +4,6 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
"log"
"os" "os"
"os/exec" "os/exec"
"sync" "sync"
@ -42,7 +41,7 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
c := exec.Command(shell) c := exec.Command(shell)
f, err := pty.Start(c) f, err := pty.Start(c)
if err != nil { if err != nil {
log.Printf("Unable to start shell: %s", shell) logger.Printf("Unable to start shell: %s", shell)
return return
} }
@ -53,9 +52,9 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
channel.Close() channel.Close()
err := c.Wait() err := c.Wait()
if err != nil { if err != nil {
log.Printf("failed to exit bash (%s)", err) logger.Printf("failed to exit bash (%s)", err)
} }
log.Printf("session closed") logger.Printf("session closed")
} }
go func(in <-chan *ssh.Request) { go func(in <-chan *ssh.Request) {
@ -73,11 +72,11 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
pty := ptyReq{} pty := ptyReq{}
err = ssh.Unmarshal(req.Payload, &pty) err = ssh.Unmarshal(req.Payload, &pty)
if err != nil { if err != nil {
log.Printf("Unable to decode pty request: %s", err.Error()) logger.Printf("Unable to decode pty request: %s", err.Error())
} }
setWinsize(f.Fd(), pty.Width, pty.Height) setWinsize(f.Fd(), pty.Width, pty.Height)
log.Printf("pty-req '%s'", pty.Term) logger.Printf("pty-req '%s'", pty.Term)
type termModeStruct struct { type termModeStruct struct {
//Key byte //Key byte
@ -115,7 +114,7 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
win := windowDimensionReq{} win := windowDimensionReq{}
err = ssh.Unmarshal(req.Payload, &win) err = ssh.Unmarshal(req.Payload, &win)
if err != nil { if err != nil {
log.Printf("Error reading window dimension change request: %s", err.Error()) logger.Printf("Error reading window dimension change request: %s", err.Error())
} }
setWinsize(f.Fd(), win.Width, win.Height) setWinsize(f.Fd(), win.Width, win.Height)
continue //no response according to RFC 4254 6.7 continue //no response according to RFC 4254 6.7
@ -132,20 +131,20 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
} }
command = exec.Command("sh", "-c", cmd.Command) // Let shell do the parsing command = exec.Command("sh", "-c", cmd.Command) // Let shell do the parsing
log.Printf("exec starting: %s", cmd.Command) logger.Printf("exec starting: %s", cmd.Command)
//c.Env = append(c.Env, env...) //c.Env = append(c.Env, env...)
exitStatus := exitStatusReq{} exitStatus := exitStatusReq{}
fd, err := pty.Start(command) fd, err := pty.Start(command)
if err != nil { if err != nil {
log.Printf("Unable to wrap exec command in pty\n") logger.Printf("Unable to wrap exec command in pty\n")
return return
} }
execClose := func() { execClose := func() {
channel.Close() channel.Close()
log.Printf("exec finished: %s", cmd.Command) logger.Printf("exec finished: %s", cmd.Command)
} }
defer fd.Close() defer fd.Close()
@ -160,7 +159,7 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
//command.Stdin = channel // TODO: test how stdin works on exec on openssh server //command.Stdin = channel // TODO: test how stdin works on exec on openssh server
//err = command.Run() //err = command.Run()
if err != nil { if err != nil {
log.Printf("Error running exec : %s", err.Error()) logger.Printf("Error running exec : %s", err.Error())
e, ok := err.(*exec.ExitError) e, ok := err.(*exec.ExitError)
errVal := 1 errVal := 1
if ok { if ok {
@ -202,7 +201,7 @@ func SessionChannel(newChannel ssh.NewChannel, channel ssh.Channel, reqs <-chan
ok = true ok = true
sig := signalRequest{} sig := signalRequest{}
ssh.Unmarshal(req.Payload, &sig) ssh.Unmarshal(req.Payload, &sig)
log.Println("Received Signal: ", sig.Signal) logger.Println("Received Signal: ", sig.Signal)
s := signalsMap[sig.Signal] s := signalsMap[sig.Signal]
if command != nil { if command != nil {
@ -307,7 +306,7 @@ type winsize struct {
// SetWinsize uses syscall to set pty window size // SetWinsize uses syscall to set pty window size
func setWinsize(fd uintptr, w, h uint32) { func setWinsize(fd uintptr, w, h uint32) {
log.Printf("Resize Window to %dx%d", w, h) logger.Printf("Resize Window to %dx%d", w, h)
ws := &winsize{Col: uint16(w), Row: uint16(h)} ws := &winsize{Col: uint16(w), Row: uint16(h)}
syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws))) syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
} }

View File

@ -3,7 +3,6 @@ package easyssh
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log"
"net" "net"
"strconv" "strconv"
@ -53,10 +52,10 @@ func TCPIPForwardRequest(req *ssh.Request, sshConn ssh.Conn) {
ln, err := net.Listen("tcp", addr) //tie to the client connection ln, err := net.Listen("tcp", addr) //tie to the client connection
if err != nil { if err != nil {
log.Println("Unable to listen on address: ", addr) logger.Println("Unable to listen on address: ", addr)
return return
} }
log.Println("Listening on address: ", ln.Addr().String()) logger.Println("Listening on address: ", ln.Addr().String())
quit := make(chan bool) quit := make(chan bool)
@ -102,7 +101,7 @@ func TCPIPForwardRequest(req *ssh.Request, sshConn ssh.Conn) {
p.Port2 = uint32(portnum) p.Port2 = uint32(portnum)
ch, reqs, err := sshConn.OpenChannel(ForwardedTCPReturnRequest, ssh.Marshal(p)) ch, reqs, err := sshConn.OpenChannel(ForwardedTCPReturnRequest, ssh.Marshal(p))
if err != nil { if err != nil {
log.Println("Open forwarded Channel: ", err.Error()) logger.Println("Open forwarded Channel: ", err.Error())
return return
} }
ssh.DiscardRequests(reqs) ssh.DiscardRequests(reqs)
@ -112,7 +111,7 @@ func TCPIPForwardRequest(req *ssh.Request, sshConn ssh.Conn) {
ch.Close() ch.Close()
conn.Close() conn.Close()
// log.Printf("forwarding closed") // logger.Printf("forwarding closed")
} }
go CopyReadWriters(conn, ch, close) go CopyReadWriters(conn, ch, close)
@ -126,7 +125,7 @@ func TCPIPForwardRequest(req *ssh.Request, sshConn ssh.Conn) {
}() }()
sshConn.Wait() sshConn.Wait()
log.Println("Stop forwarding/listening on ", ln.Addr()) logger.Println("Stop forwarding/listening on ", ln.Addr())
ln.Close() ln.Close()
quit <- true quit <- true
@ -151,7 +150,7 @@ func DirectPortForwardChannel(newChannel ssh.NewChannel, channel ssh.Channel, re
p := directForward{} p := directForward{}
ssh.Unmarshal(newChannel.ExtraData(), &p) ssh.Unmarshal(newChannel.ExtraData(), &p)
log.Println(p) logger.Println(p)
go func(ch ssh.Channel, sshConn ssh.Conn) { go func(ch ssh.Channel, sshConn ssh.Conn) {
addr := fmt.Sprintf("%s:%d", p.Host1, p.Port1) addr := fmt.Sprintf("%s:%d", p.Host1, p.Port1)
@ -163,7 +162,7 @@ func DirectPortForwardChannel(newChannel ssh.NewChannel, channel ssh.Channel, re
ch.Close() ch.Close()
conn.Close() conn.Close()
//log.Printf("forwarding closed") //logger.Printf("forwarding closed")
} }
go CopyReadWriters(conn, ch, close) go CopyReadWriters(conn, ch, close)