Tanadin atomatik Yealink T19 + littafin adireshi mai ƙarfi

Lokacin da na zo aiki don wannan kamfani, na riga na sami wasu bayanan na'urorin IP, sabobin da yawa masu alamar alama da faci a cikin nau'in FreeBPX. Bugu da kari, wani analog PBX Samsung IDCS500 yayi aiki a layi daya kuma, gabaɗaya, shine babban tsarin sadarwa a cikin kamfanin; telephony na IP yayi aiki ne kawai don sashen tallace-tallace. Kuma da komai ya ci gaba da dahuwa haka, amma wata rana mai kyau aka ba da umarnin a tura kowa zuwa wayar IP, aka amince da ranar ƙarshe, aka sayo kayan aiki, aka fara aiwatar da shirin canja wurin kasuwancin zuwa ƙarni na 21.
Abu na farko da ya fara damuwa a cikin irin wannan yanayi shi ne yadda na'urorin wayar tarho ke karuwa da sauri wanda ke buƙatar sarrafa ko ta yaya, abu na biyu da ya dame shi sosai shine littafin waya. Idan Manajan Ƙarshen Ƙarshen zai iya taimaka mana da na farko (wanda, a hanya, an yanke shi daga sababbin sigogin FreePBX), to, wasu tambayoyi sun taso tare da littafin:

  • Da fari dai, ta yaya za a tabbatar da daidaito lokacin da wurin / ruwar masu amfani ke canzawa akai-akai?
  • Na biyu, yadda ake kawar da wayoyi gaba daya. Kuma ba cika sunan lamba kowane lokaci?

Matsalar ta kasance mai ban sha'awa, maganin bai dauki lokaci mai tsawo ba. Yanzu zan ba da cikakken jeri, sa'an nan kuma mu duba shi a cikin tsari.

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')

Shirin yana gudana akan kwamfutar mai amfani kuma yana aiki idan an haɗa kwamfutar da hanyar sadarwa ta waya, tun da Yealink T19 ba zai iya aiki a matsayin ƙofa ba.

Da farko, muna bukatar mu fahimci ko an haɗa shi? kuma menene mac da ip wayar mu.

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

Anan muna amfani da aikin sniff daga tsarin scapy, tare da taimakonsa muna karɓar fakitin udp da aka ƙaddara, jira 70 seconds kuma idan ba mu kama wani abu ba, mu fita.

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

Na gaba, muna tabbatar da cewa na'urar ita ce Yealink kuma ta dawo da mahimman ƙimar (ip da mac).

Yin amfani da buƙatun musamman, muna gano asusun yanzu akan wayar. Don yin wannan, ana zazzage tsarin na yanzu daga wayar kuma ana yin nazari.

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

Nemo kalmar sirri don wannan asusun. Don yin wannan, za mu juya zuwa tebur asterisk.sip da filin bayanai a ciki.

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

Da kyau, don mataki na ƙarshe muna haɗi zuwa ldap AD kuma muna amfani da sAMAccountName da aka samu ta hanyar aikin getpass.getuser() ɗauki cn na mai amfani na yanzu (wanda yawanci ya ƙunshi cikakken sunan mai amfani).

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

Muna haɗi zuwa tebur da aka riga aka ƙirƙira a cikin bayanan (Na ƙirƙira shi a can) kuma shigar da duk abin da muka koya, wato: 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()

Za mu iya tsayawa a nan, saboda mun riga mun ƙirƙiri littafin adireshi mai ƙarfi, kuna iya tambaya, amma na ci gaba da ƙara samar da na'urori ta atomatik a nan.

Don yin wannan, ana zazzage tsarin samfuri daga sabar tftp da aka riga aka tsara, inda muke yin canje-canjenmu kuma mu adana shi azaman mac.cfg. Wato, ga Yealink akwai nau'ikan tsari guda biyu, ɗaya na duniya ne, na biyu kuma ya shafi takamaiman waya kuma yakamata ya kasance ta hanyar mac_phone.cfg.

Bayan duk canje-canje a cikin fayil ɗin kuma adana shi zuwa uwar garken tftp, muna ba da umarni ga wayar don samarwa da sake kunna na'urar.

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')

Bayan sake kunna na'urar, muna samun cikakken sunan mu akan allon wayar + littafin adireshi koyaushe yana cika daidai a cikin nau'in bayanan bayanai, to abin da ya rage shine ƙara XML da ƙaramin PHP don nuna abubuwan da ke ciki a hankali. Akwai da yawa irin waɗannan misalai, ko da ita kanta YEALINK tana da su.

PS: Don ƙarin haɓakawa, zaku iya matsar da manyan saitunan (masu canzawa) zuwa fayil ɗin daban.

source: www.habr.com

Add a comment