#!/usr/bin/env python # -*- coding: UTF-8 -*- ########################################################################## # TcosMonitor writen by MarioDebian # # tcos-server-utils version __VERSION__ # # Copyright (c) 2006 Mario Izquierdo # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. ########################################################################### import os, sys import getopt from gettext import gettext as _ import socket import netifaces import IPy import xml.dom.minidom import tcosmonitor.shared from subprocess import Popen, PIPE, STDOUT import grp, pwd if os.geteuid() != 0: print "tcos-server-utils ERROR: you must be root to run this" sys.exit(1) # append current dir to sys-path if exec from sources for m in range(len(sys.path)): if "server-utils" in sys.path[m]: sys.path[m]=os.path.dirname(sys.path[m]) from tcosmonitor import shared def print_debug(txt): if shared.debug: print "%s::%s" %("tcos-server-utils", txt) shared.from_cron=False actions=["reboot", "poweroff", "restartx", "message", "nothing"] action = "" text="" users="" def usage(): print "tcos-server-utils help:" print "" print " tcos-server-utils --action=XXX (action must be: %s ) " %(", ".join(actions) ) print " (use --action=nothing to test with doing nothing!!!)" print " tcos-server-utils --text=\"foo\" (if action=message this text will be displayed " print " in all connected users with notification-daemon)" print " --users=foo,bar (coma separated list of users we want to do action" print " only valid for --action=message)" print " tcos-server-utils -d [--debug] (write debug data to stdout)" print " tcos-server-utils -h [--help] (this help)" try: opts, args = getopt.getopt(sys.argv[1:], ":hd", ["help", "cron", "debug", "action=", "text=", "users="]) except getopt.error, msg: print msg print "for command line options use tcos-server-utils --help" sys.exit(2) # process options for o, a in opts: if o in ("--help"): usage() sys.exit(0) if o in ("-d", "--debug"): shared.debug = True if o in ("--cron"): shared.from_cron=True if o == "--action": if not a in actions: print "TCOS tcos-server-utils ERROR: action \"%s\" not avalaible" %(a) sys.exit(1) action = a if o == "--text": text=a if o == "--users": users=a if action=="": print "tcos-server-utils ERROR: action must be in: %s" %(", ".join(actions) ) sys.exit(0) class ServerUtils: def __init__(self): self.name="ServerUtils" self.worker_running = False self.ingroup_tcos=None # get all devices import tcosmonitor.TcosCommon import tcosmonitor.TcosXmlRpc import tcosmonitor.TcosConf self.common=tcosmonitor.TcosCommon.TcosCommon(self) self.config=tcosmonitor.TcosConf.TcosConf(self) self.xmlrpc=tcosmonitor.TcosXmlRpc.TcosXmlRpc(self) for group in os.getgroups(): if grp.getgrgid(group)[0] == "tcos": self.ingroup_tcos=True if os.getuid() == 0: self.ingroup_tcos=True if self.ingroup_tcos == False and os.getuid() != 0: sys.exit(1) interface=self.config.GetVar("network_interface") ss=self.get_net_address(interface) if self.config.GetVar("xmlrpc_username") == "" or self.config.GetVar("xmlrpc_password") == "": print "tcos-server-utils ERROR: need to create /root/.tcosmonitor.conf with user and pass." print " see /usr/share/doc/tcosmonitor/README.tcos-server-utils" sys.exit(1) import tcosmonitor.LocalData self.localdata=tcosmonitor.LocalData.LocalData(self) self.alltcosclients=[] self.allclients=self.ping_iprange_nmap(ss) if len(self.allclients) == 0: print "tcos-server-utils No host connected, exiting..." sys.exit(0) for host in self.allclients: self.xmlrpc.newhost(host) if self.xmlrpc.connected: print_debug ("Host %s connected" %(host) ) self.alltcosclients.append(host) else: print_debug ("Host %s NOT connected" %(host) ) print ("Doing action \"%s\" in %s" %(action, self.alltcosclients) ) if action == "message": if text != "": print ( "Searching for all connected users..." ) connected_users=[] #connected_users=['magna26'] if users != "": connected_users = users.split(',') print "Users from cdmline: %s" %(connected_users) else: for client in self.alltcosclients: if self.localdata.IsLogged(client): connected_users.append(self.localdata.GetUsername(client)) print ( "Connected users: %s" %connected_users) from tcosmonitor.TcosDBus import TcosDBusAction self.dbus_action=TcosDBusAction( self, \ admin=self.config.GetVar("xmlrpc_username"), \ passwd=self.config.GetVar("xmlrpc_password") ) result=self.dbus_action.do_message ( connected_users, text ) if not result: print "ERROR: sending dbus msg: %s" %(self.dbus_action.get_error_msg() ) else: print "DBus message send ok." else: print ( "ERROR: message action need a --text value" ) for client in self.alltcosclients: if action == "reboot": print ( "Restarting %s..." %client ) self.xmlrpc.newhost(client) self.xmlrpc.Exe("reboot") elif action == "poweroff": print ( "Shutting down %s..." %client ) self.xmlrpc.newhost(client) self.xmlrpc.Exe("poweroff") elif action == "restartx": print ( "Restarting Xorg of %s..." %client ) self.xmlrpc.newhost(client) self.xmlrpc.Exe("restartx") elif action == "message": pass else: print ( "Unknow action %s in client %s" %(action, client) ) def get_net_address(self, ifname): print("get_net_address() ifname=%s" %(ifname) ) if not ifname in netifaces.interfaces(): return None ip=netifaces.ifaddresses(ifname) if ip.has_key(netifaces.AF_INET): address="%s" %ip[netifaces.AF_INET][0]['addr'] mask="%s" %ip[netifaces.AF_INET][0]['netmask'] net="%s" %IPy.IP(address).make_net(mask) print("net=%s" %net) return net return None def get_server_ips(self): IPS=[] for dev in netifaces.interfaces(): if not dev in tcosmonitor.shared.hidden_network_ifaces: print("get_server_ips() add interface %s"%dev) ip=netifaces.ifaddresses(dev) if ip.has_key(netifaces.AF_INET): ip[netifaces.AF_INET][0]['gateway']=self.get_gateway(dev) print("get_server_ips() iface=%s data=%s"%(dev, ip[netifaces.AF_INET] )) IPS.append(ip[netifaces.AF_INET][0]['addr']) return IPS def get_gateway(self, iface): data=[] f=open("/proc/net/route", 'r') for l in f.readlines(): if l.startswith(iface): tmp=l.strip().split() if tmp[1] == "00000000": data.append(self.__hex2dec__(tmp[2])) f.close() if len(data) < 1: #print ("WARNING: no gateway") return None else: return data[0] def __hex2dec__(self, s): out=[] for i in range(len(s)/2): out.append( str(int(s[i*2:(i*2)+2], 16)) ) # data in /proc/net/route is reversed out.reverse() return ".".join(out) def ping_iprange_nmap(self, selfip): pinglist=[] reachip=[] server_ips=self.get_server_ips() if self.config.GetVar("onlyshowtcos") == 1: print("cmd='op nmap-tcos -sS -p%s -n --open -oX - %s'"%(tcosmonitor.shared.xmlremote_port, selfip)) cmd="op nmap-tcos -sS -p%s -n --open -oX - %s" %(tcosmonitor.shared.xmlremote_port, selfip) else: print("cmd='op nmap-tcos -sP -n -oX - %s'"%selfip) cmd="op nmap-tcos -sP -n -oX - %s" %selfip try: p = Popen(cmd, shell=True, bufsize=100000, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) except Exception, e: print("Exception in subprocess cmd(%s), error='%s'"%(cmd, e)) return None # Use dom to parse output, idea taken from python-nmap source # wait until finished # get output (nmap_last_output, nmap_err) = p.communicate() # If there was something on stderr, there was a problem so abort... if len(nmap_err) > 0: print("Error in nmap cmd(%s), error='%s'"%(cmd, nmap_err)) return [] dom = xml.dom.minidom.parseString(nmap_last_output) for dhost in dom.getElementsByTagName('host'): ipnmap = dhost.getElementsByTagName('address')[0].getAttributeNode('addr').value print("ipnmap: %s" %str(ipnmap)) for dstatus in dhost.getElementsByTagName('status'): # is up? up = dstatus.getAttributeNode('state').value reason = dstatus.getAttributeNode('reason').value print("state=%s reason=%s" %(str(up), str(reason))) if str(up) != "up" or str(reason) != "arp-response": continue if self.config.GetVar("onlyshowtcos") == 1: for dport in dhost.getElementsByTagName('port'): proto = dport.getAttributeNode('protocol').value port = int(dport.getAttributeNode('portid').value) state = dport.getElementsByTagName('state')[0].getAttributeNode('state').value print("port=%s state=%s" %(str(port), str(state))) if str(port) == str(tcosmonitor.shared.xmlremote_port) and str(state) == "open": pinglist.append(str(ipnmap)) else: pinglist.append(str(ipnmap)) print_debug(pinglist) i=0 for ipnmap in pinglist: i=i+1 if ipnmap in server_ips: print("Nmap:: ip (%s) is in server_ips(%s)" % (ipnmap, server_ips) ) continue # only show in list hosts running tcosxmlrpc in 8998 or 8999 port if self.config.GetVar("onlyshowtcos") == 1: if self.xmlrpc.newhost(ipnmap): if self.xmlrpc.GetVersion(): print("ping_iprange() host=%s ports 8998 or 8999 OPEN" %(ipnmap)) reachip.append(ipnmap) else: print("ping_iprange() host=%s ports 8998 or 8999 OPEN but not tcosxmlrpc" %(ipnmap)) else: print("ping_iprange() host=%s ports 8998 or 8999 closed" %(ipnmap)) else: reachip.append(ipnmap) print("ping_iprange_nmap() discovered host finished" ) return reachip if __name__ == "__main__": app=ServerUtils()