You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fw-daemon/fw-prompt/fw-prompt.go

511 lines
11 KiB

package main
import (
"github.com/gotk3/gotk3/gtk"
"github.com/gotk3/gotk3/glib"
"log"
"fmt"
"os"
"io/ioutil"
"encoding/json"
"os/user"
"strconv"
)
type fpPreferences struct {
Winheight uint
Winwidth uint
Wintop uint
Winleft uint
}
var userPrefs fpPreferences
var mainWin *gtk.Window
var Notebook *gtk.Notebook
var globalLS *gtk.ListStore
func promptInfo(msg string) {
dialog := gtk.MessageDialogNew(mainWin, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Displaying full log info:")
// dialog.SetDefaultGeometry(500, 200)
tv, err := gtk.TextViewNew()
if err != nil {
log.Fatal("Unable to create TextView:", err)
}
tvbuf, err := tv.GetBuffer()
if err != nil {
log.Fatal("Unable to get buffer:", err)
}
tvbuf.SetText(msg)
tv.SetEditable(false)
tv.SetWrapMode(gtk.WRAP_WORD)
scrollbox, err := gtk.ScrolledWindowNew(nil, nil)
if err != nil {
log.Fatal("Unable to create scrolled window:", err)
}
scrollbox.Add(tv)
scrollbox.SetSizeRequest(600, 100)
box, err := dialog.GetContentArea()
if err != nil {
log.Fatal("Unable to get content area of dialog:", err)
}
box.Add(scrollbox)
dialog.ShowAll()
dialog.Run()
dialog.Destroy()
//self.set_default_size(150, 100)
}
func promptChoice(msg string) int {
dialog := gtk.MessageDialogNew(mainWin, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_YES_NO, msg)
result := dialog.Run()
dialog.Destroy()
return result
}
func promptError(msg string) {
dialog := gtk.MessageDialogNew(mainWin, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, "Error: %s", msg)
dialog.Run()
dialog.Destroy()
}
func getConfigPath() string {
usr, err := user.Current()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n");
return ""
}
prefPath := usr.HomeDir + "/.fwprompt.json"
return prefPath
}
func savePreferences() bool {
usr, err := user.Current()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file:", err, "\n");
return false
}
prefPath := usr.HomeDir + "/.fwprompt.json"
jsonPrefs, err := json.Marshal(userPrefs)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not generate user preferences data:", err, "\n")
return false
}
err = ioutil.WriteFile(prefPath, jsonPrefs, 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not save user preferences data:", err, "\n")
return false
}
return true
}
func loadPreferences() bool {
usr, err := user.Current()
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not determine location of user preferences file: %v", err, "\n");
return false
}
prefPath := usr.HomeDir + "/.fwprompt.json"
fmt.Println("xxxxxxxxxxxxxxxxxxxxxx preferences path = ", prefPath)
jfile, err := ioutil.ReadFile(prefPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not read preference data from file: %v", err, "\n")
return false
}
err = json.Unmarshal(jfile, &userPrefs)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: could not load preferences data from file: %v", err, "\n")
return false
}
fmt.Println(userPrefs)
return true
}
func get_hbox() *gtk.Box {
hbox, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 0)
if err != nil {
log.Fatal("Unable to create horizontal box:", err)
}
return hbox
}
func get_label(text string) *gtk.Label {
label, err := gtk.LabelNew(text)
if err != nil {
log.Fatal("Unable to create label in GUI:", err)
return nil
}
return label
}
func createColumn(title string, id int) *gtk.TreeViewColumn {
cellRenderer, err := gtk.CellRendererTextNew()
if err != nil {
log.Fatal("Unable to create text cell renderer:", err)
}
column, err := gtk.TreeViewColumnNewWithAttribute(title, cellRenderer, "text", id)
if err != nil {
log.Fatal("Unable to create cell column:", err)
}
column.SetSortColumnID(id)
column.SetResizable(true)
return column
}
func createListStore(general bool) *gtk.ListStore {
colData := []glib.Type{glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING}
listStore, err := gtk.ListStoreNew(colData...)
if err != nil {
log.Fatal("Unable to create list store:", err)
}
return listStore
}
func addRequest(listStore *gtk.ListStore, path, proto string, pid int, ipaddr, hostname string, port, uid, gid int, origin, optstring string) {
if listStore == nil {
listStore = globalLS
}
iter := listStore.Append()
colVals := make([]interface{}, 11)
colVals[0] = 1
colVals[1] = path
colVals[2] = proto
colVals[3] = pid
colVals[4] = ipaddr
colVals[5] = hostname
colVals[6] = port
colVals[7] = uid
colVals[8] = gid
colVals[9] = origin
colVals[10] = optstring
colNums := make([]int, len(colVals))
for n := 0; n < len(colVals); n++ {
colNums[n] = n
}
err := listStore.Set(iter, colNums, colVals)
if err != nil {
log.Fatal("Unable to add row:", err)
}
}
func setup_settings() {
box, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
if err != nil {
log.Fatal("Unable to create settings box:", err)
}
scrollbox, err := gtk.ScrolledWindowNew(nil, nil)
if err != nil {
log.Fatal("Unable to create settings scrolled window:", err)
}
hLabel, err := gtk.LabelNew("Settings")
if err != nil {
log.Fatal("Unable to create notebook label:", err)
}
scrollbox.Add(box)
scrollbox.SetSizeRequest(600, 800)
tv, err := gtk.TreeViewNew()
if err != nil {
log.Fatal("Unable to create treeview:", err)
}
h := get_hbox()
l := get_label("Log to file:")
b, err := gtk.ButtonNewWithLabel("Save")
if err != nil {
log.Fatal("Unable to create button:", err)
}
h.PackStart(l, false, true, 10)
h.PackStart(b, false, true, 10)
h.SetMarginTop(10)
box.Add(h)
h = get_hbox()
h.SetMarginTop(0)
h.SetMarginBottom(20)
box.Add(h)
box.Add(tv)
b.Connect("clicked", func() {
fmt.Println("CLICKED")
if err != nil {
promptError("Unexpected error saving log file info: "+err.Error())
return
}
})
Notebook.AppendPage(scrollbox, hLabel)
}
func main() {
_, err := newDbusServer();
if err != nil {
log.Fatal("Error:", err)
return
}
loadPreferences()
gtk.Init(nil)
// Create a new toplevel window, set its title, and connect it to the "destroy" signal to exit the GTK main loop when it is destroyed.
mainWin, err = gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
if err != nil {
log.Fatal("Unable to create window:", err)
}
mainWin.SetTitle("SGOS fw-daemon Prompter")
mainWin.Connect("destroy", func() {
fmt.Println("Shutting down...")
savePreferences()
gtk.MainQuit()
})
mainWin.Connect("configure-event", func() {
w, h := mainWin.GetSize()
userPrefs.Winwidth, userPrefs.Winheight = uint(w), uint(h)
l, t := mainWin.GetPosition()
userPrefs.Winleft, userPrefs.Wintop = uint(l), uint(t)
})
mainWin.SetPosition(gtk.WIN_POS_CENTER)
Notebook, err = gtk.NotebookNew()
if err != nil {
log.Fatal("Unable to create new notebook:", err)
}
loglevel := "Pending Approval"
nbLabel, err := gtk.LabelNew(loglevel)
if err != nil {
log.Fatal("Unable to create notebook label:", err)
}
box, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
if err != nil {
log.Fatal("Unable to create box:", err)
}
scrollbox, err := gtk.ScrolledWindowNew(nil, nil)
if err != nil {
log.Fatal("Unable to create scrolled window:", err)
}
scrollbox.Add(box)
tv, err := gtk.TreeViewNew()
if err != nil {
log.Fatal("Unable to create treeview:", err)
}
tv.SetSizeRequest(300, 300)
tv.SetHeadersClickable(true)
ab, err := gtk.ButtonNewWithLabel("Approve")
if err != nil {
log.Fatal("Unable to create button:", err)
}
db, err := gtk.ButtonNewWithLabel("Deny")
if err != nil {
log.Fatal("Unable to create button:", err)
}
ib, err := gtk.ButtonNewWithLabel("Ignore")
if err != nil {
log.Fatal("Unable to create button:", err)
}
bb := get_hbox()
bb.PackStart(ab, false, false, 5)
bb.PackStart(db, false, false, 5)
bb.PackStart(ib, false, false, 5)
// box.Add(tv)
box.PackStart(bb, false, false, 5)
box.PackStart(tv, false, true, 5)
tv.AppendColumn(createColumn("#", 0))
tv.AppendColumn(createColumn("Path", 1))
tv.AppendColumn(createColumn("Protocol", 2))
tv.AppendColumn(createColumn("PID", 3))
tv.AppendColumn(createColumn("IP Address", 4))
tv.AppendColumn(createColumn("Hostname", 5))
tv.AppendColumn(createColumn("Port", 6))
tv.AppendColumn(createColumn("UID", 7))
tv.AppendColumn(createColumn("GID", 8))
tv.AppendColumn(createColumn("Origin", 9))
tv.AppendColumn(createColumn("Details", 10))
listStore := createListStore(true)
globalLS = listStore
tv.SetModel(listStore)
ab.Connect("clicked", func() {
promptError("Approving firewall request.")
/* choice := promptChoice("hmm?")
if choice != int(gtk.RESPONSE_YES) {
return
} */
})
db.Connect("clicked", func() {
promptError("Denying firewall request.")
})
db.Connect("clicked", func() {
promptError("Ignoring firewall request.")
})
tv.Connect("row-activated", func() {
fmt.Println("DOUBLE CLICK")
sel, err := tv.GetSelection()
if err != nil {
promptError("Unexpected error retrieving selection: "+err.Error())
return
}
rows := sel.GetSelectedRows(listStore)
// func (v *TreeSelection) GetSelected() (model ITreeModel, iter *TreeIter, ok bool) ???
fmt.Println("RETURNED ROWS: ", rows.Length())
if rows.Length() > 0 {
rdata := rows.NthData(0)
lIndex, err := strconv.Atoi(rdata.(*gtk.TreePath).String())
if err != nil {
promptError("Unexpected error reading selection data: "+err.Error())
return
}
path, err := gtk.TreePathNewFromString(fmt.Sprintf("%d", lIndex))
if err != nil {
promptError("Unexpected error reading data from selection: "+err.Error())
return
}
iter, err := listStore.GetIter(path)
if err != nil {
promptError("Unexpected error looking up log entry: "+err.Error())
return
}
val, err := listStore.GetValue(iter, 6)
if err != nil {
promptError("Unexpected error getting data from log entry: "+err.Error())
return
}
sval, err := val.GetString()
if err != nil {
promptError("Unexpected error reading data from log entry: "+err.Error())
return
}
fmt.Println("HEH: ", sval)
promptInfo(sval)
}
})
scrollbox.SetSizeRequest(600, 800)
Notebook.AppendPage(scrollbox, nbLabel)
setup_settings()
mainWin.Add(Notebook)
if userPrefs.Winheight > 0 && userPrefs.Winwidth > 0 {
fmt.Printf("height was %d, width was %d\n", userPrefs.Winheight, userPrefs.Winwidth)
mainWin.Resize(int(userPrefs.Winwidth), int(userPrefs.Winheight))
} else {
mainWin.SetDefaultSize(800, 600)
}
if userPrefs.Wintop > 0 && userPrefs.Winleft > 0 {
mainWin.Move(int(userPrefs.Winleft), int(userPrefs.Wintop))
}
// addRequest(listStore, "/bin/bla", "proto", 666, "loglevel", "provider", 23, 100, 1000)
mainWin.ShowAll()
mainWin.SetKeepAbove(true)
gtk.Main()
}