Package zephir :: Module lib_zephir
[frames] | no frames]

Source Code for Module zephir.lib_zephir

  1  # -*- coding: UTF-8 -*- 
  2  ########################################################################### 
  3  # Eole NG - 2007 
  4  # Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon) 
  5  # Licence CeCill  cf /root/LicenceEole.txt 
  6  # eole@ac-dijon.fr 
  7  # 
  8  # lib_zephir.py 
  9  # 
 10  # librairie de fonctions pour le client Zephir 
 11  # 
 12  ########################################################################### 
 13   
 14  registered = 1 
 15  try: 
 16      import zephir.zephir_conf.zephir_conf as config 
 17  except: 
 18      registered = 0 
 19  import os, sys, time, socket, getpass 
 20  from creole.cfgparser import EoleDict 
 21  from creole.config import eoledirs, eoleroot, eole_module, rsyslog_request_template 
 22  from creole.utils import print_orange, print_red, print_green 
 23  from creole.eosfunc import load_container_var 
 24  from creole.cert import gen_request, gen_privkey 
 25  from pyeole.service import service_out, service_code 
 26  from pyeole.process import system_code, system_out 
 27  from glob import glob 
 28  import traceback 
 29  # imports locaux 
 30  from zephir.eolerpclib import xmlrpclib, EoleProxy 
 31  from zephir.prelude_options import get_options 
 32   
 33  # valeurs par défaut pour la fonction de saisie d'enregistrement_zephir 
 34  defaults = {'timeout':30,'interf':'eth0'} 
 35   
 36  # définition de l'encodage du texte 
 37  charset = 'UTF-8' 
 38  # répertoire publique d'uucp 
 39  public_dir = '/var/spool/uucppublic' 
 40  # définition du proxy XMLRPC 
 41  eole_dir = '/usr/share/eole' 
 42  zephir_dir = '/usr/share/zephir' 
 43  new_addr_file = os.path.join(zephir_dir, 'zephir_conf', 'new_pubkey') 
 44  # mode de sauvegarde des données locales 
 45  save_modes = {0:"Tout", 
 46                1:"configuration", 
 47                2:"configuration + patchs/dicos/templates", 
 48                3:"fichiers divers locaux", 
 49               } 
 50  # variables de gestion des conteneurs 
 51  container_vars = load_container_var() 
 52   
 53  # recherche du répertoire du module zephir 
 54  import zephir as zephir_lib 
 55  zephir_path = os.path.dirname(zephir_lib.__file__) 
 56   
 57  # redéfinition de la classe pour supporter les timeouts 
58 -class TransportEole(xmlrpclib.SafeTransport):
59
60 - def _parse_response(self, file, sock):
61 """lit et parse la réponse du serveur 62 modifié pour ne pas bloquer sur la lecture (file.read) 63 dans le cas de l'utilisation de ssl 64 """ 65 # read response from input file/socket, and parse it 66 67 p, u = self.getparser() 68 69 while 1: 70 if sock: 71 response = sock.recv(1024) 72 else: 73 response = file.read(1024) 74 if not response: 75 break 76 if self.verbose: 77 print "body:", repr(response) 78 p.feed(response) 79 if len(response) < 1024: 80 break 81 82 file.close() 83 p.close() 84 85 return u.close()
86 87 try: 88 if os.path.isdir('/var/lib/zephir'): 89 # on permet un temps d'attente plus long lors des requêtes sur Zephir 90 socket.setdefaulttimeout(180) 91 else: 92 # timeout réduit sur les serveurs clients pour éviter de bloquer le système 93 socket.setdefaulttimeout(15) 94 except: 95 # non implémenté sur python 2.2 96 pass 97 98 if registered: 99 zephir_proxy = EoleProxy("https://zephir:zephir@"+config.adresse_zephir+":7080", transport=TransportEole()) 100 # pour compatibilité avec des programmes externes 101 zephir = zephir_proxy 102
103 -def convert(objet):
104 """Transforme les objets unicode contenus dans un objet en chaines 105 """ 106 if type(objet) == list: 107 l = [] 108 for item in objet: 109 l.append(convert(item)) 110 return l 111 if type(objet) == dict: 112 dico = {} 113 for cle in objet.keys(): 114 dico[cle] = convert(objet[cle]) 115 return dico 116 if type(objet) == unicode: 117 string = objet.encode(charset) 118 return string 119 return objet
120
121 -def u(objet):
122 if type(objet) == list: 123 l = [] 124 for item in objet: 125 l.append(u(item)) 126 return l 127 if type(objet) == dict: 128 dico = {} 129 for cle in objet.keys(): 130 dico[cle] = u(objet[cle]) 131 return dico 132 if type(objet) == str: 133 string = unicode(objet, charset) 134 return string 135 return objet
136
137 -def log(action, etat, msg, date=''):
138 """fonction de log local et distant (si disponible) des actions zephir effectuées sur le serveur 139 """ 140 # on insère le log actuel à la liste des logs à envoyer 141 failed_logs = [] 142 ignored_logs = [] 143 if date == '': 144 date = str(time.ctime()) 145 liste_logs = [[str(date), action, str(etat), msg]] 146 # on regarde si il y a des logs différés (erreur de contact avec zephir lors d'un log précédent) 147 try: 148 fic_logs = open('%s/deffered_logs' % zephir_dir, 'r') 149 # rqe : on limite à 20 le nombre d'anciens logs à remonter (pour éviter de bloquer trop longtemps) 150 deffered_logs = fic_logs.read().strip().split('\n') 151 if len(deffered_logs) > 20: 152 old_logs = deffered_logs[:20] 153 ignored_logs = deffered_logs[20:] 154 else: 155 old_logs = deffered_logs 156 for log in old_logs: 157 # on stocke ces logs dans la liste 158 if log.count(';') > 0: 159 liste_logs.append(log.split(';')) 160 fic_logs.close() 161 except: 162 # le fichier n'existe pas 163 # (tous les logs sont passés) 164 pass 165 166 erreur_zephir = 0 167 # on essaie d'envoyer tous les logs via xmlrpc 168 for log in liste_logs: 169 if erreur_zephir == 0: 170 # on n'essaie pas de réinsérer les logs suivants si il y a eu une erreur 171 # (évite de répeter les timeouts de la connexion) 172 try: 173 date, action, etat, msg = log 174 try: 175 msg = u(msg) 176 except: 177 pass 178 if log[0] != '': 179 res = zephir_proxy.uucp.log_serveur(config.id_serveur, u(date), u(action), int(etat), msg) 180 else: 181 res = zephir_proxy.uucp.log_serveur(config.id_serveur, u(str(time.ctime())), u(action), int(etat), msg) 182 if res[0] == 0: 183 # erreur d'insertion du log, mais zephir répond, on continue en stockant ce log 184 failed_logs.append(';'.join(log)) 185 except: 186 # echec de la connexion à zephir 187 # on stocke les informations de log dans le fichier deffered_logs 188 # Ces logs seront parsés au prochain appel de cette fonction 189 erreur_zephir = 1 190 failed_logs.append(';'.join(log)) 191 else: 192 failed_logs.append(';'.join(log)) 193 194 if ignored_logs != []: 195 failed_logs.extend(ignored_logs) 196 # on sauvegarde tous les logs non envoyés 197 try: 198 fic_logs=open('%s/deffered_logs' % zephir_dir, 'w') 199 for log in failed_logs: 200 fic_logs.write(log+'\n') 201 fic_logs.close() 202 except: 203 # pas les droits pour écrire dans le fichier ? 204 pass 205 206 # Le log local est géré par les fonctions Zephir et Zecho 207 return "ok"
208 209 # fonctions de verrouillage 210 211 lock_dir = '/var/lock' 212
213 -def lock(tags):
214 """fonction qui crée un ou plusieurs verrous""" 215 retour = 1 216 if os.path.isdir(lock_dir): 217 if not type(tags) == list: 218 tags = [tags] 219 for tag in tags: 220 try: 221 fic_temp = open(lock_dir + os.sep + tag, "w").close() 222 except: 223 retour = 0 224 else: 225 retour = 0 226 return retour
227
228 -def unlock(tags):
229 """fonction qui supprime un verrou""" 230 try: 231 if not type(tags) == list: 232 tags = [tags] 233 for tag in tags: 234 if os.path.isfile(lock_dir+os.sep+tag): 235 os.unlink(lock_dir+os.sep+tag) 236 except: 237 return 0 238 return 1
239
240 -def is_locked(tags):
241 """fonction qui permet de savoir si un verrou particulier est posé""" 242 if not type(tags) == list: 243 tags = [tags] 244 for tag in tags: 245 if os.path.isfile(lock_dir+os.sep+tag): 246 return 1 247 else: 248 return 0
249
250 -def update_conf(id_serveur, adresse_zephir):
251 """met à jour le fichier conf_zephir""" 252 template_conf = """#!/usr/bin/env python 253 id_serveur=%s 254 adresse_zephir="%s" 255 256 if __name__ == "__main__": 257 print adresse_zephir 258 """ 259 try: 260 conf = open(os.path.join(zephir_path, 'zephir_conf/zephir_conf.py'), 'w') 261 conf.write(template_conf % (str(id_serveur), str(adresse_zephir))) 262 conf.close() 263 res = os.system('/bin/chmod 644 %s' % os.path.join(zephir_path, 'zephir_conf/zephir_conf.py')) 264 assert res == 0 265 except: 266 return False 267 if os.path.isfile(new_addr_file): 268 os.unlink(new_addr_file) 269 log('CONFIGURE', 0, """Nouvelle adresse de zephir prise en compte : %s""" % str(adresse_zephir)) 270 return True
271 272
273 -def maj_client_zephir(zephir_proxy, adresse_zephir):
274 """met à jour le client""" 275 276 # on regarde si une mise à jour est nécessaire 277 # récupération de la version locale 278 out = os.popen('/usr/bin/dpkg -p zephir-client | grep ^Version') 279 version_client = out.read().split(':')[1] 280 out.close() 281 version_client = "zephir-client_" + version_client.strip() 282 res_maj = 2 283 # vérification de la version présente sur zephir 284 try: 285 res = convert(zephir_proxy.maj_client(version_client)) 286 except Exception, e: 287 # fonction de mise à jour non disponible sur cette version de zephir 288 pass 289 else: 290 if res[0] == 0: 291 print("pas de mise à jour disponible sur zephir") 292 else: 293 if res[1] != "OK": 294 # une mise à jour est nécessaire 295 rpm_client = res[1].encode(charset).strip() 296 res_maj = os.system('%s/scripts/maj_client.sh %s %s' % (zephir_dir, adresse_zephir, rpm_client)) / 256 297 return res_maj
298
299 -def update_zephir_ip():
300 """vérifie si zephir répond sur sa nouvelle adresse (envoyée auparavant via change_ip) 301 """ 302 # lecture des données stockées (ancienne/nouvelle clé + nouvelle adresse) 303 ssh_dir = "/var/spool/uucp/.ssh/" 304 tmp_dir = os.path.join(ssh_dir, 'tmpkeys') 305 data_new_key = file(new_addr_file).read().strip() 306 old_key, new_key, new_addr = data_new_key.split('%%') 307 try: 308 proxy = EoleProxy("https://zephir:zephir@%s:7080" % (new_addr),transport=TransportEole()) 309 # demande de récupération de la nouvelle clé privée sur zephir. On doit envoyer les clés publiques (actuelle et nouvelle) 310 code, res = convert(proxy.serveurs.get_key(config.id_serveur, old_key, new_key)) 311 if code == 0: 312 log('CONFIGURE', 1, """Prise en compte de la nouvelle adresse (%s): clé non reconnue par zephir""" % (new_addr)) 313 return False 314 except: 315 return False 316 fic_priv = os.path.join(tmp_dir, 'new_key') 317 try: 318 if os.path.exists(fic_priv): 319 os.unlink(fic_priv) 320 os.system('/bin/touch %s;/bin/chmod 600 %s' % (fic_priv, fic_priv)) 321 fichier = file(fic_priv, 'a') 322 fichier.write(xmlrpclib.base64.decodestring(res)) 323 fichier.close() 324 except: 325 print "erreur d'ouverture du fichier %s" %fic_priv 326 return False 327 # activation de la clé sur zephir 328 data = convert(proxy.serveurs.update_key(config.id_serveur)) 329 if data[0] == 0: 330 print "erreur de mise en place de la nouvelle clé sur zephir : %s" % str(res) 331 return False 332 # sauvegarde de la clé actuelle 333 os.system("/bin/mv %s/id_rsa.pub %s/old_key.pub" % (ssh_dir, tmp_dir)) 334 os.system("/bin/mv %s/id_rsa %s/old_key" % (ssh_dir, tmp_dir)) 335 # mise en place de la nouvelle clé locale 336 os.system("/bin/mv %s/new_key.pub %s/id_rsa.pub" % (tmp_dir, ssh_dir)) 337 os.system("/bin/mv %s/new_key %s/id_rsa" % (tmp_dir, ssh_dir)) 338 os.system("/bin/chown uucp.uucp %s/id_rsa*" % ssh_dir) 339 # unlock(['configure', 'uucp', 'maj', 'reconfigure']) 340 # mise à jour de la configuration uucp 341 old_addr = config.adresse_zephir 342 for path_uucp in ['/etc/uucp/port', '/etc/uucp/sys']: 343 conf_uucp = open(path_uucp).read() 344 conf_uucp = conf_uucp.replace(old_addr, new_addr) 345 fic_uucp = open(path_uucp, 'w') 346 fic_uucp.write(conf_uucp) 347 fic_uucp.close() 348 # mise à jour de zephir_conf.py avec la nouvelle adresse 349 return update_conf(config.id_serveur, new_addr)
350
351 -def update_sudoers():
352 """met à jour la liste des scripts exécutables par sudo en tant que root""" 353 uucp_pattern = """uucp ALL=NOPASSWD""" 354 if os.path.isfile('/etc/sudoers'): 355 scripts = glob('%s/scripts/*.zephir' % zephir_dir) 356 scripts.sort() 357 # liste des scripts disponibles 358 uucp_conf = ["#ZEPHIR : liste des scripts exécutables par zephir_client, ne pas modifier\n"] 359 for script in scripts: 360 uucp_conf.append('%s : %s\n' % (uucp_pattern, script)) 361 uucp_conf.append('#ZEPHIR FIN\n') 362 # fichier actuel 363 orig_data = file('/etc/sudoers').readlines() 364 # supression des lignes concernant uucp 365 final_data = [] 366 for line in orig_data: 367 if not (line.startswith(uucp_pattern) or line.startswith('#ZEPHIR')): 368 final_data.append(line) 369 final_data.extend(uucp_conf) 370 # ré-écriture du fichier 371 try: 372 sudo_file = file('/etc/sudoers', 'w') 373 sudo_file.writelines(final_data) 374 sudo_file.close() 375 os.system('chmod 0440 /etc/sudoers') 376 return True 377 except: 378 print "\n! Client Zephir: Le fichier /etc/sudoers n'a pas pu être mis à jour !\n" 379 return False
380
381 -def verif_transfer(zephir_proxy, archive):
382 """vérifie la validité d'une archive recue et confirme sa réception à zephir""" 383 verif_archive = convert(zephir_proxy.uucp.get_checksum(config.id_serveur, u(archive))) 384 if verif_archive[0] == 0: 385 log('ZEPHIR', 1, 'erreur de récupération du checksum pour '+archive+'.tar') 386 return verif_archive 387 else: 388 md5string = xmlrpclib.base64.decodestring(verif_archive[1]) 389 f_md5 = open(public_dir+os.sep+archive+'.md5', 'w') 390 f_md5.write(md5string) 391 f_md5.close() 392 res = os.system('cd ' + public_dir + ' ; /usr/bin/md5sum -c ' + f_md5.name) 393 os.unlink(f_md5.name) 394 if res == 0: 395 # on informe zephir que le transfert s'est bien passé (rapport ?) 396 res = convert(zephir_proxy.uucp.confirm_transfer(config.id_serveur, u(archive))) 397 if res[0] == 1: 398 return 1, 'ok' 399 else: 400 #erreur de supression de l'archive sur zephir ? 401 return 1, res[1] 402 else: 403 # log('WARNING', 'checksum invalide pour '+archive+'.tar') 404 return 0, 'checksum invalide pour '+archive+'.tar'
405
406 -def mod_var_path(filepath):
407 """change un chemin de fichier pour insérer 'variante' """ 408 filepath = list(os.path.split(filepath)) 409 filepath.insert(1, 'variante') 410 return os.sep.join(filepath)
411 412
413 -def get_container_file(filepath):
414 try: 415 fpath, container = filepath.split('::') 416 cont_path = container_vars.get('container_path_%s' % container, '') 417 if cont_path: 418 return os.path.join(cont_path, fpath.lstrip(os.sep)) 419 else: 420 return fpath 421 except: 422 pass 423 # pas de container donné (--> container root) 424 return filepath
425
426 -def get_file_perms(base_dir, data_path, variante=False, filepath=""):
427 """renvoie les informations de permissions associées à un fichier 428 """ 429 data_dir = base_dir + os.sep + data_path 430 # lecture des informations sur le fichier si disponibles 431 if variante == True: 432 permsfile = base_dir + os.sep + 'droits_variante' 433 else: 434 permsfile = base_dir+os.sep+'droits_zephir' 435 if os.path.isfile(permsfile): 436 f_rights = file(permsfile) 437 data = f_rights.read().strip().split('\n') 438 f_rights.close() 439 else: 440 data = [] 441 mode = user = group = "" 442 recursive = False 443 if filepath != "": 444 if variante == True: 445 result = {mod_var_path(filepath):[mode, user, group, recursive]} 446 else: 447 result = {filepath:[mode, user, group, recursive]} 448 else: 449 result = {} 450 for line in data: 451 if line.startswith(filepath) or filepath == "": 452 if line.startswith(data_path): 453 try: 454 filename, mode, user, group, recursive = line.split('#') 455 if recursive != '': 456 recursive = eval(recursive) 457 if variante == True: 458 result[mod_var_path(filename)] = [mode, user, group, recursive] 459 else: 460 result[filename] = [mode, user, group, recursive] 461 if filepath != "": 462 break 463 except: 464 # fichier vide ? 465 pass 466 return result
467
468 -def sudo_script(cmd, log_prefix='ZEPHIR'):
469 res = os.system("sudo %s/scripts/%s 2>&1 >> /var/log/zephir/last_action.log" % (zephir_dir, cmd)) 470 if res != 0: 471 # log de l'erreur sur zephir (par défaut dans la rubrique divers) 472 log(log_prefix, 1, "Erreur lors de l'exécution du script %s" % cmd) 473 sys.exit(1)
474
475 -def register_log(zephir_proxy, id_serveur, eole_variables, ip_zlog=None, regen=False):
476 """ 477 mise en place d'un certificat pour envoi des logs centralisés si disponible 478 @zephir_proxy : objet xmlrpclib.ServeurProxy pour communiquer avec le 479 Zéphir. 480 @id_serveur : id du serveur qui s'enregistre 481 @eole_variables : dictionnaire contenant les chemins des certificats et clé, passés 482 en argument pour éviter de recharger le dictionnaire 483 @id_zlog (optionnel) : identifiant du ZéphirLog, si absent, on considère 484 que c'est un ZéphirLog qui s'enregistre. 485 """ 486 id_zlog = None 487 488 # Création d'une clé privée si elle n'existe pas 489 if regen or not os.path.isfile(eole_variables['rsyslog_privkey']): 490 gen_privkey(eole_variables['rsyslog_privkey']) 491 # TODO : gérer la révocation 492 request_data = {} 493 with open(rsyslog_request_template, 'r') as request_template_data: 494 request_template = xmlrpclib.base64.encodestring(request_template_data.read()) 495 request_data['template'] = request_template 496 if ip_zlog != None: 497 # on considère que c'est un client qui s'enregistre 498 # recherche du serveur zephirlog correspondant sur zephir 499 res, managers = zephir_proxy.prelude.get_managers('') 500 if res != 1: 501 print_red("Erreur lors de la récupération des serveurs ZéphirLog") 502 return False 503 if managers != {}: 504 id_zephirlog, ip_manager = select_manager(ip_zlog, managers, 'zephirlog') 505 if id_zephirlog == "": 506 print_orange("\nMise en place du certificat ZephirLogs ignoré\n\n") 507 return True 508 else: 509 if ip_zlog != ip_manager: 510 if not update_logs_conf(ip_manager): 511 print_red("""\nL'adresse ip du serveur zephirlog n'a pas pu être sauvegardée\n\n""") 512 return False 513 print_green("""\nNouvelle adresse ZephirLogs enregistrée dans la configuration : %s\n\n""" % ip_manager) 514 # mise en place de la CA du serveur ZephirLog sélectionné 515 request_content = gen_request(rsyslog_request_template, 516 eole_variables['rsyslog_privkey']) 517 request_content = xmlrpclib.base64.encodestring(request_content) 518 request_data['request'] = request_content 519 request_data['rsyslog'] = xmlrpclib.base64.encodestring("$InputTCPServerStreamDriverPermittedPeer {0}".format(eole_variables['serveur'])) 520 res, data = zephir_proxy.prelude.gen_certif(request_data, id_serveur, id_zephirlog) 521 if res != 1: 522 print_red("""\nErreur de récupération des certificats rsyslog sur Zephir.\n\n""") 523 return False 524 with open(eole_variables['rsyslog_ca'], 'w') as rsyslog_ca: 525 rsyslog_ca.write(xmlrpclib.base64.decodestring(data['ca_data'])) 526 print_green("\nCertificat racine enregistré sous %s\n\n" % eole_variables['rsyslog_ca']) 527 with open(eole_variables['rsyslog_cert'], 'w') as rsyslog_crt: 528 rsyslog_crt.write(xmlrpclib.base64.decodestring(data['cert_data'])) 529 print_green("\nCertificat rsyslog enregistré sous %s\n\n" % eole_variables['rsyslog_cert']) 530 if data.has_key('rsyslog_data'): 531 outgoing_dir = '/etc/rsyslog.d/outgoing_peers' 532 if not os.path.exists(outgoing_dir): 533 os.makedirs(outgoing_dir) 534 with open(os.path.join(outgoing_dir, 'tls.peers'), 'w') as rsyslog_conf: 535 rsyslog_conf.write(xmlrpclib.base64.decodestring(data['rsyslog_data'])) 536 else: 537 # on considère que c'est un ZéphirLog qui s'enregistre 538 request_content = gen_request(rsyslog_request_template, 539 eole_variables['rsyslog_privkey']) 540 request_data['request'] = xmlrpclib.base64.encodestring(request_content) 541 request_data['rsyslog'] = xmlrpclib.base64.encodestring("$ActionSendStreamDriverPermittedPeer {0}".format(eole_variables['serveur'])) 542 res, data = zephir_proxy.prelude.gen_certif(request_data, id_serveur) 543 with open(eole_variables['rsyslog_ca'], 'w') as rsyslog_ca: 544 rsyslog_ca.write(xmlrpclib.base64.decodestring(data['ca_data'])) 545 print_green("\nCertificat racine enregistré sous %s\n\n" % eole_variables['rsyslog_ca']) 546 with open(eole_variables['rsyslog_cert'], 'w') as rsyslog_crt: 547 rsyslog_crt.write(xmlrpclib.base64.decodestring(data['cert_data'])) 548 print_green("\nCertificat rsyslog enregistré sous %s\n\n" % eole_variables['rsyslog_cert']) 549 if data.has_key('rsyslog_data'): 550 incoming_dir = '/etc/rsyslog.d/incoming_peers' 551 if not os.path.exists(incoming_dir): 552 os.makedirs(incoming_dir) 553 with open(os.path.join(incoming_dir, 'tls.peers'), 'w') as rsyslog_conf: 554 rsyslog_conf.write(xmlrpclib.base64.decodestring(data['rsyslog_data'])) 555 return True
556 557
558 -def wait_for_port(addr, port, timeout = 20):
559 """attend qu'une connexion soit disponible sur une adresse/port 560 timeout : temps d'attente maximum avant d'abandonner (en secondes) 561 """ 562 sock_timeout = 3 563 run_time = 0 564 while run_time < timeout: 565 sock_test = socket.socket() 566 sock_test.settimeout(sock_timeout) 567 try: 568 sock_test.connect((addr, port)) 569 return True 570 except socket.timeout: 571 pass 572 except socket.error: 573 time.sleep(sock_timeout) 574 run_time += sock_timeout 575 return False
576
577 -def check_prelude_conf():
578 """récupère les options prelude définies dans la configuration creole 579 """ 580 ip_conf = '' 581 sondes = [] 582 try: 583 # si une adresse_ip est définie, on la propose par défaut 584 conf = EoleDict() 585 conf.read_dir(eoledirs) 586 conf.load_values('/etc/eole/config.eol') 587 try: 588 ip_conf = conf.get_value('adresse_ip_prelude_manager')[0] 589 except IndexError: 590 ip_conf = "" 591 if eole_module == 'zephirlogs': 592 print "** enregistrement prelude-lml" 593 sondes = ['prelude-lml'] 594 else: 595 for varname, var in conf.variables.items(): 596 if varname.startswith('sonde_') and var.get_final_value() == 'oui': 597 sondes.append(varname.replace('sonde_', '').replace('__', '-')) 598 print "** enregistrement ", varname.replace('sonde_', '').replace('__', '-') 599 except: 600 traceback.print_exc() 601 pass 602 return ip_conf, sondes
603
604 -def select_manager(ip_conf, managers, mgr_type = 'preludemanager'):
605 """propose le choix du manager sur lequel l'enregistrement doit s'effectuer 606 """ 607 # choix du manager 608 saisie_default = "" 609 choix = [""] 610 id_man = "" 611 ip_manager = "" 612 if ip_conf is not None: 613 ip_manager = ip_conf 614 # ip du manager donnée en paramètre, on recherche l'id correspondant 615 for id_manager, data_man in managers.items(): 616 ip_man = data_man[0] 617 libelle = data_man[1] 618 if ip_man == ip_conf: 619 id_man = id_manager 620 if id_man == "": 621 if ip_conf: 622 print_orange("\nLe serveur %s correspondant à l'ip %s n'a pas été trouvé." % (mgr_type, ip_conf)) 623 print "\nserveurs %s disponibles :\n" % mgr_type 624 id_default = "" 625 # si pas de manager spécifié, on propose un choix 626 for id_man in managers.keys(): 627 ip_man = managers[id_man][0] 628 libelle = managers[id_man][1] 629 choix.append(id_man) 630 print id_man, " -> ", ip_man, "(", libelle, ")" 631 id_man = "undef" 632 while id_man not in choix: 633 id_man = raw_input("\nIdentifiant du serveur %s à utiliser (rien pour ignorer) ? " % (mgr_type)) 634 if id_man != "": 635 ip_manager = managers[id_man][0] 636 return id_man, ip_manager
637
638 -def update_prelude_conf(ip_manager):
639 """met à jour la configuration creole du serveur et instancie les templates 640 nécessaires à l'enregistrement des sondes prelude 641 """ 642 # mise en place de la configuration 643 conf = EoleDict() 644 conf.read(os.path.join(eoleroot, 'dicos', '1_prelude.xml')) 645 prelude_files = conf.files 646 prelude_filelists = conf.filelists 647 # instanciation des fichier de configuration prelude 648 conf = EoleDict() 649 # on récupère les autres variables 650 conf.read_dir(eoledirs) 651 # on lit la configuration dans config.eol (ou zephir.eol si non instancié) 652 if os.path.isfile('/etc/eole/config.eol'): 653 conf.load_values('/etc/eole/config.eol') 654 else: 655 conf.load_values('/root/zephir.eol') 656 conf.set_value('adresse_ip_prelude_manager' , ip_manager) 657 saved = True 658 for conf_file in ['/etc/eole/config.eol', '/root/zephir.eol']: 659 if os.path.isfile(conf_file): 660 if not conf.save_values(conf_file): 661 saved = False 662 if saved: 663 # et on ne garde que les fichiers prelude 664 conf.files = prelude_files 665 conf.filelists = prelude_filelists 666 # instanciation des fichiers templates avec les valeurs chargées 667 try: 668 conf.instance() 669 except: 670 traceback.print_exc() 671 print '\n!! erreur de génération de la configuration prelude !!\n' 672 saved = False 673 return saved
674
675 -def update_logs_conf(ip_manager):
676 """met à jour la configuration creole du serveur 677 """ 678 # mise en place de la configuration 679 try: 680 conf = EoleDict() 681 conf.read(os.path.join(eoleroot, 'dicos', '1_logs.xml')) 682 # instanciation des fichier de configuration prelude 683 conf = EoleDict() 684 # on récupère les autres variables 685 conf.read_dir(eoledirs) 686 # on lit la configuration dans config.eol (ou zephir.eol si non instancié) 687 if os.path.isfile('/etc/eole/config.eol'): 688 conf.load_values('/etc/eole/config.eol') 689 else: 690 conf.load_values('/root/zephir.eol') 691 except: 692 print "Erreur à la lecture de la configuration du serveur" 693 return False 694 conf.set_value('adresse_ip_serveur_logs' , ip_manager) 695 saved = True 696 for conf_file in ['/etc/eole/config.eol', '/root/zephir.eol']: 697 if os.path.isfile(conf_file): 698 if not conf.save_values(conf_file): 699 saved = False 700 return saved
701
702 -def register_sonde(sonde, id_man, ip_manager, zephir_proxy):
703 retry = True 704 num_tries = 0 705 while retry: 706 retry = False 707 # lancement du serveur d'enregistrement à distance 708 code, pass_register = convert(zephir_proxy.prelude.register_server(id_man)) 709 if code == -1: 710 # si le serveur est déjà occupé, on attend au maximum 30 secondes (essai toutes les 5 secondes) 711 print "Un enregistrement est déjà en cours sur prelude-manager. nouvelle tentative dans 5 secondes..." 712 if num_tries < 6: 713 num_tries += 1 714 retry = True 715 time.sleep(4) 716 continue 717 else: 718 return False 719 elif code == 0: 720 return False 721 # attente de la dispo du serveur 722 print "Attente du lancement du serveur d'enregistrement sur prelude-manager" 723 conn_ok = wait_for_port(ip_manager, 5553) 724 # lancer adduser avec les paramêtres donnés 725 if conn_ok: 726 print " - enregistrement de la sonde %s" % sonde 727 options = get_options(zephir_dir) 728 if sonde in options: 729 permissions, uid, gid, services = options[sonde] 730 else: 731 permissions = "idmef:w admin:r" 732 uid = "root" 733 gid = "root" 734 services = [sonde] 735 cmd_register = '/usr/bin/prelude-admin register %s "%s" %s --uid %s --gid %s --passwd=%s 2>/dev/null' % (sonde, permissions, ip_manager, uid, gid, pass_register) 736 res = os.system(cmd_register) 737 if res != 0: 738 print "\terreur lors de l'enregistrement de %s \n\t(%s)" % (sonde, cmd_register) 739 else: 740 pass 741 res = os.system('/bin/chown %s.%s /etc/prelude/profile/%s/analyzerid' % (uid, gid, sonde)) 742 for serv in services: 743 print " - relance du service %s ..." % serv 744 service_out(serv, 'restart') 745 else: 746 print "\nserveur d'enregistrement non lancé ?" 747 return False 748 return True
749
750 -def register_prelude(zephir_proxy):
751 """mise en place de la configuration prelude si nécessaire""" 752 # recherche des managers disponibles 753 try: 754 ret_code, managers = convert(zephir_proxy.prelude.get_managers()) 755 except xmlrpclib.ProtocolError: 756 print("Vous n'êtes pas autorisé à utiliser les fonctionnalités prelude") 757 return False 758 except: 759 print "\n!! erreur de lecture de la configuration prelude sur zephir" 760 return False 761 if managers != {}: 762 ip_conf, sondes = check_prelude_conf() 763 id_man, ip_manager = select_manager(ip_conf, managers) 764 if id_man == "": 765 print_orange("\nEnregistrement auprès du serveur PreludeManager ignoré\n\n") 766 else: 767 if ip_manager != ip_conf: 768 if not update_prelude_conf(ip_manager): 769 print_red("""\nL'adresse ip du serveur PreludeManager n'a pas pu être sauvegardée\n\n""") 770 return False 771 else: 772 print_green("""\nNouvelle adresse PreludeManager enregistrée dans la configuration : %s\n\n""" % ip_manager) 773 # pour chaque sonde définie dans la configuration, on effectue un enregistrement (prelude-adduser) 774 err_sonde = False 775 for sonde in sondes: 776 if not register_sonde(sonde, id_man, ip_manager, zephir_proxy): 777 err_sonde = True 778 print_red ("\n Echec de l'enregistrement de la sonde %s sur le serveur Preludemanager (%s) \n\n" % (sonde, ip_manager)) 779 if err_sonde: 780 return False 781 return True
782
783 -def saisie(variable,message):
784 """effectue la saisie d'une variable en utilisant 785 une valeur par défaut si disponible 786 """ 787 try: 788 val_def = " (%s par défaut)" % defaults[variable] 789 except Exception,e: 790 val_def = "" 791 val = raw_input(message + val_def + " : ") 792 if val == "" and val_def != "": 793 return defaults[variable] 794 else: 795 return val
796 797 pppoe_int_template = """# zephir_client : template minimum pour montage d'une connexion pppoe 798 # loopback network interface 799 auto lo 800 iface lo inet loopback 801 802 # dsl provider 803 auto dsl-provider 804 iface dsl-provider inet ppp 805 pre-up /sbin/ifconfig %%pppoe_interface up 806 provider dsl-provider 807 808 auto %%pppoe_interface 809 iface %%pppoe_interface inet manual 810 """ 811 812 dsl_provider_template = """ 813 # Minimalistic default options file for DSL/PPPoE connections 814 815 noipdefault 816 defaultroute 817 replacedefaultroute 818 hide-password 819 noauth 820 persist 821 updetach 822 usepeerdns 823 user "%%pppoe_user" 824 """ 825
826 -def conf_network(use_pppoe=False):
827 828 def configure_dns(ip_dns): 829 """ 830 Vérification et configuration du serveur DNS 831 """ 832 testdns = (['/usr/bin/host', '-W2', '-tA', 'bp-eole.ac-dijon.fr', ip_dns]) 833 res = system_out(testdns) 834 if res[0] != 0: 835 print "le serveur DNS %s ne répond pas (%s)" % (ip_dns, res[1]) 836 return False 837 server_conf = "nameserver %s" % ip_dns 838 f_dns = open('/etc/resolv.conf', 'w') 839 f_dns.write(server_conf) 840 f_dns.close() 841 return True
842 843 # création d'une configuration réseau minimum 844 if not use_pppoe: 845 # connexion ethernet classique 846 ip_eth0 = mask_eth0 = gateway = "" 847 while ip_eth0 =="" or mask_eth0 == "" or gateway == "": 848 interf = saisie("interf","interface connectée sur l'extérieur") 849 ip_eth0 = saisie("ip_eth0","adresse_ip %s" % interf) 850 mask_eth0 = saisie("mask_eth0","masque de réseau pour %s" % interf) 851 gateway = saisie("gateway","adresse de la passerelle") 852 system_code(['/sbin/ifconfig', interf, ip_eth0, 'netmask', mask_eth0]) 853 system_code(['/sbin/route', 'add', 'default', 'gw', gateway, 'dev', interf]) 854 system_code(['/sbin/ifconfig', interf, 'up']) 855 dns_ok = False 856 while not dns_ok: 857 ip_dns = saisie("ip_dns", "adresse du serveur DNS (ou rien)") 858 if ip_dns == "" or configure_dns(ip_dns): 859 dns_ok = True 860 else: 861 if not eole_module.startswith("amon"): 862 exit_err("""La connexion par pppoe n'est gérée que sur les modules amon et amonecole""") 863 configs = {'pap-secrets':'/etc/ppp','chap-secrets':'/etc/ppp', 'dsl-provider':'/etc/ppp/peers'} 864 for tmpl in configs.keys(): 865 if not os.path.isfile(os.path.join(distrib_dir, tmpl)): 866 exit_err("""Fichier de configuration non présent : %s""" % tmpl) 867 interf_ppp = login_ppp = pass_ppp = mtu_ppp = "" 868 while interf_ppp == "" or login_ppp == "" or pass_ppp == "": 869 # connexion pppoe - saisie login/pwd et interface 870 interf_ppp = saisie("interf","interface utilisée pour la connexion pppoe") 871 mtu_ppp = saisie("mtu_ppp","MTU utilisé pour la connexion pppoe (facultatif)") 872 login_ppp = saisie("login_ppp", "utilisateur pour la connexion pppoe") 873 pass_ppp = getpass.getpass("mot de passe pour la connexion pppoe : ") 874 # mise en place des fichiers de configuration : pap(/chap)-secrets et dsl-provider 875 try: 876 for tmpl_name, dest_dir in configs.items(): 877 if tmpl_name == 'dsl-provider': 878 conf_data = dsl_provider_template 879 # gestion du MTU pour dls-provider 880 if mtu_ppp == "": 881 conf_data += 'pty "pppoe -I %s -T 80"' % (interf_ppp) 882 else: 883 conf_data += 'pty "pppoe -I %s -T 80 -m %s"' % (interf_ppp, mtu_ppp) 884 else: 885 tmpl = os.path.join(distrib_dir, tmpl_name) 886 conf_data = open(tmpl).read() 887 # remplacement des variables 888 conf_data = conf_data.replace("%%pppoe_user", login_ppp) 889 conf_data = conf_data.replace("%%pppoe_passwd", pass_ppp) 890 conf_data = conf_data.replace("%%pppoe_interface", interf_ppp) 891 # écriture du résultat dans sa destination 892 f_conf = open(os.path.join(dest_dir, tmpl_name), 'w') 893 f_conf.write(conf_data) 894 f_conf.close() 895 # fichier interfaces minimum 896 tmpl_name = "interfaces" 897 f_int = open('/etc/network/interfaces', 'w') 898 f_int.write(pppoe_int_template.replace("%%pppoe_interface", interf_ppp)) 899 f_int.close() 900 except: 901 exit_err("erreur de mise en place du fichier %s" % tmpl_name) 902 # lancement de la connexion ppp 903 print_orange("""\nRelance des services réseaux ...\n""") 904 if not service_code('networking', 'restart') == 0: 905 print_red("""Erreur au redémarrage du réseau""") 906
907 -def exit_err(msg):
908 print_red("\n\n%s\n\n" % msg) 909 sys.exit(1)
910