/* * Copyright (c) 2016, Psiphon Inc. * All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ package main import ( "flag" "fmt" "io/ioutil" "os" "strconv" "strings" "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon" "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/server" ) func main() { var generateTrafficRulesFilename string var generateServerEntryFilename string var generateLogFilename string var generateServerIPaddress string var generateServerNetworkInterface string var generateWebServerPort int var generateProtocolPorts stringListFlag var configFilename string flag.StringVar( &generateTrafficRulesFilename, "trafficRules", server.SERVER_TRAFFIC_RULES_FILENAME, "generate with this traffic rules `filename`") flag.StringVar( &generateServerEntryFilename, "serverEntry", server.SERVER_ENTRY_FILENAME, "generate with this server entry `filename`") flag.StringVar( &generateLogFilename, "logFilename", "", "set application log file name and path; blank for stderr") flag.StringVar( &generateServerIPaddress, "ipaddress", server.DEFAULT_SERVER_IP_ADDRESS, "generate with this server `IP address`") flag.StringVar( &generateServerNetworkInterface, "interface", "", "generate with server IP address from this `network-interface`") flag.IntVar( &generateWebServerPort, "web", 0, "generate with web server `port`; 0 for no web server") flag.Var( &generateProtocolPorts, "protocol", "generate with `protocol:port`; flag may be repeated to enable multiple protocols") flag.StringVar( &configFilename, "config", server.SERVER_CONFIG_FILENAME, "run or generate with this config `filename`") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage:\n\n"+ "%s generate generates configuration files\n"+ "%s run runs configured services\n\n", os.Args[0], os.Args[0]) flag.PrintDefaults() } flag.Parse() args := flag.Args() if len(args) < 1 { flag.Usage() os.Exit(1) } else if args[0] == "generate" { serverIPaddress := generateServerIPaddress if generateServerNetworkInterface != "" { var err error serverIPaddress, err = psiphon.GetInterfaceIPAddress(generateServerNetworkInterface) if err != nil { fmt.Printf("generate failed: %s\n", err) os.Exit(1) } } tunnelProtocolPorts := make(map[string]int) for _, protocolPort := range generateProtocolPorts { parts := strings.Split(protocolPort, ":") if len(parts) == 2 { port, err := strconv.Atoi(parts[1]) if err != nil { fmt.Printf("generate failed: %s\n", err) os.Exit(1) } tunnelProtocolPorts[parts[0]] = port } } configJSON, trafficRulesJSON, encodedServerEntry, err := server.GenerateConfig( &server.GenerateConfigParams{ LogFilename: generateLogFilename, ServerIPAddress: serverIPaddress, EnableSSHAPIRequests: true, WebServerPort: generateWebServerPort, TunnelProtocolPorts: tunnelProtocolPorts, TrafficRulesFilename: generateTrafficRulesFilename, }) if err != nil { fmt.Printf("generate failed: %s\n", err) os.Exit(1) } err = ioutil.WriteFile(configFilename, configJSON, 0600) if err != nil { fmt.Printf("error writing configuration file: %s\n", err) os.Exit(1) } err = ioutil.WriteFile(generateTrafficRulesFilename, trafficRulesJSON, 0600) if err != nil { fmt.Printf("error writing traffic rule configuration file: %s\n", err) os.Exit(1) } err = ioutil.WriteFile(generateServerEntryFilename, encodedServerEntry, 0600) if err != nil { fmt.Printf("error writing server entry file: %s\n", err) os.Exit(1) } } else if args[0] == "run" { configJSON, err := ioutil.ReadFile(configFilename) if err != nil { fmt.Printf("error loading configuration file: %s\n", err) os.Exit(1) } err = server.RunServices(configJSON) if err != nil { fmt.Printf("run failed: %s\n", err) os.Exit(1) } } } type stringListFlag []string func (list *stringListFlag) String() string { return strings.Join(*list, ", ") } func (list *stringListFlag) Set(flagValue string) error { *list = append(*list, flagValue) return nil }