Utillisation de subprocess sans shell

This commit is contained in:
Gabriel Detraz 2017-06-13 01:42:15 +02:00 committed by root
parent 0db6c091aa
commit b38db69db5
2 changed files with 38 additions and 27 deletions

View File

@ -39,10 +39,10 @@ from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
import subprocess import subprocess
def apply(cmd): def apply(cmd):
return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) return subprocess.Popen(cmd, stdin=subprocess.PIPE)
def mac_from_ip(ip): def mac_from_ip(ip):
cmd = '/usr/sbin/arp -na %s' % ip cmd = ['/usr/sbin/arp','-na',ip]
p = apply(cmd) p = apply(cmd)
output, errors = p.communicate() output, errors = p.communicate()
if output is not None : if output is not None :
@ -52,19 +52,18 @@ def mac_from_ip(ip):
return None return None
def create_ip_set(): def create_ip_set():
command_to_execute = "sudo " + GENERIC_IPSET_COMMAND + " create " + IPSET_NAME + " hash:mac hashsize 1024 maxelem 65536" command_to_execute = ["sudo", "-n"] + GENERIC_IPSET_COMMAND.split() + ["create",IPSET_NAME,"hash:mac","hashsize","1024","maxelem","65536"]
apply(command_to_execute) apply(command_to_execute)
command_to_execute = "sudo " + GENERIC_IPSET_COMMAND + " flush " + IPSET_NAME command_to_execute = ["sudo", "-n"] + GENERIC_IPSET_COMMAND.split() + ["flush",IPSET_NAME]
apply(command_to_execute) apply(command_to_execute)
return return
def fill_ipset(): def fill_ipset():
all_machines = Machine.objects.filter(proprio__in=User.objects.filter(state=User.STATE_ACTIVE)) all_machines = Machine.objects.filter(proprio__in=User.objects.filter(state=User.STATE_ACTIVE))
file = open("/tmp/ipset_restore", 'w+') ipset = "%s\nCOMMIT\n" % '\n'.join(["add %s %s" % (IPSET_NAME, str(machine.mac_address)) for machine in all_machines])
file.write("%s\nCOMMIT\n" % '\n'.join(["add %s %s" % (IPSET_NAME, str(machine.mac_address)) for machine in all_machines])) command_to_execute = ["sudo", "-n"] + GENERIC_IPSET_COMMAND.split() + ["restore"]
file.close() process = apply(command_to_execute)
command_to_execute = "sudo " + GENERIC_IPSET_COMMAND + " restore < /tmp/ipset_restore" process.communicate(input=ipset.encode('utf-8'))
apply(command_to_execute)
return return
class iptables: class iptables:
@ -100,17 +99,18 @@ def gen_filter(ipt):
ipt.commit("filter") ipt.commit("filter")
return ipt return ipt
def gen_nat(ipt): def gen_nat(ipt, nat_active=True):
ipt.init_nat("PREROUTING") ipt.init_nat("PREROUTING")
ipt.init_nat("INPUT") ipt.init_nat("INPUT")
ipt.init_nat("OUTPUT") ipt.init_nat("OUTPUT")
ipt.init_nat("POSTROUTING") ipt.init_nat("POSTROUTING")
ipt.init_nat("CAPTIF", decision="-") if nat_active:
ipt.jump("nat", "PREROUTING", "CAPTIF") ipt.init_nat("CAPTIF", decision="-")
ipt.jump("nat", "POSTROUTING", "MASQUERADE") ipt.jump("nat", "PREROUTING", "CAPTIF")
if PORTAIL_ACTIVE: ipt.jump("nat", "POSTROUTING", "MASQUERADE")
ipt.add("nat", "-A CAPTIF -m set ! --match-set %s src -j DNAT --to-destination %s" % (IPSET_NAME, SERVER_SELF_IP)) if PORTAIL_ACTIVE:
ipt.jump("nat", "CAPTIF", "RETURN") ipt.add("nat", "-A CAPTIF -m set ! --match-set %s src -j DNAT --to-destination %s" % (IPSET_NAME, SERVER_SELF_IP))
ipt.jump("nat", "CAPTIF", "RETURN")
ipt.commit("nat") ipt.commit("nat")
return ipt return ipt
@ -132,10 +132,21 @@ def restore_iptables():
gen_nat(ipt) gen_nat(ipt)
gen_filter(ipt) gen_filter(ipt)
global_chain = ipt.nat + ipt.filter + ipt.mangle global_chain = ipt.nat + ipt.filter + ipt.mangle
file = open("/tmp/iptables_restore", 'w+') command_to_execute = ["sudo","-n","/sbin/iptables-restore"]
file.write(global_chain) process = apply(command_to_execute)
file.close() process.communicate(input=global_chain.encode('utf-8'))
apply("iptables-restore < /tmp/iptables_restore") return
def disable_iptables():
""" Insère une iptables minimaliste sans nat"""
ipt = iptables()
gen_mangle(ipt)
gen_filter(ipt)
gen_nat(ipt, nat_active=False)
global_chain = ipt.nat + ipt.filter + ipt.mangle
command_to_execute = ["sudo","-n","/sbin/iptables-restore"]
process = apply(command_to_execute)
process.communicate(input=global_chain.encode('utf-8'))
return return
class UserManager(BaseUserManager): class UserManager(BaseUserManager):
@ -256,11 +267,11 @@ class Machine(models.Model):
mac_address = MACAddressField(integer=False, unique=True) mac_address = MACAddressField(integer=False, unique=True)
def add_to_set(self): def add_to_set(self):
command_to_execute = "sudo " + GENERIC_IPSET_COMMAND + " add " + IPSET_NAME + " " + str(self.mac_address) command_to_execute = ["sudo", "-n"] + GENERIC_IPSET_COMMAND.split() + ["add",IPSET_NAME,str(self.mac_address)]
apply(command_to_execute) apply(command_to_execute)
def del_to_set(self): def del_to_set(self):
command_to_execute = "sudo " + GENERIC_IPSET_COMMAND + " del " + IPSET_NAME + " " + str(self.mac_address) command_to_execute = ["sudo", "-n"] + GENERIC_IPSET_COMMAND.split() + ["del",IPSET_NAME,str(self.mac_address)]
apply(command_to_execute) apply(command_to_execute)
@receiver(post_save, sender=Machine) @receiver(post_save, sender=Machine)

View File

@ -40,7 +40,7 @@ from django.db import transaction
from reversion.models import Version from reversion.models import Version
from reversion import revisions as reversion from reversion import revisions as reversion
from users.models import User, MachineForm, Request from users.models import User, MachineForm, Request
from users.models import EditInfoForm, InfoForm, BaseInfoForm, Machine, StateForm, mac_from_ip, apply from users.models import EditInfoForm, InfoForm, BaseInfoForm, Machine, StateForm, mac_from_ip
from users.forms import PassForm, ResetPasswordForm from users.forms import PassForm, ResetPasswordForm
import ipaddress import ipaddress
import subprocess import subprocess
@ -272,10 +272,10 @@ def capture_mac(request, users, verbose=True):
messages.error(request, "Assurez-vous que la machine n'est pas déjà enregistrée") messages.error(request, "Assurez-vous que la machine n'est pas déjà enregistrée")
else: else:
if verbose: if verbose:
messages.error(request, "Impossible d'enregistrer la machine") messages.error(request, "Impossible d'enregistrer la machine")
else: else:
if verbose: if verbose:
messages.error(request, "Merci de vous connecter sur le réseau du portail captif pour capturer la machine (WiFi %s)" % CAPTIVE_WIFI) messages.error(request, "Merci de vous connecter sur le réseau du portail captif pour capturer la machine (WiFi %s)" % CAPTIVE_WIFI)
def capture_mac_afterlogin(sender, user, request, **kwargs): def capture_mac_afterlogin(sender, user, request, **kwargs):
capture_mac(request, user, verbose=False) capture_mac(request, user, verbose=False)
@ -301,14 +301,14 @@ def reset_password(request):
user = User.objects.get(pseudo=userform.cleaned_data['pseudo'],email=userform.cleaned_data['email']) user = User.objects.get(pseudo=userform.cleaned_data['pseudo'],email=userform.cleaned_data['email'])
except User.DoesNotExist: except User.DoesNotExist:
messages.error(request, "Cet utilisateur n'existe pas") messages.error(request, "Cet utilisateur n'existe pas")
return form({'userform': userform}, 'users/user.html', request) return form({'userform': userform}, 'users/user.html', request)
req = Request() req = Request()
req.type = Request.PASSWD req.type = Request.PASSWD
req.user = user req.user = user
req.save() req.save()
reset_passwd_mail(req, request) reset_passwd_mail(req, request)
messages.success(request, "Un mail pour l'initialisation du mot de passe a été envoyé") messages.success(request, "Un mail pour l'initialisation du mot de passe a été envoyé")
redirect("/") redirect("/")
return form({'userform': userform}, 'users/user.html', request) return form({'userform': userform}, 'users/user.html', request)
def process(request, token): def process(request, token):