package main import ( "./networkmanager" _ "./statik" "./wifinetworks" "encoding/json" "flag" "fmt" "github.com/gorilla/mux" "github.com/rakyll/statik/fs" "log" "net/http" "os/user" ) type config struct { WAN string CurrentSSID string ScanDelay int Listen string Password string Port int } var c config var WifiNetworks wifinetworks.Wifinetworks func init() { u, err := user.Current() if err != nil { log.Fatal("Couldn't get current user: ", err) } if u.Uid != "0" { log.Fatal("Must run as root. Try again with sudo.") } flag.StringVar(&c.WAN, "wan", "wlan0", "WAN Interface Name") flag.StringVar(&c.Listen, "listen", "0.0.0.0", "IP address to listen for interface") flag.IntVar(&c.Port, "port", 32000, "Listen port for interface") flag.IntVar(&c.ScanDelay, "scandelay", 5, "Delay between initiating scan and listing networks") flag.StringVar(&c.Password, "password", "password", "Require this password (and username admin) to access interface") flag.Parse() } func main() { statikFS, err := fs.New() if err != nil { log.Fatal("Couldn't init static FS!", err) } WifiNetworks.Load() // networkmanager.Reset() r := mux.NewRouter() r.Use(BasicAuth) r.HandleFunc("/rpc/scan", doScan) r.HandleFunc("/rpc/connect", doConnect) r.HandleFunc("/rpc/delete", doRemove) r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(statikFS))) r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/public/", 301) }) if c.Listen == "0.0.0.0" { fmt.Printf("The admin interface is available at http://[any IP address of this host]:%d/\n", c.Port) } else { fmt.Printf("The admin interface is available at http://%s:%d/\n", c.Listen, c.Port) } listen := fmt.Sprintf("%s:%d", c.Listen, c.Port) log.Fatal(http.ListenAndServe(listen, r)) } func SetKnown(visible []networkmanager.Networklist) []networkmanager.Networklist { for l, _ := range visible { if visible[l].Connected { c.CurrentSSID = visible[l].SSID } for j, _ := range WifiNetworks.Networks { if visible[l].SSID == WifiNetworks.Networks[j].SSID { t := visible[l] t.Known = true visible[l] = t } } } return visible } func doScan(w http.ResponseWriter, r *http.Request) { networks := SetKnown(networkmanager.Scan(c.WAN, c.ScanDelay)) j, err := json.Marshal(networks) if err != nil { log.Fatal("Json marshal: ", err) } w.Write(j) } func doRemove(w http.ResponseWriter, r *http.Request) { r.ParseForm() ssid := r.FormValue("ssid") if ssid != "" { WifiNetworks.RemoveSSID(ssid) WifiNetworks.Save() } } func doConnect(w http.ResponseWriter, r *http.Request) { r.ParseForm() var n wifinetworks.Wifinetwork n.SSID = r.FormValue("SSID") if n.SSID == "" { log.Println("No SSID") return } n.PSK = r.FormValue("Password") if n.PSK == "" { tmp, err := WifiNetworks.Find(n.SSID) if err != nil { n.PSK = "" } else { n.PSK = tmp.PSK } } if r.FormValue("Prioritize") == "true" { n.Priority = true } else { n.Priority = false } if networkmanager.ConnectToAccessPoint(c.WAN, n.SSID, n.PSK) { c.CurrentSSID = n.SSID if r.FormValue("Remember") == "true" { WifiNetworks.Add(n) } w.Write([]byte("Success")) } else { w.Write([]byte("Invalid Password")) } } func BasicAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { user, pass, ok := r.BasicAuth() if !ok || user != "admin" || pass != c.Password { w.Header().Set("WWW-Authenticate", `Basic realm="mydomain"`) http.Error(w, "Unauthorized", http.StatusUnauthorized) } else { next.ServeHTTP(w, r) } }) }