@ -48,6 +48,7 @@ type ruleColumns struct {
Uname string
Uname string
Gname string
Gname string
Origin string
Origin string
Timestamp string
IsSocks bool
IsSocks bool
ForceTLS bool
ForceTLS bool
Scope int
Scope int
@ -70,6 +71,7 @@ var btnApprove, btnDeny, btnIgnore *gtk.Button
var chkTLS , chkUser , chkGroup * gtk . CheckButton
var chkTLS , chkUser , chkGroup * gtk . CheckButton
func dumpDecisions ( ) {
func dumpDecisions ( ) {
return
fmt . Println ( "XXX Total of decisions pending: " , len ( decisionWaiters ) )
fmt . Println ( "XXX Total of decisions pending: " , len ( decisionWaiters ) )
for i := 0 ; i < len ( decisionWaiters ) ; i ++ {
for i := 0 ; i < len ( decisionWaiters ) ; i ++ {
fmt . Printf ( "XXX %d ready = %v, rule = %v\n" , i + 1 , decisionWaiters [ i ] . Ready , decisionWaiters [ i ] . Rule )
fmt . Printf ( "XXX %d ready = %v, rule = %v\n" , i + 1 , decisionWaiters [ i ] . Ready , decisionWaiters [ i ] . Rule )
@ -77,6 +79,7 @@ func dumpDecisions() {
}
}
func addDecision ( ) * decisionWaiter {
func addDecision ( ) * decisionWaiter {
return nil
decision := decisionWaiter { Lock : & sync . Mutex { } , Ready : false , Scope : int ( sgfw . APPLY_ONCE ) , Rule : "" }
decision := decisionWaiter { Lock : & sync . Mutex { } , Ready : false , Scope : int ( sgfw . APPLY_ONCE ) , Rule : "" }
decision . Cond = sync . NewCond ( decision . Lock )
decision . Cond = sync . NewCond ( decision . Lock )
decisionWaiters = append ( decisionWaiters , & decision )
decisionWaiters = append ( decisionWaiters , & decision )
@ -315,7 +318,7 @@ func createColumn(title string, id int) *gtk.TreeViewColumn {
func createListStore ( general bool ) * gtk . ListStore {
func createListStore ( general bool ) * gtk . ListStore {
colData := [ ] glib . Type { glib . TYPE_INT , glib . TYPE_STRING , glib . TYPE_STRING , glib . TYPE_STRING , glib . TYPE_STRING , glib . TYPE_INT , glib . TYPE_STRING ,
colData := [ ] glib . Type { glib . TYPE_INT , glib . TYPE_STRING , glib . TYPE_STRING , 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_ INT, glib . TYPE_STRING , glib . TYPE_INT }
glib . TYPE_STRING , glib . TYPE_INT , glib . TYPE_INT , glib . TYPE_INT , glib . TYPE_STRING , glib . TYPE_ STRING, glib . TYPE_ INT, glib . TYPE_STRING , glib . TYPE_INT }
listStore , err := gtk . ListStoreNew ( colData ... )
listStore , err := gtk . ListStoreNew ( colData ... )
if err != nil {
if err != nil {
@ -331,7 +334,7 @@ func removeRequest(listStore *gtk.ListStore, guid string) {
defer globalPromptLock . Unlock ( )
defer globalPromptLock . Unlock ( )
/* XXX: This is horrible. Figure out how to do this properly. */
/* XXX: This is horrible. Figure out how to do this properly. */
for ridx := 0 ; ridx < 2000 ; ridx ++ {
for ridx := 0 ; ridx < globalLS . IterNChildren ( nil ) ; ridx ++ {
rule , _ , err := getRuleByIdx ( ridx )
rule , _ , err := getRuleByIdx ( ridx )
if err != nil {
if err != nil {
@ -357,7 +360,7 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
globalPromptLock . Lock ( )
globalPromptLock . Lock ( )
defer globalPromptLock . Unlock ( )
defer globalPromptLock . Unlock ( )
for ridx := 0 ; ridx < 2000 ; ridx ++ {
for ridx := 0 ; ridx < globalLS . IterNChildren ( nil ) ; ridx ++ {
/* XXX: This is horrible. Figure out how to do this properly. */
/* XXX: This is horrible. Figure out how to do this properly. */
rule , iter , err := getRuleByIdx ( ridx )
rule , iter , err := getRuleByIdx ( ridx )
@ -385,98 +388,14 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
}
}
func addRequestAsync ( listStore * gtk . ListStore , guid , path , icon , proto string , pid int , ipaddr , hostname string , port , uid , gid int ,
func addRequestAsync ( listStore * gtk . ListStore , guid , path , icon , proto string , pid int , ipaddr , hostname string , port , uid , gid int ,
origin string , is_socks bool , optstring string , sandbox string , action int ) bool {
origin , timestamp string , is_socks bool , optstring string , sandbox string , action int ) bool {
if listStore == nil {
addRequest ( listStore , guid , path , icon , proto , pid , ipaddr , hostname , port , uid , gid , origin , timestamp , is_socks ,
listStore = globalLS
optstring , sandbox , action )
waitTimes := [ ] int { 1 , 2 , 5 , 10 }
if listStore == nil {
log . Println ( "SGFW prompter was not ready to receive firewall request... waiting" )
for _ , wtime := range waitTimes {
time . Sleep ( time . Duration ( wtime ) * time . Second )
listStore = globalLS
if listStore != nil {
break
}
log . Println ( "SGFW prompter is still waiting..." )
}
}
}
if listStore == nil {
log . Fatal ( "SGFW prompter GUI failed to load for unknown reasons" )
}
if addRequestInc ( listStore , guid , path , icon , proto , pid , ipaddr , hostname , port , uid , gid , origin , is_socks , optstring , sandbox , action ) {
fmt . Println ( "REQUEST WAS DUPLICATE" )
return false
} else {
fmt . Println ( "NOT DUPLICATE" )
}
globalPromptLock . Lock ( )
iter := listStore . Append ( )
if is_socks {
if ( optstring != "" ) && ( strings . Index ( optstring , "SOCKS" ) == - 1 ) {
optstring = "SOCKS5 / " + optstring
} else if optstring == "" {
optstring = "SOCKS5"
}
}
colVals := make ( [ ] interface { } , 15 )
colVals [ 0 ] = 1
colVals [ 1 ] = guid
colVals [ 2 ] = path
colVals [ 3 ] = icon
colVals [ 4 ] = proto
colVals [ 5 ] = pid
if ipaddr == "" {
colVals [ 6 ] = "---"
} else {
colVals [ 6 ] = ipaddr
}
colVals [ 7 ] = hostname
colVals [ 8 ] = port
colVals [ 9 ] = uid
colVals [ 10 ] = gid
colVals [ 11 ] = origin
colVals [ 12 ] = 0
if is_socks {
colVals [ 12 ] = 1
}
colVals [ 13 ] = optstring
colVals [ 14 ] = action
colNums := make ( [ ] int , len ( colVals ) )
for n := 0 ; n < len ( colVals ) ; n ++ {
colNums [ n ] = n
}
err := listStore . Set ( iter , colNums , colVals )
globalPromptLock . Unlock ( )
if err != nil {
log . Fatal ( "Unable to add row:" , err )
}
toggleHover ( )
return true
return true
}
}
func addRequest ( listStore * gtk . ListStore , guid , path , icon , proto string , pid int , ipaddr , hostname string , port , uid , gid int ,
func addRequest ( listStore * gtk . ListStore , guid , path , icon , proto string , pid int , ipaddr , hostname string , port , uid , gid int ,
origin string , is_socks bool , optstring string , sandbox string , action int ) * decisionWaiter {
origin , timestamp string , is_socks bool , optstring string , sandbox string , action int ) * decisionWaiter {
if listStore == nil {
if listStore == nil {
listStore = globalLS
listStore = globalLS
waitTimes := [ ] int { 1 , 2 , 5 , 10 }
waitTimes := [ ] int { 1 , 2 , 5 , 10 }
@ -506,7 +425,9 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
if addRequestInc ( listStore , guid , path , icon , proto , pid , ipaddr , hostname , port , uid , gid , origin , is_socks , optstring , sandbox , action ) {
if addRequestInc ( listStore , guid , path , icon , proto , pid , ipaddr , hostname , port , uid , gid , origin , is_socks , optstring , sandbox , action ) {
fmt . Println ( "REQUEST WAS DUPLICATE" )
fmt . Println ( "REQUEST WAS DUPLICATE" )
decision := addDecision ( )
decision := addDecision ( )
globalPromptLock . Lock ( )
toggleHover ( )
toggleHover ( )
globalPromptLock . Unlock ( )
return decision
return decision
} else {
} else {
fmt . Println ( "NOT DUPLICATE" )
fmt . Println ( "NOT DUPLICATE" )
@ -523,7 +444,7 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
}
}
}
colVals := make ( [ ] interface { } , 1 5 )
colVals := make ( [ ] interface { } , 1 6 )
colVals [ 0 ] = 1
colVals [ 0 ] = 1
colVals [ 1 ] = guid
colVals [ 1 ] = guid
colVals [ 2 ] = path
colVals [ 2 ] = path
@ -542,14 +463,15 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
colVals [ 9 ] = uid
colVals [ 9 ] = uid
colVals [ 10 ] = gid
colVals [ 10 ] = gid
colVals [ 11 ] = origin
colVals [ 11 ] = origin
colVals [ 12 ] = 0
colVals [ 12 ] = timestamp
colVals [ 13 ] = 0
if is_socks {
if is_socks {
colVals [ 1 2 ] = 1
colVals [ 1 3 ] = 1
}
}
colVals [ 1 3 ] = optstring
colVals [ 1 4 ] = optstring
colVals [ 1 4 ] = action
colVals [ 1 5 ] = action
colNums := make ( [ ] int , len ( colVals ) )
colNums := make ( [ ] int , len ( colVals ) )
@ -558,7 +480,6 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
}
err := listStore . Set ( iter , colNums , colVals )
err := listStore . Set ( iter , colNums , colVals )
globalPromptLock . Unlock ( )
if err != nil {
if err != nil {
log . Fatal ( "Unable to add row:" , err )
log . Fatal ( "Unable to add row:" , err )
@ -567,6 +488,7 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
decision := addDecision ( )
decision := addDecision ( )
dumpDecisions ( )
dumpDecisions ( )
toggleHover ( )
toggleHover ( )
globalPromptLock . Unlock ( )
return decision
return decision
}
}
@ -682,14 +604,17 @@ func makeDecision(idx int, rule string, scope int) error {
return nil
return nil
}
}
/* Do we need to hold the lock while this is called? Stay safe... */
func toggleHover ( ) {
func toggleHover ( ) {
mainWin . SetKeepAbove ( len ( decisionWaiters ) > 0 )
nitems := globalLS . IterNChildren ( nil )
mainWin . SetKeepAbove ( nitems > 0 )
}
}
func toggleValidRuleState ( ) {
func toggleValidRuleState ( ) {
ok := true
ok := true
// Unfortunately, this can cause deadlock since it's a part of i the item removal cascade
// Unfortunately, this can cause deadlock since it's a part of the item removal cascade
// globalPromptLock.Lock()
// globalPromptLock.Lock()
// defer globalPromptLock.Unlock()
// defer globalPromptLock.Unlock()
@ -912,8 +837,13 @@ func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
return rule , nil , err
return rule , nil , err
}
}
rule . Timestamp , err = lsGetStr ( globalLS , iter , 12 )
if err != nil {
return rule , nil , err
}
rule . IsSocks = false
rule . IsSocks = false
is_socks , err := lsGetInt ( globalLS , iter , 12 )
is_socks , err := lsGetInt ( globalLS , iter , 1 3 )
if err != nil {
if err != nil {
return rule , nil , err
return rule , nil , err
}
}
@ -922,7 +852,7 @@ func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
rule . IsSocks = true
rule . IsSocks = true
}
}
rule . Scope , err = lsGetInt ( globalLS , iter , 1 4 )
rule . Scope , err = lsGetInt ( globalLS , iter , 1 5 )
if err != nil {
if err != nil {
return rule , nil , err
return rule , nil , err
}
}
@ -965,7 +895,7 @@ func addPendingPrompts(rules []string) {
for _ , rule := range rules {
for _ , rule := range rules {
fields := strings . Split ( rule , "|" )
fields := strings . Split ( rule , "|" )
if len ( fields ) != 1 8 {
if len ( fields ) != 1 9 {
log . Printf ( "Got saved prompt message with strange data: \"%s\"" , rule )
log . Printf ( "Got saved prompt message with strange data: \"%s\"" , rule )
continue
continue
}
}
@ -1011,15 +941,16 @@ func addPendingPrompts(rules []string) {
continue
continue
}
}
optstring := fields [ 16 ]
timestamp := fields [ 16 ]
optstring := fields [ 17 ]
action , err := strconv . Atoi ( fields [ 1 7 ] )
action , err := strconv . Atoi ( fields [ 1 8 ] )
if err != nil {
if err != nil {
log . Println ( "Error converting action in pending prompt message to integer:" , err )
log . Println ( "Error converting action in pending prompt message to integer:" , err )
continue
continue
}
}
addRequestAsync ( nil , guid , path , icon , proto , int ( pid ) , ip , address , int ( port ) , int ( uid ) , int ( gid ) , origin , is_socks, optstring , sandbox , action )
addRequestAsync ( nil , guid , path , icon , proto , int ( pid ) , ip , address , int ( port ) , int ( uid ) , int ( gid ) , origin , timestamp, is_socks, optstring , sandbox , action )
}
}
}
}
@ -1255,14 +1186,15 @@ func main() {
tv . AppendColumn ( createColumn ( "UID" , 9 ) )
tv . AppendColumn ( createColumn ( "UID" , 9 ) )
tv . AppendColumn ( createColumn ( "GID" , 10 ) )
tv . AppendColumn ( createColumn ( "GID" , 10 ) )
tv . AppendColumn ( createColumn ( "Origin" , 11 ) )
tv . AppendColumn ( createColumn ( "Origin" , 11 ) )
tv . AppendColumn ( createColumn ( "Timestamp" , 12 ) )
scol := createColumn ( "Is SOCKS" , 1 2 )
scol := createColumn ( "Is SOCKS" , 1 3 )
scol . SetVisible ( false )
scol . SetVisible ( false )
tv . AppendColumn ( scol )
tv . AppendColumn ( scol )
tv . AppendColumn ( createColumn ( "Details" , 1 3 ) )
tv . AppendColumn ( createColumn ( "Details" , 1 4 ) )
acol := createColumn ( "Scope" , 1 4 )
acol := createColumn ( "Scope" , 1 5 )
acol . SetVisible ( false )
acol . SetVisible ( false )
tv . AppendColumn ( acol )
tv . AppendColumn ( acol )