Telnet client in go - go

I am trying to send 'hello world' to the telnet server from go client. In the documentation I have found example:
var caller telnet.Caller = telnet.StandardCaller
telnet.DialToAndCall("localhost:5555", caller)
What is the next step to send 'helloworld' now?

Example of programmatic connection using go-telnet
func SetTest() {
conn, _ := telnet.DialTo("localhost:5555")
conn.Write([]byte("hello world"))
conn.Write([]byte("\n"))
}

In the example below you can see that the CallTELNET uses stdin and stdout to allow the user of the program to communicate through telnet. You can send "hello world" by running the program and typing the desired text you wish to send followed by the enter key.
package main
import (
"bufio"
"fmt"
"log"
"os"
"github.com/reiver/go-oi"
"github.com/reiver/go-telnet"
)
type caller struct{}
func (c caller) CallTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
oi.LongWrite(w, scanner.Bytes())
oi.LongWrite(w, []byte("\n"))
}
}
func main() {
fmt.Printf("Dial to %s:%d\n", "localhost", 8080)
err := telnet.DialToAndCall(fmt.Sprintf("%s:%d", "localhost", 8080), caller{})
if err != nil {
log.Fatal(err)
}
}
Examples found here and here

The telnet library implements the 'Writer' type. The Writer Type has a Write method.

Related

generate otp code same like authy desktop

I try to generate totp code using this library same like authy.com desktop application. this is my current code :
package main
import (
"time"
"github.com/pquerna/otp/totp"
"bufio"
"fmt"
"os"
)
func promptForPasscode() string {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter Passcode: ")
text, _ := reader.ReadString('\n')
return text
}
func main() {
keySecret := "NK4KFDHUGRGMFKFEWRJ5EEOV6FT2IAKE"
coded, _ := totp.GenerateCode(keySecret, time.Now().UTC())
fmt.Println("code :", coded)
fmt.Println("Validating TOTP...")
// Now Validate that the user's successfully added the passcode.
passcode := promptForPasscode()
valid := totp.Validate(passcode, keySecret)
if valid {
println("Valid passcode!")
os.Exit(0)
} else {
println("Invalid passocde!")
os.Exit(1)
}
}
The code is working, my problem is, the code generated by golang application is not the same like authy desktop application, what is wrong ?

Keep a MQTT Go client running

I think it is a silly question, I need a MQTT Client to keep running after connection and subscription. I never encountered the problem because my MQTT clients are always coupled with an HTTP server, and when launching a HTTP server, the code don't stop running.
But in the present use case I only need a MQTT Client to subscribe to some topic and stay alive.
Here is what I do (the function just connect to a broker and subcribe to one topic.)
func main() {
godotenv.Load("./.env")
_initMqttConnection()
}
I need the client to stay connected and not stop just after the subscription is done.
How to perform that simple thing ?
Edit 1 : Complete Code
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/yosssi/gmq/mqtt"
"github.com/yosssi/gmq/mqtt/client"
"github.com/joho/godotenv"
"github.com/skratchdot/open-golang/open"
)
var cli *client.Client
func _initMqttConnection() {
cli = client.New(&client.Options{
ErrorHandler: func(err error) {
fmt.Println(err)
},
})
defer cli.Terminate()
log.Println("Connecting to " + os.Getenv("mqtt_host"))
err := cli.Connect(&client.ConnectOptions{
Network: "tcp",
Address: os.Getenv("mqtt_host"),
UserName: []byte(os.Getenv("mqtt_user")),
Password: []byte(os.Getenv("mqtt_password")),
ClientID: []byte("mqtt_video_launcher"),
})
if err != nil {
log.Println("Error 1")
panic(err)
}
log.Println("Connected to MQTT")
topic_to_sub := []byte("/" + os.Getenv("video_topic"))
err = cli.Subscribe(&client.SubscribeOptions{
SubReqs: []*client.SubReq{
&client.SubReq{
TopicFilter: topic_to_sub,
QoS: mqtt.QoS0,
Handler: func(topicName, message []byte) {
//do struff with message
fmt.Println(string(topicName), string(message))
},
},
},
})
if err != nil {
panic(err)
}
log.Println("Subscription OK : " + string(topic_to_sub[:len(topic_to_sub)]))
}
func main() {
godotenv.Load("./.env")
_initMqttConnection()
}
The temporary solution I use is adding :
http.ListenAndServe(":", nil)
at the end.
You have to make the program run infinitely or unless you want to explicitly end it (Cntrl c). One good solution that worked for me is to wait for a channel before exiting the main function and that channel can keep listening for an interrupt.
Eg:
func main() {
keepAlive := make(chan os.Signal)
signal.Notify(keepAlive, os.Interrupt, syscall.SIGTERM)
// All your code
<-keepAlive
}

ssh server in golang

I am trying the github.com/gliderlabs/ssh package in order to build a ssh server.
The example are working fine.
The code below listen and reply some text when I connect, then close the connection.
I would like to keep it open, listening to user input (lines) and echoing "you say : "... but I have no idea of what to do and it seems this is too simple to be explained somewhere.
Can someone give me an indication of what to do ?
package main
import (
"bufio"
"fmt"
"io"
"log"
"github.com/gliderlabs/ssh"
)
func main() {
ssh.Handle(func(s ssh.Session) {
io.WriteString(s, fmt.Sprintf("Hello %s\n", s.User()))
io.WriteString(s, fmt.Sprintf("Hello 2%s\n", s.User()))
io.WriteString(s, fmt.Sprintf("Hello 3%s\n", s.User()))
text,err:= bufio.NewReader(s).ReadString('\n')
if err != nil {
panic("GetLines: " + err.Error())
}
io.WriteString(s, fmt.Sprintf("ton texte %s\n", text))
})
log.Println("starting ssh server on port 2223...")
log.Fatal(ssh.ListenAndServe(":2223", nil))
}
If question is still actual, you shoud use for{} cycle inside handler, and always read input. BTW, it's more suitable to use "golang.org/x/crypto/ssh/terminal" package.
Here's little example:
func (s *Server) handler(sess ssh.Session) {
...
term := terminal.NewTerminal(sess, "> ")
for {
line, err := term.ReadLine()
if err != nil {
break
}
response := router(line)
log.Println(line)
if response != "" {
term.Write(append([]byte(response), '\n'))
}
}
log.Println("terminal closed")
}

How to get the URL in Go

I tried looking it up, but couldn't find an already answered question.
How do I get the host part of the URL in Go?
For eg.
if the user enters http://localhost:8080 in the address bar, I wanted to extract "localhost" from the URL.
If you are talking about extracting the host from a *http.Request you can do the following:
func ExampleHander(w http.ResponseWriter, r *http.Request) {
host := r.Host // This is your host (and will include port if specified)
}
If you just want to access the host part without the port part you can do the following:
func ExampleHandler(w http.ResponseWriter, r *http.Request) {
host, port, _ := net.SplitHostPort(r.Host)
}
For the last one to work you also have to import net
Go has wonderful documentation, I would also recommend taking a look at that: net/http
Go has built in library that can do it for you.
package main
import "fmt"
import "net"
import "net/url"
func main() {
s := "http://localhost:8080"
u, err := url.Parse(s)
if err != nil {
panic(err)
}
host, _, _ := net.SplitHostPort(u.Host)
fmt.Println(host)
}
https://golang.org/pkg/net/url/#

How to fork a process

I need help understanding how to demonize a process in Go.
package main
import (
"fmt"
"os"
)
func start() {
var procAttr os.ProcAttr
procAttr.Files = []*os.File{nil, nil, nil}
_, err := os.StartProcess("/Path/prog", nil, &procAttr)
if err != nil {
fmt.Printf("%v", err)
}
}
func main () {
start()
}
If you start this code on the command line the program returns control, but is still connected with cmd. Closing the cmd closes the program.
How can I decouple it from the cmd? Adding:
procAttr.Sys.HideWindow = true
Results in this error: "panic" to wrong memory pointer
I asked in 'golang-nuts', and found out that Go has a link option:
go tool 8l -o output.exe -Hwindowsgui input.8
Here is a fake daemon in go; it's simple to use: https://github.com/icattlecoder/godaemon
An example:
package main
import (
_ "github.com/icattlecoder/godaemon"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/index", func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte("hello, golang!\n"))
})
log.Fatalln(http.ListenAndServe(":7070", mux))
}

Resources