Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac加入Root Helper,并修复更新提示 #2513

Merged
merged 4 commits into from
Mar 28, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gae_proxy/web_ui/status.html
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ <h3>{{ _( "Diagnostic Info" ) }}</h3>
}

function test_http_proxy_setting() {
if (window.http_proxy_setting === "OK") {
if (window.http_proxy_setting === "OK" || window.https_proxy_setting === "OK") {
return "OK";
}

Expand Down
Binary file added launcher/mac_helper
Binary file not shown.
32 changes: 32 additions & 0 deletions launcher/mac_helper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, const char * argv[]) {
if (geteuid() != 0) {
fprintf(stderr, "Must be run as root!\n");
return 1;
}
if (argc == 4 && strcmp(argv[1], "enableauto") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setautoproxyurl", argv[2], argv[3], NULL);
} else if (argc == 5 && strcmp(argv[1], "enablehttp") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setwebproxy", argv[2], argv[3], argv[4], NULL);
} else if (argc == 5 && strcmp(argv[1], "enablehttps") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setsecurewebproxy", argv[2], argv[3], argv[4], NULL);
} else if (argc == 3 && strcmp(argv[1], "disableauto") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setautoproxystate", argv[2], "off", NULL);
} else if (argc == 3 && strcmp(argv[1], "disablehttp") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setwebproxystate", argv[2], "off", NULL);
} else if (argc == 3 && strcmp(argv[1], "disablehttps") == 0) {
execl("/usr/sbin/networksetup", "networksetup", "-setsecurewebproxystate", argv[2], "off", NULL);
} else {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "%s enableauto <networkservice> <url>\n", argv[0]);
fprintf(stderr, "%s enablehttp <networkservice> <domain> <port number>\n", argv[0]);
fprintf(stderr, "%s enablehttps <networkservice> <domain> <port number>\n", argv[0]);
fprintf(stderr, "%s disableauto <networkservice>\n", argv[0]);
fprintf(stderr, "%s disablehttp <networkservice>\n", argv[0]);
fprintf(stderr, "%s disablehttps <networkservice>\n", argv[0]);
}
return 0;
}
201 changes: 125 additions & 76 deletions launcher/mac_tray.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import config

current_path = os.path.dirname(os.path.abspath(__file__))
helper_path = os.path.join(current_path, os.pardir, 'data', 'launcher', 'helper')

if __name__ == "__main__":
python_path = os.path.abspath( os.path.join(current_path, os.pardir, 'python27', '1.0'))
Expand All @@ -31,33 +32,10 @@ def __init__(self):
pass

def applicationDidFinishLaunching_(self, notification):
setupHelper()
self.setupUI()
self.registerObserver()

def getProxyState(self, service):
if not service:
return

# Check if auto proxy is enabled
checkAutoProxyUrlCommand = 'networksetup -getautoproxyurl "%s"' % service
executeResult = subprocess.check_output(checkAutoProxyUrlCommand, shell=True)
if ( executeResult.find('http://127.0.0.1:8086/proxy.pac\nEnabled: Yes') != -1 ):
return "pac"

# Check if global proxy is enabled
checkGlobalProxyUrlCommand = 'networksetup -getwebproxy "%s"' % service
executeResult = subprocess.check_output(checkGlobalProxyUrlCommand, shell=True)
if ( executeResult.find('Enabled: Yes\nServer: 127.0.0.1\nPort: 8087') != -1 ):
return "gae"

return "disable"

def getCurrentServiceMenuItemTitle(self):
if currentService:
return 'Connection: %s' % currentService
else:
return 'Connection: None'

def setupUI(self):
self.statusbar = NSStatusBar.systemStatusBar()
self.statusitem = self.statusbar.statusItemWithLength_(NSSquareStatusItemLength) #NSSquareStatusItemLength #NSVariableStatusItemLength
Expand All @@ -74,15 +52,15 @@ def setupUI(self):
self.statusitem.setToolTip_("XX-Net")

# Get current selected mode
proxyState = self.getProxyState(currentService)
proxyState = getProxyState(currentService)

# Build a very simple menu
self.menu = NSMenu.alloc().initWithTitle_('XX-Net')

menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Config', 'config:', '')
self.menu.addItem_(menuitem)

menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(self.getCurrentServiceMenuItemTitle(), None, '')
menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(getCurrentServiceMenuItemTitle(), None, '')
self.menu.addItem_(menuitem)
self.currentServiceMenuItem = menuitem

Expand Down Expand Up @@ -117,15 +95,15 @@ def setupUI(self):
NSApp.setActivationPolicy_(NSApplicationActivationPolicyProhibited)

def updateStatusBarMenu(self):
self.currentServiceMenuItem.setTitle_(self.getCurrentServiceMenuItemTitle())
self.currentServiceMenuItem.setTitle_(getCurrentServiceMenuItemTitle())

# Remove Tick before All Menu Items
self.autoGaeProxyMenuItem.setState_(NSOffState)
self.globalGaeProxyMenuItem.setState_(NSOffState)
self.disableGaeProxyMenuItem.setState_(NSOffState)

# Get current selected mode
proxyState = self.getProxyState(currentService)
proxyState = getProxyState(currentService)

# Update Tick before Menu Item
if proxyState == 'pac':
Expand All @@ -143,30 +121,40 @@ def validateMenuItem_(self, menuItem):
menuItem != self.globalGaeProxyMenuItem and
menuItem != self.disableGaeProxyMenuItem)

def updateConfig(self, newStatus):
config.set(["modules", "launcher", "proxy"], newStatus)
config.save()
def presentAlert_withTitle_(self, msg, title):
self.performSelectorOnMainThread_withObject_waitUntilDone_('presentAlertWithInfo:', [title, msg], True)
return self.alertReturn

def presentAlertWithInfo_(self, info):
alert = NSAlert.alloc().init()
alert.setMessageText_(info[0])
alert.setInformativeText_(info[1])
alert.addButtonWithTitle_("OK")
alert.addButtonWithTitle_("Cancel")
self.alertReturn = alert.runModal() == NSAlertFirstButtonReturn

def registerObserver(self):
nc = NSWorkspace.sharedWorkspace().notificationCenter()
nc.addObserver_selector_name_object_(self, 'windowWillClose:', NSWorkspaceWillPowerOffNotification, None)

def windowWillClose_(self, notification):
listNetworkServicesCommand = 'networksetup -listallnetworkservices'
executeResult = subprocess.check_output(listNetworkServicesCommand, shell=True)
executeResult = subprocess.check_output(['networksetup', '-listallnetworkservices'])
services = executeResult.split('\n')
services = filter(lambda service : service and service.find('*') == -1 and self.getProxyState(service) != 'disable', services) # Remove disabled services and empty lines
services = filter(lambda service : service and service.find('*') == -1 and getProxyState(service) != 'disable', services) # Remove disabled services and empty lines

if len(services) > 0:
disableAutoProxyCommand = ';'.join(map(self.getDisableAutoProxyCommand, services))
disableGlobalProxyCommand = ';'.join(map(self.getDisableGlobalProxyCommand, services))
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, disableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try disable proxy:%s", executeCommand)
os.system(executeCommand)
try:
map(helperDisableAutoProxy, services)
map(helperDisableGlobalProxy, services)
except:
disableAutoProxyCommand = ';'.join(map(getDisableAutoProxyCommand, services))
disableGlobalProxyCommand = ';'.join(map(getDisableGlobalProxyCommand, services))
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, disableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try disable proxy:%s", executeCommand)
os.system(executeCommand)

self.updateConfig('disable')
module_init.stop_all()
os._exit(0)
NSApp.terminate_(self)
Expand All @@ -180,54 +168,115 @@ def resetGoagent_(self, _):
module_init.start("gae_proxy")

def enableAutoProxy_(self, _):
disableGlobalProxyCommand = self.getDisableGlobalProxyCommand(currentService)
enableAutoProxyCommand = self.getEnableAutoProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableGlobalProxyCommand, enableAutoProxyCommand)
executeCommand = rootCommand.encode('utf-8')
try:
helperDisableGlobalProxy(currentService)
helperEnableAutoProxy(currentService)
except:
disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService)
enableAutoProxyCommand = getEnableAutoProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableGlobalProxyCommand, enableAutoProxyCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try enable auto proxy:%s", executeCommand)
os.system(executeCommand)
xlog.info("try enable auto proxy:%s", executeCommand)
os.system(executeCommand)
self.updateStatusBarMenu()
self.updateConfig('pac')

def enableGlobalProxy_(self, _):
disableAutoProxyCommand = self.getDisableAutoProxyCommand(currentService)
enableGlobalProxyCommand = self.getEnableGlobalProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, enableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')
try:
helperDisableAutoProxy(currentService)
helperEnableGlobalProxy(currentService)
except:
disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)
enableGlobalProxyCommand = getEnableGlobalProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, enableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try enable global proxy:%s", executeCommand)
os.system(executeCommand)
xlog.info("try enable global proxy:%s", executeCommand)
os.system(executeCommand)
self.updateStatusBarMenu()
self.updateConfig('gae')

def disableProxy_(self, _):
disableAutoProxyCommand = self.getDisableAutoProxyCommand(currentService)
disableGlobalProxyCommand = self.getDisableGlobalProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, disableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')
try:
helperDisableAutoProxy(currentService)
helperDisableGlobalProxy(currentService)
except:
disableAutoProxyCommand = getDisableAutoProxyCommand(currentService)
disableGlobalProxyCommand = getDisableGlobalProxyCommand(currentService)
rootCommand = """osascript -e 'do shell script "%s;%s" with administrator privileges' """ % (disableAutoProxyCommand, disableGlobalProxyCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try disable proxy:%s", executeCommand)
os.system(executeCommand)
self.updateStatusBarMenu()


xlog.info("try disable proxy:%s", executeCommand)
def setupHelper():
try:
with open(os.devnull) as devnull:
subprocess.check_call(helper_path, stderr=devnull)
except:
cpCommand = "cp \\\"%s\\\" \\\"%s\\\"" % (os.path.join(current_path, 'mac_helper'), helper_path)
chmodCommand = "chmod 4777 \\\"%s\\\"" % helper_path
chownCommand = "chown root \\\"%s\\\"" % helper_path
rootCommand = """osascript -e 'do shell script "%s;%s;%s" with administrator privileges' """ % (cpCommand, chmodCommand, chownCommand)
executeCommand = rootCommand.encode('utf-8')

xlog.info("try setup helper:%s", executeCommand)
os.system(executeCommand)
self.updateStatusBarMenu()
self.updateConfig('disable')

# Generate commands for Apple Script
def getEnableAutoProxyCommand(self, service):
return "networksetup -setautoproxyurl \\\"%s\\\" \\\"http://127.0.0.1:8086/proxy.pac\\\"" % service
def getCurrentServiceMenuItemTitle():
if currentService:
return 'Connection: %s' % currentService
else:
return 'Connection: None'

def getProxyState(service):
if not service:
return

# Check if auto proxy is enabled
executeResult = subprocess.check_output(['networksetup', '-getautoproxyurl', service])
if ( executeResult.find('http://127.0.0.1:8086/proxy.pac\nEnabled: Yes') != -1 ):
return "pac"

# Check if global proxy is enabled
executeResult = subprocess.check_output(['networksetup', '-getwebproxy', service])
if ( executeResult.find('Enabled: Yes\nServer: 127.0.0.1\nPort: 8087') != -1 ):
return "gae"

return "disable"

# Generate commands for Apple Script
def getEnableAutoProxyCommand(service):
return "networksetup -setautoproxyurl \\\"%s\\\" \\\"http://127.0.0.1:8086/proxy.pac\\\"" % service

def getDisableAutoProxyCommand(service):
return "networksetup -setautoproxystate \\\"%s\\\" off" % service

def getEnableGlobalProxyCommand(service):
enableHttpProxyCommand = "networksetup -setwebproxy \\\"%s\\\" 127.0.0.1 8087" % service
enableHttpsProxyCommand = "networksetup -setsecurewebproxy \\\"%s\\\" 127.0.0.1 8087" % service
return "%s;%s" % (enableHttpProxyCommand, enableHttpsProxyCommand)

def getDisableGlobalProxyCommand(service):
disableHttpProxyCommand = "networksetup -setwebproxystate \\\"%s\\\" off" % service
disableHttpsProxyCommand = "networksetup -setsecurewebproxystate \\\"%s\\\" off" % service
return "%s;%s" % (disableHttpProxyCommand, disableHttpsProxyCommand)

# Call helper
def helperEnableAutoProxy(service):
subprocess.check_call([helper_path, 'enableauto', service, 'http://127.0.0.1:8086/proxy.pac'])

def getDisableAutoProxyCommand(self, service):
return "networksetup -setautoproxystate \\\"%s\\\" off" % service
def helperDisableAutoProxy(service):
subprocess.check_call([helper_path, 'disableauto', service])

def getEnableGlobalProxyCommand(self, service):
enableHttpProxyCommand = "networksetup -setwebproxy \\\"%s\\\" 127.0.0.1 8087" % service
enableHttpsProxyCommand = "networksetup -setsecurewebproxy \\\"%s\\\" 127.0.0.1 8087" % service
return "%s;%s" % (enableHttpProxyCommand, enableHttpsProxyCommand)
def helperEnableGlobalProxy(service):
subprocess.check_call([helper_path, 'enablehttp', service, '127.0.0.1', '8087'])
subprocess.check_call([helper_path, 'enablehttps', service, '127.0.0.1', '8087'])

def getDisableGlobalProxyCommand(self, service):
disableHttpProxyCommand = "networksetup -setwebproxystate \\\"%s\\\" off" % service
disableHttpsProxyCommand = "networksetup -setsecurewebproxystate \\\"%s\\\" off" % service
return "%s;%s" % (disableHttpProxyCommand, disableHttpsProxyCommand)
def helperDisableGlobalProxy(service):
subprocess.check_call([helper_path, 'disablehttp', service])
subprocess.check_call([helper_path, 'disablehttps', service])


sys_tray = MacTrayObject.alloc().init()
Expand Down
4 changes: 2 additions & 2 deletions launcher/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def download_module(module, new_version):
ignore_module(module, new_version)
elif sys.platform == "darwin":
from mac_tray import sys_tray
if sys_tray.dialog_yes_no(msg, u"Install", None, None) == 1:
if sys_tray.presentAlert_withTitle_(msg, "Install"):
install_module(module, new_version)
else:
ignore_module(module, new_version)
Expand Down Expand Up @@ -314,7 +314,7 @@ def check_push_update():
elif sys.platform == "darwin":
from mac_tray import sys_tray
msg = "Module %s new version: %s, Download?" % (module, new_version)
if sys_tray.dialog_yes_no(msg, u"Download", None, None) == 1:
if sys_tray.presentAlert_withTitle_(msg, "Download"):
download_module(module, new_version)
else:
ignore_module(module, new_version)
Expand Down