mirror of https://github.com/subgraph/fw-daemon
shw_dev
parent
c3635093fa
commit
e3833190bf
@ -0,0 +1,3 @@
|
||||
To get this to work, first edit /usr/share/gnome-shell/modes/subgraph.json
|
||||
Remove the entry for "firewall@subgraph.com", hit CTRL+F2 and then issue the reload "r" command.
|
||||
Reset these changes to revert back to the old gnome-shell prompt.
|
@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/godbus/dbus"
|
||||
"log"
|
||||
// "github.com/gotk3/gotk3/glib"
|
||||
)
|
||||
|
||||
|
||||
type dbusServer struct {
|
||||
conn *dbus.Conn
|
||||
run bool
|
||||
}
|
||||
|
||||
type promptData struct {
|
||||
Application string
|
||||
Icon string
|
||||
Path string
|
||||
Address string
|
||||
Port int
|
||||
IP string
|
||||
Origin string
|
||||
Proto string
|
||||
UID int
|
||||
GID int
|
||||
Username string
|
||||
Groupname string
|
||||
Pid int
|
||||
OptString string
|
||||
Expanded bool
|
||||
Expert bool
|
||||
Action int
|
||||
}
|
||||
|
||||
|
||||
func newDbusServer() (*dbusServer, error) {
|
||||
conn, err := dbus.SystemBus()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reply, err := conn.RequestName("com.subgraph.FirewallPrompt", dbus.NameFlagDoNotQueue)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if reply != dbus.RequestNameReplyPrimaryOwner {
|
||||
return nil, errors.New("Bus name is already owned")
|
||||
}
|
||||
|
||||
ds := &dbusServer{}
|
||||
|
||||
if err := conn.Export(ds, "/com/subgraph/FirewallPrompt", "com.subgraph.FirewallPrompt"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds.conn = conn
|
||||
ds.run = true
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
func (ds *dbusServer) RequestPrompt(application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32,
|
||||
optstring string, expanded, expert bool, action int32) (int32, string, *dbus.Error) {
|
||||
log.Printf("REALLY GOT IT!")
|
||||
log.Printf("app = %s, icon = %s, path = %s, address = %s, action = %v\n", application, icon, path, address, action)
|
||||
addRequest(nil, path, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, optstring)
|
||||
// glib.IdleAdd(func, data)
|
||||
return 0, "bla bla bla", nil
|
||||
}
|
@ -0,0 +1,510 @@
|
||||
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()
|
||||
}
|
Loading…
Reference in new issue