diff --git a/src/cmd/add_server.go b/src/cmd/add_server.go index dca24cc..e9919f9 100644 --- a/src/cmd/add_server.go +++ b/src/cmd/add_server.go @@ -25,6 +25,7 @@ type addServerCmdConfig struct { configFileServer string writeToClipboard bool port int + nickname string } var addServerCmdArgs = addServerCmdConfig{ @@ -35,6 +36,7 @@ var addServerCmdArgs = addServerCmdConfig{ configFileServer: ConfigServer, writeToClipboard: false, port: USE_ENDPOINT_PORT, + nickname: "", } // addServerCmd represents the server command. @@ -53,6 +55,7 @@ func init() { addServerCmd.Flags().StringSliceVarP(&addServerCmdArgs.allowedIPs, "routes", "r", addServerCmdArgs.allowedIPs, "[REQUIRED] CIDR IP ranges that will be routed through wiretap") addServerCmd.Flags().StringVarP(&addServerCmdArgs.serverAddress, "server-address", "s", addServerCmdArgs.serverAddress, "API address of server that new server will connect to, connects to client by default") addServerCmd.Flags().IntVarP(&addServerCmdArgs.port, "port", "p", addServerCmdArgs.port, "listener port to start on new server for wireguard relay. If --outbound, default is the port specified in --endpoint; otherwise default is 51820") + addServerCmd.Flags().StringVarP(&addServerCmdArgs.nickname, "nickname", "n", addServerCmdArgs.nickname, "Server nickname to display in 'status' command") addServerCmd.Flags().BoolVarP(&addServerCmdArgs.writeToClipboard, "clipboard", "c", addServerCmdArgs.writeToClipboard, "copy configuration args to clipboard") addServerCmd.Flags().StringVarP(&addServerCmdArgs.configFileRelay, "relay-input", "", addServerCmdArgs.configFileRelay, "filename of input relay config file") @@ -167,6 +170,7 @@ func (c addServerCmdConfig) Run() { PublicKey: serverConfigE2EE.GetPublicKey(), AllowedIPs: c.allowedIPs, Endpoint: net.JoinHostPort(newRelayPrefixes[0].Addr().Next().Next().String(), fmt.Sprint(E2EEPort)), + Nickname: c.nickname, }) check("failed to generate new e2ee peer", err) clientConfigE2EE.AddPeer(serverE2EEPeer) @@ -260,6 +264,7 @@ func (c addServerCmdConfig) Run() { PublicKey: serverConfigE2EE.GetPublicKey(), AllowedIPs: c.allowedIPs, Endpoint: net.JoinHostPort(addresses.NextServerRelayAddr4.String(), fmt.Sprint(E2EEPort)), + Nickname: c.nickname, }) check("failed to parse server as peer", err) clientConfigE2EE.AddPeer(serverPeerConfigE2EE) diff --git a/src/cmd/configure.go b/src/cmd/configure.go index 90d9cb2..78d6b3d 100644 --- a/src/cmd/configure.go +++ b/src/cmd/configure.go @@ -18,6 +18,7 @@ type configureCmdConfig struct { endpoint string outbound bool port int + nickname string configFileRelay string configFileE2EE string configFileServer string @@ -43,6 +44,7 @@ var configureCmdArgs = configureCmdConfig{ endpoint: Endpoint, outbound: false, port: USE_ENDPOINT_PORT, + nickname: "", configFileRelay: ConfigRelay, configFileE2EE: ConfigE2EE, configFileServer: ConfigServer, @@ -79,6 +81,8 @@ func init() { configureCmd.Flags().StringVarP(&configureCmdArgs.endpoint, "endpoint", "e", configureCmdArgs.endpoint, "[REQUIRED] IP:PORT (or [IP]:PORT for IPv6) of wireguard listener that server will connect to (example \"1.2.3.4:51820\")") configureCmd.Flags().BoolVar(&configureCmdArgs.outbound, "outbound", configureCmdArgs.outbound, "client will initiate handshake to server; --endpoint now specifies server's listening socket instead of client's, and --port assigns the server's listening port instead of client's") configureCmd.Flags().IntVarP(&configureCmdArgs.port, "port", "p", configureCmdArgs.port, "listener port for wireguard relay. Default is to copy the --endpoint port. If --outbound, sets port for the server; else for the client.") + configureCmd.Flags().StringVarP(&configureCmdArgs.nickname, "nickname", "n", configureCmdArgs.nickname, "Server nickname to display in 'status' command") + configureCmd.Flags().StringVarP(&configureCmdArgs.configFileRelay, "relay-output", "", configureCmdArgs.configFileRelay, "wireguard relay config output filename") configureCmd.Flags().StringVarP(&configureCmdArgs.configFileE2EE, "e2ee-output", "", configureCmdArgs.configFileE2EE, "wireguard E2EE config output filename") configureCmd.Flags().StringVarP(&configureCmdArgs.configFileServer, "server-output", "s", configureCmdArgs.configFileServer, "wiretap server config output filename") @@ -193,7 +197,6 @@ func (c configureCmdConfig) Run() { err = serverConfigRelay.SetPort(serverPort) check("failed to set port", err) - clientConfigRelayArgs := peer.ConfigArgs{ ListenPort: clientPort, @@ -239,6 +242,7 @@ func (c configureCmdConfig) Run() { PublicKey: serverConfigE2EE.GetPublicKey(), AllowedIPs: c.allowedIPs, Endpoint: net.JoinHostPort(relaySubnet4.Addr().Next().Next().String(), fmt.Sprint(E2EEPort)), + Nickname: c.nickname, }, }, Addresses: clientE2EEAddrs, diff --git a/src/cmd/status.go b/src/cmd/status.go index b173317..ad80a6f 100644 --- a/src/cmd/status.go +++ b/src/cmd/status.go @@ -134,11 +134,12 @@ func (c statusCmdConfig) Run() { } } t.AddChild(tree.NodeString(fmt.Sprintf(`server - relay: %v... - e2ee: %v... + nickname: %v + relay: %v... + e2ee: %v... - api: %v - routes: %v `, c.relayConfig.GetPublicKey()[:8], c.e2eeConfig.GetPublicKey()[:8], api, strings.Join(ips, ",")))) + api: %v + routes: %v `, c.peerConfig.GetNickname(), c.relayConfig.GetPublicKey()[:8], c.e2eeConfig.GetPublicKey()[:8], api, strings.Join(ips, ",")))) child, err := t.Child(0) check("could not build tree", err) treeTraversal(node.children[i], child) diff --git a/src/peer/config.go b/src/peer/config.go index 15fcd57..cf83d72 100644 --- a/src/peer/config.go +++ b/src/peer/config.go @@ -44,6 +44,8 @@ const ( PowerShell ) +const CUSTOM_PREFIX = "#@" + func GetConfig(args ConfigArgs) (Config, error) { c, err := NewConfig() if err != nil { @@ -158,9 +160,16 @@ func ParseConfig(filename string) (c Config, err error) { case "[peer]": newPeer := PeerConfig{} for _, line := range lines[1:] { - if len(line) == 0 || line[0] == '#' { + if len(line) == 0 { continue } + + if strings.HasPrefix(line, CUSTOM_PREFIX) { //special wiretap-specific values + line = line[len(CUSTOM_PREFIX):] + } else if line[0] == '#' { + continue + } + key, value, err := parseConfigLine(line) if err != nil { return c, err @@ -178,6 +187,8 @@ func ParseConfig(filename string) (c Config, err error) { return c, e } err = newPeer.SetPersistentKeepaliveInterval(keepalive) + case "nickname": + err = newPeer.SetNickname(value) } if err != nil { return c, err @@ -195,12 +206,12 @@ func ParseConfig(filename string) (c Config, err error) { } func parseConfigLine(line string) (string, string, error) { - split := strings.Fields(line) - if len(split) != 3 { - return "", "", fmt.Errorf("failed to parse line: incorrect number of fields: [%s]", line) + key, val, found := strings.Cut(line, "=") + if !found { + return "", "", fmt.Errorf("failed to parse line: no = found: [%s]", line) } - return strings.ToLower(strings.TrimSpace(split[0])), strings.TrimSpace(split[2]), nil + return strings.ToLower(strings.TrimSpace(key)), strings.TrimSpace(val), nil } func (c *Config) MarshalJSON() ([]byte, error) { @@ -403,7 +414,7 @@ func (c *Config) AsShareableFile() string { s.WriteString("[Peer]\n") s.WriteString(fmt.Sprintf("PublicKey = %s\n", c.config.PrivateKey.PublicKey().String())) s.WriteString("AllowedIPs = 0.0.0.0/32\n") - + return s.String() } diff --git a/src/peer/peer_config.go b/src/peer/peer_config.go index e8d4010..7cc4064 100644 --- a/src/peer/peer_config.go +++ b/src/peer/peer_config.go @@ -15,11 +15,13 @@ import ( type PeerConfig struct { config wgtypes.PeerConfig privateKey *wgtypes.Key + nickname string } type peerConfigJSON struct { Config wgtypes.PeerConfig PrivateKey *wgtypes.Key + Nickname string } type PeerConfigArgs struct { @@ -32,6 +34,7 @@ type PeerConfigArgs struct { ReplaceAllowedIPs bool AllowedIPs []string PrivateKey string + Nickname string } func GetPeerConfig(args PeerConfigArgs) (PeerConfig, error) { @@ -84,6 +87,13 @@ func GetPeerConfig(args PeerConfigArgs) (PeerConfig, error) { return PeerConfig{}, err } } + + if args.Nickname != "" { + err = c.SetNickname(args.Nickname) + if err != nil { + return PeerConfig{}, err + } + } return c, nil } @@ -99,6 +109,7 @@ func NewPeerConfig() (PeerConfig, error) { PublicKey: privateKey.PublicKey(), }, privateKey: &privateKey, + nickname: "", }, nil } @@ -106,6 +117,7 @@ func (p *PeerConfig) MarshalJSON() ([]byte, error) { return json.Marshal(peerConfigJSON{ p.config, p.privateKey, + p.nickname, }) } @@ -119,6 +131,7 @@ func (p *PeerConfig) UnmarshalJSON(b []byte) error { p.config = tmp.Config p.privateKey = tmp.PrivateKey + p.nickname = tmp.Nickname return nil } @@ -231,11 +244,27 @@ func (p *PeerConfig) SetPrivateKey(privateKey string) error { return nil } +func (p *PeerConfig) GetNickname() string { + return p.nickname +} + +func (p *PeerConfig) SetNickname(nickname string) error { + if nickname != "" { + p.nickname = nickname + } + return nil +} + func (p *PeerConfig) AsFile() string { var s strings.Builder - s.WriteString("[Peer]\n") + + if p.nickname != "" { + s.WriteString(fmt.Sprintf("%s Nickname = %s\n", CUSTOM_PREFIX, p.nickname)) + } + s.WriteString(fmt.Sprintf("PublicKey = %s\n", p.config.PublicKey.String())) + ips := []string{} for _, a := range p.config.AllowedIPs { ips = append(ips, a.String())