د اتوماتیک چمتو کول ییلینک T19 + متحرک پته کتاب

کله چې زه د دې شرکت لپاره کار کولو ته راغلم، ما دمخه د IP وسیلو ځینې ډیټابیس درلود، د ستوري سره څو سرورونه او د FreeBPX په بڼه یو پیچ. برسېره پردې، یو انلاګ PBX سیمسنگ IDCS500 په موازي توګه کار کاوه او په عموم کې، په شرکت کې د مخابراتو اصلي سیسټم و؛ IP ټیلیفوني یوازې د پلور څانګې لپاره کار کاوه. او هر څه به همداسې پخولو ته دوام ورکړي، مګر یوه ښه ورځ یو فرمان ورکړل شو چې هرچا ته IP ټیلیفون ته لیږدول کیږي، د مهال ویش موافقه وشوه، تجهیزات اخیستل شوي، او 21 پیړۍ ته د تصدۍ لیږدولو پلان پلي کول پیل شول.
لومړی شی چې په داسې حالت کې اندیښنه پیل کوي د تلیفون سیټونو ګړندۍ وده ده چې باید یو څه اداره شي ، دوهم شی چې خورا اندیښنه وه د تلیفون کتاب و. که د پای ټکي مدیر له موږ سره د لومړي سره مرسته وکړي (کوم چې په لاره کې د FreePBX وروستي نسخو څخه قطع شوی و) ، بیا د کتاب سره ځینې پوښتنې راپورته شوې:

  • لومړی، څنګه د دې دقت ډاډ ترلاسه کړئ کله چې د کاروونکو موقعیت/روغتیا په دوامداره توګه بدلیږي؟
  • دوهم، د تلیفونونو په بشپړه توګه بې ځایه کولو څرنګوالی. او هر وخت د تماس نوم نه ډکوي؟

ستونزه په زړه پورې وه، حل ډیر وخت نه و رسیدلی. اوس به زه بشپړ لیست درکړم، او بیا به موږ په ترتیب سره وګورو.

from scapy.all import sniff
from scapy.layers.inet import IP
import mysql.connector
import ldap
import getpass
import tftpy
import requests
import os
import time
from string import replace

def conn_ldap(login):
    ad = ldap.initialize('ldap://***.local')
    ad.simple_bind_s('voip@***.local', 'password')
    basedn = 'OU=IT,DC=***,DC=LOCAL'
    basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL'
    scope = ldap.SCOPE_SUBTREE
    filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))"
    filterexp2 = "(&(ObjectClass=organizationUnit))"
    attrlist = ['cn']
    attrlist2 = ['OU']
    search = ad.search_s(basedn, scope, filterexp, attrlist)
    adname = search[0][1]['cn'][0].decode('utf-8')
    if adname == ' ':
        search = ad.search_s(basedn_user, scope, filterexp2, attrlist2)
        for i in range(1, len(search)+1):
            group = search[i][1]['ou'][0]
            basedn_user2 = 'OU='+group+','+basedn_user
            search = ad.search_s(basedn_user2, scope, filterexp, attrlist)
            adname = search[0][1]['cn'][0].decode('utf-8')
            if adname != ' ':
                return adname
        adname = search[0][1]['cn'][0].decode('utf-8')
    ad.unbind_s()
    return adname


def tftp_file_change(config,place,adname,current_account,current_account_password):

    client = tftpy.TftpClient("192.168.0.3", 69)
    client.download('template.cfg', place)
    fileread = open(place, 'r')
    line = fileread.readlines()
    fileread.close()
    line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + 'n')
    line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + 'n')
    filewrite = open(place, 'w')
    for i in line:
      filewrite.write(i)
    filewrite.close()
    print place
    print config
    client.upload(config,place)


def get_phone_inform(ipaddr):
    fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]')
    conf = fileconf.text.split('|')
    current_account = conf[2]
    return current_account


def sniff_frame():
    pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060")
    if len(pcapf) == 0:
        exit()
    frame = pcapf[0]
    macaddr = frame.src
    print macaddr[:8]
    if macaddr[:8] != '80:5e:c0':
        exit()
    ipaddr = frame[0][IP].src
    return macaddr, ipaddr


def conn_mysql(query,fquery,macaddr,qwery2):
    connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***')
    cursor = connect.cursor()
    cursor.execute(fquery)
    state = cursor.fetchall()
    state = bool(state[0][0])
    if state == True:
        cursor.execute(qwery2)
        connect.commit()
        connect.close()
    else:
        cursor.execute(query)
        connect.commit()
        connect.close()


def check_account(current_account):
    connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***')
    cursor = connect.cursor()
    qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";'
    cursor.execute(qwery)
    password = cursor.fetchall()
    if password == ' ':
        exit()
    else:
        return password


if __name__ == '__main__':
    macaddr, ipaddr = sniff_frame()
    current_account = get_phone_inform(ipaddr)
    current_account_password = check_account(current_account)
    macaddr = macaddr.replace(':', '')
    ipaddr = ipaddr.decode('utf-8')
    adname = conn_ldap(getpass.getuser())
    query = 'INSERT INTO station (mac, ip, name, number) VALUES (' + '"' + macaddr + '",' + '"' + ipaddr + '",' + '"' + adname + '",' + '"' + get_phone_inform(ipaddr) + '"' + ')'
    qwery2 = 'UPDATE station SET ip=' + '"' + ipaddr + '"' + ', name=' + '"' + adname + '"' + ', number=' + '"' + get_phone_inform(ipaddr) + '"' + ' WHERE mac=' + '"' + macaddr + '"'
    fquery = 'SELECT EXISTS(SELECT mac FROM voip.station WHERE mac=' + '"' + macaddr + '")'
    query = query.encode('utf-8')
    fquery = fquery.encode('utf-8')
    config = macaddr + '.cfg'
    place = os.path.expanduser("~") + "" + "AppDataLocal" + config
    conn_mysql(query,fquery,macaddr,qwery2)
    tftp_file_change(config,place,adname,current_account,current_account_password)
    requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP')
    requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot')

برنامه د کارونکي کمپیوټر پرمخ ځي او په دې شرط کار کوي چې کمپیوټر د تلیفون له لارې شبکې سره وصل وي ، ځکه چې Yealink T19 نشي کولی د دروازې په توګه کار وکړي.

لومړی، موږ باید پوه شو چې ایا دا تړلی دی؟ او زموږ تلیفون څه میک او آی پی لري.

def sniff_frame():
    pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060")
    if len(pcapf) == 0:
        exit()
    frame = pcapf[0]
    macaddr = frame.src
    print macaddr[:8]
    if macaddr[:8] != '80:5e:c0':
        exit()
    ipaddr = frame[0][IP].src
    return macaddr, ipaddr

دلته موږ د scapy چوکاټ څخه د سنیف فنکشن کاروو، د هغې په مرسته موږ د مخکې ټاکل شوي udp کڅوړه ترلاسه کوو، 70 ثانیې انتظار وکړئ او که موږ هیڅ شی ونه نیول، موږ وځو.

count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060"

بیا، موږ ډاډ ترلاسه کوو چې وسیله واقعیا ییلینک ده او اړین ارزښتونه بیرته راګرځوي (ip او mac).

د ځانګړي غوښتنې په کارولو سره ، موږ په تلیفون کې اوسنی حساب ومومئ. د دې کولو لپاره، اوسنی ترتیب د تلیفون څخه ډاونلوډ شوی او پارس شوی.

def get_phone_inform(ipaddr):
    fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]')
    conf = fileconf.text.split('|')
    current_account = conf[2]
    return current_account

د دې حساب لپاره پټنوم ومومئ. د دې کولو لپاره، موږ د asterisk.sip جدول او په دې کې د معلوماتو ساحې ته مخه کوو.

def check_account(current_account):
    connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***')
    cursor = connect.cursor()
    qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";'
    cursor.execute(qwery)
    password = cursor.fetchall()
    if password == ' ':
        exit()
    else:
        return password

ښه، د وروستي مرحلې لپاره موږ د ldap AD سره وصل کوو او د فنکشن له لارې ترلاسه شوي sAMAccountName په کارولو سره getpass.getuser() د اوسني کارونکي cn واخلئ (کوم چې معمولا د کارونکي بشپړ نوم لري).

def conn_ldap(login):
    ad = ldap.initialize('ldap://***.local')
    ad.simple_bind_s('voip@***.local', 'password')
    basedn = 'OU=***,DC=***,DC=LOCAL'
    basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL'
    scope = ldap.SCOPE_SUBTREE
    filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))"
    filterexp2 = "(&(ObjectClass=organizationUnit))"
    attrlist = ['cn']
    attrlist2 = ['OU']
    search = ad.search_s(basedn, scope, filterexp, attrlist)
    adname = search[0][1]['cn'][0].decode('utf-8')
    if adname == ' ':
        search = ad.search_s(basedn_user, scope, filterexp2, attrlist2)
        for i in range(1, len(search)+1):
            group = search[i][1]['ou'][0]
            basedn_user2 = 'OU='+group+','+basedn_user
            search = ad.search_s(basedn_user2, scope, filterexp, attrlist)
            adname = search[0][1]['cn'][0].decode('utf-8')
            if adname != ' ':
                return adname
        adname = search[0][1]['cn'][0].decode('utf-8')
    ad.unbind_s()
    return adname

موږ په ډیټابیس کې له مخکې جوړ شوي جدول سره وصل کیږو (ما دا هلته رامینځته کړی) او هرڅه چې موږ زده کړل دننه کوو، یعنې: ip، mac، کارن نوم.

def conn_mysql(query,fquery,macaddr,qwery2):
    connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***')
    cursor = connect.cursor()
    cursor.execute(fquery)
    state = cursor.fetchall()
    state = bool(state[0][0])
    if state == True:
        cursor.execute(qwery2)
        connect.commit()
        connect.close()
    else:
        cursor.execute(query)
        connect.commit()
        connect.close()

موږ کولی شو دلته ودریږو، ځکه چې موږ دمخه یو متحرک پته کتاب جوړ کړی، تاسو ممکن پوښتنه وکړئ، مګر زه نور لاړم او دلته د وسایلو اتوماتیک چمتو کول اضافه کړل.

د دې کولو لپاره، د ټیمپلیټ ترتیب د مخکې ترتیب شوي tftp سرور څخه ډاونلوډ کیږي، په کوم کې چې موږ خپل بدلونونه کوو او د mac.cfg په توګه یې خوندي کوو. دا دی، د ییلینک لپاره دوه ډوله تشکیلات شتون لري، یو نړیوال دی، او دویم په ځانګړي تلیفون کې پلي کیږي او باید د mac_phone.cfg بڼه ولري.

په فایل کې د ټولو بدلونونو وروسته او دا بیرته د tftp سرور ته خوندي کول، موږ تلیفون ته امر ورکوو چې وسیله چمتو او ریبوټ کړي.

def tftp_file_change(config,place,adname,current_account,current_account_password):

    client = tftpy.TftpClient("192.168.0.3", 69)
    client.download('template.cfg', place)
    fileread = open(place, 'r')
    line = fileread.readlines()
    fileread.close()
    line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + 'n')
    line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + 'n')
    filewrite = open(place, 'w')
    for i in line:
      filewrite.write(i)
    filewrite.close()
    print place
    print config
    client.upload(config,place)

requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP')
requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot')

د وسیلې له ریبوټ کولو وروسته ، موږ خپل بشپړ نوم د تلیفون سکرین کې ترلاسه کوو + د ډیټابیس په شکل کې تل په سمه توګه ډک شوی پته کتاب ، بیا ټول هغه څه چې پاتې دي د XML او یو څه پی ایچ پی اضافه کول دي ترڅو مینځپانګه په متحرک ډول ښکاره کړي. داسې ډیری مثالونه شتون لري، حتی YEALINK پخپله دوی لري.

PS: د لوی توزیع کولو لپاره ، تاسو کولی شئ اصلي تنظیمات (متغیرونه) په جلا فایل کې حرکت وکړئ.

سرچینه: www.habr.com

Add a comment