ఆటో ప్రొవిజనింగ్ Yealink T19 + డైనమిక్ అడ్రస్ బుక్

నేను ఈ సంస్థ కోసం పని చేయడానికి వచ్చినప్పుడు, నేను ఇప్పటికే IP పరికరాల యొక్క కొంత డేటాబేస్, నక్షత్రం గుర్తుతో అనేక సర్వర్లు మరియు FreeBPX రూపంలో ఒక ప్యాచ్‌ని కలిగి ఉన్నాను. అదనంగా, ఒక అనలాగ్ 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')

ప్రోగ్రామ్ వినియోగదారు కంప్యూటర్‌లో నడుస్తుంది మరియు యెలింక్ 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

ఇక్కడ మేము స్కేపీ ఫ్రేమ్‌వర్క్ నుండి స్నిఫ్ ఫంక్షన్‌ను ఉపయోగిస్తాము, దాని సహాయంతో మేము ముందుగా నిర్ణయించిన udp ప్యాకెట్‌ను అందుకుంటాము, 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, వినియోగదారు పేరు.

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 కూడా వాటిని కలిగి ఉంది.

PS: ఎక్కువ స్కేలబిలిటీ కోసం, మీరు ప్రధాన సెట్టింగ్‌లను (వేరియబుల్స్) ప్రత్యేక ఫైల్‌లోకి తరలించవచ్చు.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి