Giter Site home page Giter Site logo

reiver / go-telnet Goto Github PK

View Code? Open in Web Editor NEW
257.0 10.0 82.0 171 KB

Package telnet provides TELNET and TELNETS client and server implementations, for the Go programming language, in a style similar to the "net/http" library that is part of the Go standard library, including support for "middleware"; TELNETS is secure TELNET, with the TELNET protocol over a secured TLS (or SSL) connection.

Home Page: https://godoc.org/github.com/reiver/go-telnet

License: MIT License

Go 100.00%
telnets telnet telnet-protocol telnet-server telnet-client rfc-15 rfc-854

go-telnet's Introduction

go-telnet

Package telnet provides TELNET and TELNETS client and server implementations, for the Go programming language.

The telnet package provides an API in a style similar to the "net/http" library that is part of the Go standard library, including support for "middleware".

(TELNETS is secure TELNET, with the TELNET protocol over a secured TLS (or SSL) connection.)

Documention

Online documentation, which includes examples, can be found at: http://godoc.org/github.com/reiver/go-telnet

GoDoc

Very Simple TELNET Server Example

A very very simple TELNET server is shown in the following code.

This particular TELNET server just echos back to the user anything they "submit" to the server.

(By default, a TELNET client does not send anything to the server until the [Enter] key is pressed. "Submit" means typing something and then pressing the [Enter] key.)

package main

import (
	"github.com/reiver/go-telnet"
)

func main() {

	var handler telnet.Handler = telnet.EchoHandler
	
	err := telnet.ListenAndServe(":5555", handler)
	if nil != err {
		//@TODO: Handle this error better.
		panic(err)
	}
}

If you wanted to test out this very very simple TELNET server, if you were on the same computer it was running, you could connect to it using the bash command:

telnet localhost 5555

(Note that we use the same TCP port number -- "5555" -- as we had in our code. That is important, as the value used by your TELNET server and the value used by your TELNET client must match.)

Very Simple (Secure) TELNETS Server Example

TELNETS is the secure version of TELNET.

The code to make a TELNETS server is very similar to the code to make a TELNET server. (The difference between we use the telnet.ListenAndServeTLS func instead of the telnet.ListenAndServe func.)

package main

import (
	"github.com/reiver/go-telnet"
)

func main() {

	var handler telnet.Handler = telnet.EchoHandler
	
	err := telnet.ListenAndServeTLS(":5555", "cert.pem", "key.pem", handler)
	if nil != err {
		//@TODO: Handle this error better.
		panic(err)
	}
}

If you wanted to test out this very very simple TELNETS server, get the telnets client program from here: https://github.com/reiver/telnets

TELNET Client Example:

package main

import (
	"github.com/reiver/go-telnet"
)

func main() {
	var caller telnet.Caller = telnet.StandardCaller

	//@TOOD: replace "example.net:5555" with address you want to connect to.
	telnet.DialToAndCall("example.net:5555", caller)
}

TELNETS Client Example:

package main

import (
	"github.com/reiver/go-telnet"

	"crypto/tls"
)

func main() {
	//@TODO: Configure the TLS connection here, if you need to.
	tlsConfig := &tls.Config{}

	var caller telnet.Caller = telnet.StandardCaller

	//@TOOD: replace "example.net:5555" with address you want to connect to.
	telnet.DialToAndCallTLS("example.net:5555", caller, tlsConfig)
}

TELNET Shell Server Example

A more useful TELNET servers can be made using the "github.com/reiver/go-telnet/telsh" sub-package.

For example:

package main


import (
	"github.com/reiver/go-oi"
	"github.com/reiver/go-telnet"
	"github.com/reiver/go-telnet/telsh"

	"io"
	"time"
)



func fiveHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
	oi.LongWriteString(stdout, "The number FIVE looks like this: 5\r\n")

	return nil
}

func fiveProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{
	return telsh.PromoteHandlerFunc(fiveHandler)
}



func danceHandler(stdin io.ReadCloser, stdout io.WriteCloser, stderr io.WriteCloser, args ...string) error {
	for i:=0; i<20; i++ {
		oi.LongWriteString(stdout, "\r⠋")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠙")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠹")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠸")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠼")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠴")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠦")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠧")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠇")
		time.Sleep(50*time.Millisecond)

		oi.LongWriteString(stdout, "\r⠏")
		time.Sleep(50*time.Millisecond)
	}
	oi.LongWriteString(stdout, "\r \r\n")

	return nil
}

func danceProducer(ctx telnet.Context, name string, args ...string) telsh.Handler{

	return telsh.PromoteHandlerFunc(danceHandler)
}


func main() {

	shellHandler := telsh.NewShellHandler()

	shellHandler.WelcomeMessage = `
 __          __ ______  _        _____   ____   __  __  ______ 
 \ \        / /|  ____|| |      / ____| / __ \ |  \/  ||  ____|
  \ \  /\  / / | |__   | |     | |     | |  | || \  / || |__   
   \ \/  \/ /  |  __|  | |     | |     | |  | || |\/| ||  __|  
    \  /\  /   | |____ | |____ | |____ | |__| || |  | || |____ 
     \/  \/    |______||______| \_____| \____/ |_|  |_||______|

`


	// Register the "five" command.
	commandName     := "five"
	commandProducer := telsh.ProducerFunc(fiveProducer)

	shellHandler.Register(commandName, commandProducer)



	// Register the "dance" command.
	commandName      = "dance"
	commandProducer  = telsh.ProducerFunc(danceProducer)

	shellHandler.Register(commandName, commandProducer)



	shellHandler.Register("dance", telsh.ProducerFunc(danceProducer))

	addr := ":5555"
	if err := telnet.ListenAndServe(addr, shellHandler); nil != err {
		panic(err)
	}
}

TELNET servers made using the "github.com/reiver/go-telnet/telsh" sub-package will often be more useful as it makes it easier for you to create a shell interface.

More Information

There is a lot more information about documentation on all this here: http://godoc.org/github.com/reiver/go-telnet

(You should really read those.)

go-telnet's People

Contributors

error454 avatar reiver avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-telnet's Issues

sample script

Hello
Please provide example script for telnet client, which send some strings, then get answer and check it for some conditions?
Thank you very much!

Server response log

@reiver
Please give a tip, how can I see the response of the remote server that is accepting my commands.
I don't know how to debug it using your repo.

Thank you.

Client hangs for a minute at first.

My telnet client is connecting to a non-go-telnet server and uses the basic client code provided in the documentation example. Connecting to my server with a standard telnet client gets an instant reply, but for some reason, my go-telnet client hangs reading for exactly a minute, then is fully interactive. Is there some configuration I should be using or something extra I should be doing with the Conn to flush it?

TELNET Shell Server Example build error

.\main.go:8: imported and not used: "fmt"
.\main.go:19: undefined: telsh.Context
.\main.go:20: cannot use fiveHandler (type func(io.ReadCloser, io.WriteCloser, io.WriteCloser) error) as type telsh.HandlerFunc in argument to telsh.PromoteHandlerFunc
.\main.go:60: undefined: telsh.Context
.\main.go:62: cannot use danceHandler (type func(io.ReadCloser, io.WriteCloser, io.WriteCloser) error) as type telsh.HandlerFunc in argument to telsh.PromoteHandlerFunc
.\main.go:81: cannot convert fiveProducer (type func(, string, ...string) telsh.Handler) to type telsh.ProducerFunc
.\main.go:87: cannot convert danceProducer (type func(, string, ...string) telsh.Handler) to type telsh.ProducerFunc
.\main.go:91: cannot convert danceProducer (type func(, string, ...string) telsh.Handler) to type telsh.ProducerFunc

How to Read data unblock?

Now I use telnet.DialTo to get a conn.I use this conn to Read bytes using the function conn.Read().However,it is blocked.How can I solve this problem,thank you! Idon't know how many bytes i will receive.ButI want to receive all of them

How can the server detect conn is closed?

I send stream output to stdout in shellHandler. So when the conn is closed, I need to terminate the handler function. So How can the server detect conn is closed?

Thank you ~

Server - store list of established connections.

Hi! I'm trying to use your library in my project.

I'm working on Telnet Chat and I'm using ShellHandler for that.
The issue which I have is that Server doesn't provide access to new connections in any way.

I was thinking about copying your code for ListenAndServe, Serve and handle methods to my project as implementations of some supertype which will embed telnet.Server but it require a lot of code to be copied. What do you think will be the best choice to solve that?

How do you feel about changing handle method into exported?
Then I would have to implement only ListenAndServer and Serve methods in my own struct.

Another way is just to implement that functionality directly in go-telnet, are you OK with merging change like that?

A third way is to add current connection into a context which then is provided into Handler.
I have own handler which I'm using so that will also solve my issue. Also, it makes sense to add into context current conn, for example, if someone will do other things based on the source of the connection.
To be honest that 3rd option makes the most sense for me. Doesn't require a lot of changes and provides the biggest value added.

can support Cluster address?

        var handler telnet.Handler = telnet.EchoHandler
	err := telnet.ListenAndServe("192.168.1.10:5555,192.168.1.11:5556,192.168.1.12:5557", handler)
	if nil != err {
		//@TODO: Handle this error better.
		panic(err)
	}

A bit of help

Hello,

Thanks for making this project.

Can you help give me an example of linking a external applications standard out to this server.
I have a telnet server in CYGWIN and it is giving issue. I would like to hook up the existing application that to this server.

Thanks in advance.

telsh command with arguments

Is it possible to use telsh to implement a command with additional arguments? I could not find an example for this usecase. Is there one?

Log IPs that connect to the telnet server

What is the best way to log IPs that connect to the telnet server. I've experimented with various ways but have been unable to do it so far. Here's a simple example.

package main

import (
"github.com/reiver/go-telnet"
"log"
)

var RBTHandler telnet.Handler = internalRBTHandler{}

type internalRBTHandler struct{}

func (handler internalRBTHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
// How do I log the remote ip here?
log.Printf("%v\n", ctx)
}

func main() {
var handler telnet.Handler = RBTHandler
//var logger telnet.Logger

server := &telnet.Server{
	Addr:    ":2323",
	Handler: handler,
	//Logger:  logger,
}

err := server.ListenAndServe()
if nil != err {
	panic(err)
}

}

Not only connecting Telnet Server port, connecting other ports

I try to check Telnet server is running or not in my project. I am testing on Docker image. I used DialTo() function with passing address like 127.0.0.1:23. It seems perfect when I check as just below:

_, err := telnet.DialTo("127.0.0.1:23")
if err != nil {
    log.Fatalln("error while connecting Telnet server:", err)
}

fmt.Println("Telnet server is running...")

Program prints out Telnet server is running.... Then, I tried another port, but not Telnet server, Redis's port. I changed the address with 127.0.0.1:6378. And, it still works. I think this is not appropriate way to implement this client. I just want to talk with Telnet server and its ports, not other servers and their ports. Is there any way to solve that problem with this package? If there is not, I'd like to try add this feature with your helps.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.