Make it possible to set authtoken via ENV
This commit is contained in:
parent
19ef8d65d5
commit
030ebca2c1
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"isatty",
|
||||||
"netgiv",
|
"netgiv",
|
||||||
"pflag"
|
"pflag"
|
||||||
]
|
]
|
||||||
|
32
client.go
32
client.go
@ -9,6 +9,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
@ -22,22 +23,35 @@ type Client struct {
|
|||||||
list bool
|
list bool
|
||||||
send bool
|
send bool
|
||||||
receive bool
|
receive bool
|
||||||
|
authToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Connect() error {
|
func (c *Client) Connect() error {
|
||||||
address := fmt.Sprintf("%s:%d", c.address, c.port)
|
address := fmt.Sprintf("%s:%d", c.address, c.port)
|
||||||
|
|
||||||
serverAddress, _ := net.ResolveTCPAddr("tcp", address)
|
d := net.Dialer{Timeout: 5 * time.Second}
|
||||||
|
|
||||||
conn, err := net.DialTCP("tcp", nil, serverAddress)
|
conn, err := d.Dial("tcp", address)
|
||||||
|
|
||||||
|
// serverAddress, err := net.ResolveTCPAddr("tcp", address)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// conn, err := d.Dial("tcp", serverAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("problem connecting to server, is it running?\n")
|
return fmt.Errorf("problem connecting to server, is it running?: %v", err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
log.Printf("Connection on %s\n", address)
|
log.Printf("Connection on %s\n", address)
|
||||||
|
|
||||||
sharedKey := secure.Handshake(conn)
|
tcpConn, ok := conn.(*net.TCPConn)
|
||||||
|
if !ok {
|
||||||
|
log.Fatal("could not assert")
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedKey := secure.Handshake(tcpConn)
|
||||||
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}}
|
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}}
|
||||||
|
|
||||||
enc := gob.NewEncoder(&secureConnection)
|
enc := gob.NewEncoder(&secureConnection)
|
||||||
@ -46,7 +60,7 @@ func (c *Client) Connect() error {
|
|||||||
if c.list {
|
if c.list {
|
||||||
log.Printf("requesting file list")
|
log.Printf("requesting file list")
|
||||||
|
|
||||||
err := connectToServer(secure.OperationTypeList, enc, dec)
|
err := c.connectToServer(secure.OperationTypeList, enc, dec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not connect and auth: %v", err)
|
return fmt.Errorf("could not connect and auth: %v", err)
|
||||||
}
|
}
|
||||||
@ -69,7 +83,7 @@ func (c *Client) Connect() error {
|
|||||||
} else if c.receive {
|
} else if c.receive {
|
||||||
log.Printf("receiving a file")
|
log.Printf("receiving a file")
|
||||||
|
|
||||||
err := connectToServer(secure.OperationTypeReceive, enc, dec)
|
err := c.connectToServer(secure.OperationTypeReceive, enc, dec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not connect and auth: %v", err)
|
return fmt.Errorf("could not connect and auth: %v", err)
|
||||||
}
|
}
|
||||||
@ -111,7 +125,7 @@ func (c *Client) Connect() error {
|
|||||||
} else if c.send {
|
} else if c.send {
|
||||||
// send mode
|
// send mode
|
||||||
|
|
||||||
err := connectToServer(secure.OperationTypeSend, enc, dec)
|
err := c.connectToServer(secure.OperationTypeSend, enc, dec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not connect and auth: %v", err)
|
return fmt.Errorf("could not connect and auth: %v", err)
|
||||||
}
|
}
|
||||||
@ -167,14 +181,14 @@ func (c *Client) Connect() error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectToServer(op secure.OperationTypeEnum, enc *gob.Encoder, dec *gob.Decoder) error {
|
func (c *Client) connectToServer(op secure.OperationTypeEnum, enc *gob.Encoder, dec *gob.Decoder) error {
|
||||||
|
|
||||||
// list mode
|
// list mode
|
||||||
startPacket := secure.PacketStartRequest{
|
startPacket := secure.PacketStartRequest{
|
||||||
OperationType: op,
|
OperationType: op,
|
||||||
ClientName: "",
|
ClientName: "",
|
||||||
ProtocolVersion: "1.0",
|
ProtocolVersion: "1.0",
|
||||||
AuthToken: "dummy",
|
AuthToken: c.authToken,
|
||||||
}
|
}
|
||||||
err := enc.Encode(startPacket)
|
err := enc.Encode(startPacket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
93
main.go
93
main.go
@ -14,29 +14,95 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// log.SetFlags(log.Lshortfile)
|
// log.SetFlags(log.Lshortfile)
|
||||||
flag.Int("port", 4912, "Port to run server/client on.")
|
// flag.Int("port", 4912, "Port to run server/client on.")
|
||||||
addr := flag.String("a", "127.0.0.1", "address to connect to.")
|
// addr := flag.String("a", "127.0.0.1", "address to connect to.")
|
||||||
isServer := flag.Bool("s", false, "Set if running the server.")
|
isServer := flag.Bool("s", false, "Run netgiv in server mode")
|
||||||
|
|
||||||
|
// client mode flags
|
||||||
isList := flag.Bool("l", false, "Set if requesting a list")
|
isList := flag.Bool("l", false, "Set if requesting a list")
|
||||||
isSend := flag.Bool("c", false, "Set if sending a file (copy)")
|
isSend := flag.Bool("c", false, "sending stdin to netgiv server (copy)")
|
||||||
isReceive := flag.Bool("p", false, "Set if receiving a file (paste)")
|
isReceive := flag.Bool("p", false, "receive file from netgiv server to stdout (paste)")
|
||||||
|
flag.String("address", "", "IP address/hostname of the netgiv server")
|
||||||
|
|
||||||
|
helpConfig := flag.Bool("help-config", false, "Show help on netgiv configuration")
|
||||||
|
|
||||||
|
// common flags
|
||||||
|
flag.String("authtoken", "", "Authentication token")
|
||||||
|
flag.Int("port", 0, "Port")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
viper.AddConfigPath("$HOME/.netgiv/") // call multiple times to add many search paths
|
||||||
|
viper.SetConfigType("yaml")
|
||||||
|
|
||||||
viper.SetDefault("port", 4512)
|
viper.SetDefault("port", 4512)
|
||||||
|
|
||||||
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
|
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||||
|
// no config file maybe that's ok
|
||||||
|
panic(err)
|
||||||
|
} else {
|
||||||
|
// Config file was found but another error was produced
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
||||||
pflag.Parse()
|
pflag.Parse()
|
||||||
viper.BindPFlags(pflag.CommandLine)
|
viper.BindPFlags(pflag.CommandLine)
|
||||||
|
|
||||||
|
viper.SetEnvPrefix("NETGIV")
|
||||||
|
viper.BindEnv("authtoken")
|
||||||
|
|
||||||
|
// pull the various things into local variables
|
||||||
port := viper.GetInt("port") // retrieve value from viper
|
port := viper.GetInt("port") // retrieve value from viper
|
||||||
|
authtoken := viper.GetString("authtoken")
|
||||||
|
|
||||||
|
if authtoken == "" {
|
||||||
|
log.Fatal("authtoken must be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
address := viper.GetString("address")
|
||||||
|
if !*isServer && address == "" {
|
||||||
|
log.Fatal("an address must be provided on the command line, or configuration")
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.Usage = func() {
|
||||||
|
fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", os.Args[0])
|
||||||
|
flag.PrintDefaults()
|
||||||
|
fmt.Printf("\nIf stdin or stdout is a pipe, %s will automatically choose an appropriate\n", os.Args[0])
|
||||||
|
fmt.Printf("copy (-c) or paste (-p) mode\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if *helpConfig {
|
||||||
|
fmt.Print(
|
||||||
|
`netgiv can be configured by command line parameters (see --help) but it will
|
||||||
|
often be convenient to create a config file. The config file is in yaml format,
|
||||||
|
and should be stored in $HOME/.netgiv/config.yaml.
|
||||||
|
|
||||||
|
For both client and server, you will want to set the 'authtoken' key (they must
|
||||||
|
match). You'll want to also set the 'port' key if you would like to run netgiv
|
||||||
|
on a non-standard port (the default is 4512).
|
||||||
|
|
||||||
|
On the client you will probably want to set the 'address' key, so that your client
|
||||||
|
knows where to find the netgiv server. This key is ignored when running in server
|
||||||
|
mode.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
port: 5412
|
||||||
|
authtoken: verysecretvaluehere
|
||||||
|
address: 10.1.12.20
|
||||||
|
`)
|
||||||
|
os.Exit(1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if *isServer {
|
if *isServer {
|
||||||
|
s := Server{port: port, authToken: authtoken}
|
||||||
log.Printf("Server running on %d\n", port)
|
|
||||||
s := Server{port: port}
|
|
||||||
s.Run()
|
s.Run()
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if !*isList && !*isSend && !*isReceive {
|
if !*isList && !*isSend && !*isReceive {
|
||||||
// try to work out the intent based on whether or not stdin/stdout
|
// try to work out the intent based on whether or not stdin/stdout
|
||||||
// are ttys
|
// are ttys
|
||||||
@ -45,21 +111,18 @@ func main() {
|
|||||||
|
|
||||||
if stdinTTY && !stdoutTTY {
|
if stdinTTY && !stdoutTTY {
|
||||||
*isReceive = true
|
*isReceive = true
|
||||||
|
|
||||||
} else if !stdinTTY && stdoutTTY {
|
} else if !stdinTTY && stdoutTTY {
|
||||||
*isSend = true
|
*isSend = true
|
||||||
} else if !stdinTTY && !stdoutTTY {
|
} else if !stdinTTY && !stdoutTTY {
|
||||||
log.Fatal("I can't cope with both stdin and stdout being pipes")
|
log.Fatal("I can't cope with both stdin and stdout being pipes")
|
||||||
|
} else {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !*isList && !*isSend && !*isReceive {
|
c := Client{port: port, address: address, list: *isList, send: *isSend, receive: *isReceive, authToken: authtoken}
|
||||||
// could default to list?
|
|
||||||
*isList = true
|
|
||||||
}
|
|
||||||
|
|
||||||
c := Client{port: port, address: *addr, list: *isList, send: *isSend, receive: *isReceive}
|
|
||||||
err := c.Connect()
|
err := c.Connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
port int
|
port int
|
||||||
|
authToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
// An NGF is a Netgiv File
|
// An NGF is a Netgiv File
|
||||||
@ -71,11 +72,11 @@ func (s *Server) Run() {
|
|||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go handleConnection(conn)
|
go s.handleConnection(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleConnection(conn *net.TCPConn) {
|
func (s *Server) handleConnection(conn *net.TCPConn) {
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
conn.SetDeadline(time.Now().Add(time.Second * 5))
|
conn.SetDeadline(time.Now().Add(time.Second * 5))
|
||||||
@ -113,7 +114,7 @@ func handleConnection(conn *net.TCPConn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if start.AuthToken != "dummy2" {
|
if start.AuthToken != s.authToken {
|
||||||
log.Print("bad authtoken")
|
log.Print("bad authtoken")
|
||||||
startResponse.Response = secure.PacketStartResponseEnumBadAuthToken
|
startResponse.Response = secure.PacketStartResponseEnumBadAuthToken
|
||||||
enc.Encode(startResponse)
|
enc.Encode(startResponse)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user