Add : orphaned test to all tests.
[shinken.git] / libexec / nsca_client.py
blob76e551dbf21e798fada62792d0f38e9afca97d7e
1 ### This is a very quick and dirty code for David so he can work on its sikuli agent
2 # and report as nsca the results.
3 # This need to be clean a lot, it's still a server and should be a client class :)
4 # I can do it after my "new baby holidays" are finished ;)
5 # J.Gabes
9 import time
10 import select
11 import socket
12 import struct
13 import sys
14 import random
17 def decrypt_xor(data, key):
18 keylen = len(key)
19 crypted = [chr(ord(data[i]) ^ ord(key[i % keylen])) for i in xrange(len(data))]
20 return ''.join(crypted)
24 #Just print some stuff
25 class NSCA_client():
26 def __init__(self, host, port, encryption_method, password):
27 self.host = host
28 self.port = port
29 self.encryption_method = encryption_method
30 self.password = password
31 self.rng = random.Random(password)
34 #Ok, main function that is called in the CONFIGURATION phase
35 def get_objects(self):
36 print "[Dummy] ask me for objects to return"
37 r = {'hosts' : []}
38 h = {'name' : 'dummy host from dummy arbiter module',
39 'register' : '0',
42 r['hosts'].append(h)
43 print "[Dummy] Returning to Arbiter the hosts:", r
44 return r
46 def send_init_packet(self, socket):
47 '''
48 Build an init packet
49 00-127 : IV
50 128-131 : unix timestamp
51 '''
52 iv = ''.join([chr(self.rng.randrange(256)) for i in xrange(128)])
53 init_packet = struct.pack("!128sI", iv, int(time.mktime(time.gmtime())))
54 socket.send(init_packet)
55 return iv
57 def read_check_result(self, data, iv):
58 '''
59 Read the check result
60 00-01 : Version
61 02-05 : CRC32
62 06-09 : Timestamp
63 10-11 : Return code
64 12-75 : hostname
65 76-203 : service
66 204-715 : output of the plugin
67 716-720 : padding
68 '''
69 if len(data) != 720:
70 return None
72 if self.encryption_method == 1:
73 data = decrypt_xor(data,self.password)
74 data = decrypt_xor(data,iv)
76 (version, pad1, crc32, timestamp, rc, hostname_dirty, service_dirty, output_dirty, pad2) = struct.unpack("!hhIIh64s128s512sh",data)
77 hostname = hostname_dirty.partition("\0", 1)[0]
78 service = service_dirty.partition("\0", 1)[0]
79 output = output_dirty.partition("\0", 1)[0]
80 return (timestamp, rc, hostname, service, output)
82 def post_command(self, timestamp, rc, hostname, service, output):
83 '''
84 Send a check result command to the arbiter
85 '''
86 if len(service) == 0:
87 extcmd = "[%lu] PROCESS_HOST_CHECK_RESULT;%s;%d;%s\n" % (timestamp,hostname,rc,output)
88 else:
89 extcmd = "[%lu] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n" % (timestamp,hostname,service,rc,output)
91 print "want to send", extcmd
93 #e = ExternalCommand(extcmd)
94 #self.from_q.put(e)
97 # When you are in "external" mode, that is the main loop of your process
98 def main(self):
99 #self.set_exit_handler()
100 self.interrupted = False
101 backlog = 5
102 size = 8192
103 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
104 #server.setblocking(0)
105 server.connect((self.host, self.port))
106 #server.listen(backlog)
107 input = [server]
108 databuffer = {}
109 IVs = {}
111 init = server.recv(size)
112 print "got init", init
114 #init_packet = struct.pack("!128sI",iv,int(time.mktime(time.gmtime())))
115 (iv, t) = struct.unpack("!128sI",init)
116 print "IV", iv
117 print "T", t
119 version = 0
120 pad1 = 0
121 crc32= 0
122 timestamp = int(time.time())
123 rc = 2
124 hostname_dirty = "moncul"
125 service_dirty = "fonctionnne"
126 output_dirty = "blablalba"
127 pad2=0
129 Read the check result
130 00-01 : Version
131 02-05 : CRC32
132 06-09 : Timestamp
133 10-11 : Return code
134 12-75 : hostname
135 76-203 : service
136 204-715 : output of the plugin
137 716-720 : padding
139 init_packet = struct.pack("!hhIIh64s128s512sh", version, pad1, crc32, timestamp, rc, hostname_dirty, service_dirty, output_dirty, pad2)
140 print "Create packent len", len(init_packet)
141 #(version, pad1, crc32, timestamp, rc, hostname_dirty, service_dirty, output_dirty, pad2) = struct.unpack("!hhIIh64s128s512sh",data)
143 data = decrypt_xor(init_packet,iv)
144 data = decrypt_xor(data,self.password)
147 server.send(data)
148 sys.exit(0)
150 while not self.interrupted:
151 print "Loop"
152 inputready,outputready,exceptready = select.select(input,[],[], 1)
154 for s in inputready:
155 if s == server:
156 # handle the server socket
157 #client, address = server.accept()
158 iv = self.send_init_packet(client)
159 IVs[client] = iv
160 input.append(client)
161 else:
162 # handle all other sockets
163 data = s.recv(size)
164 if s in databuffer:
165 databuffer[s] += data
166 else:
167 databuffer[s] = data
168 if len(databuffer[s]) == 720:
169 # end-of-transmission or an empty line was received
170 (timestamp, rc, hostname, service, output)=self.read_check_result(databuffer[s],IVs[s])
171 del databuffer[s]
172 del IVs[s]
173 self.post_command(timestamp,rc,hostname,service,output)
174 try:
175 s.shutdown(2)
176 except Exception , exp:
177 print exp
178 s.close()
179 input.remove(s)
183 nsca = NSCA_client('localhost', 5667, 1, 'toto')
184 nsca.main()