خودڪار روزي Yealink T19 + متحرڪ پتو ڪتاب

جڏهن آئون هن ڪمپني لاءِ ڪم ڪرڻ لاءِ آيو آهيان، مون وٽ اڳ ۾ ئي IP ڊوائيسز جو ڪجهه ڊيٽابيس، ڪيترن ئي سرورن سان ستارن ۽ فري بي پي ايڪس جي صورت ۾ هڪ پيچ موجود هو. ان کان سواء، هڪ اينالاگ PBX Samsung 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

هتي اسان اسڪيپي فريم ورڪ مان سنيف فنڪشن استعمال ڪريون ٿا، ان جي مدد سان اسان کي اڳواٽ مقرر ڪيل يو ڊي پي پيڪٽ ملي ٿو، 70 سيڪنڊن جو انتظار ڪريو ۽ جيڪڏهن اسان ڪجھ به نه پڪڙيو ته ٻاهر نڪرنداسين.

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

اڳيون، اسان پڪ ڪريون ٿا ته ڊوائيس واقعي Yealink آهي ۽ ضروري قدر واپس آڻيو (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، username.

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 طور محفوظ ڪندا آهيون. اهو آهي، Yealink لاءِ ٻه قسم جون ترتيبون آهن، هڪ عالمي آهي، ۽ ٻيو هڪ مخصوص فون تي لاڳو ٿئي ٿو ۽ فارم جو هجڻ گهرجي 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 ۽ ٿورو PHP شامل ڪرڻ آهي. اهڙا ڪيترائي مثال آهن، جيتوڻيڪ YEALINK پاڻ وٽ آهن.

پي ايس: وڏي پيماني تي، توهان مکيه سيٽنگون (متغير) کي الڳ فائل ۾ منتقل ڪري سگهو ٿا.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو