wifimanager/main.go

157 lines
3.6 KiB
Go

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)
}
})
}