Hāʻawi kaʻa iā Yealink T19 + puke leka uila

I koʻu hele ʻana mai e hana no kēia ʻoihana, ua loaʻa iaʻu kahi waihona o nā polokalamu IP, nā kikowaena me ka asterisk a me kahi patch ma ke ʻano o FreeBPX. Eia kekahi, ua hana like kahi analogue PBX Samsung IDCS500 a, ma ka laulā, ʻo ia ka ʻōnaehana kamaʻilio koʻikoʻi i ka hui; Ua hana wale ke kelepona IP no ka ʻoihana kūʻai. A e hoʻomau nā mea a pau e kuke e like me kēia, akā i kekahi lā maikaʻi ua hāʻawi ʻia kahi kauoha e hoʻololi i nā mea a pau i ke kelepona IP, ua ʻae ʻia nā lā palena, ua kūʻai ʻia nā lako, a ua hoʻomaka ka hoʻolālā e hoʻololi i ka ʻoihana i ke kenekulia 21st.
ʻO ka mea mua e hoʻomaka ai e hopohopo i kēlā ʻano kūlana ʻo ia ka ulu wikiwiki ʻana o nā kelepona kelepona e pono e mālama ʻia i kekahi ʻano, ʻo ka lua o ka mea hopohopo nui ʻo ia ka puke kelepona. Inā hiki iā Endpoint Manager ke kōkua iā mākou me ka mea mua (ʻo ia, ma ke ala, ua ʻoki ʻia mai nā mana hou o FreePBX), a laila ua kū mai kekahi mau nīnau me ka puke:

  • ʻO ka mea mua, pehea e hōʻoia ai i kona pololei i ka wā e loli mau ai ka wahi/fluidity o nā mea hoʻohana?
  • ʻO ka lua, pehea e hoʻopau pono ai i nā kelepona. A ʻaʻole hoʻopiha i ka inoa pili i kēlā me kēia manawa?

Ua hoihoi ka pilikia, ʻaʻole i lōʻihi ka hōʻea ʻana mai. I kēia manawa e hāʻawi wau i ka papa inoa piha, a laila e nānā mākou ma ke ʻano.

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

Holo ka polokalamu ma ka lolouila o ka mea hoʻohana a hana ʻia inā pili ka lolouila i ka pūnaewele ma o ke kelepona, ʻoiai ʻaʻole hiki iā Yealink T19 ke hana ma ke ʻano he ʻīpuka.

ʻO ka mea mua, pono mākou e hoʻomaopopo inā pili ia? a he aha ka mac a me ka ip o kā mākou kelepona.

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

Maanei mākou e hoʻohana ai i ka hana sniff mai ka scapy framework, me kāna kōkua e loaʻa iā mākou kahi ʻeke udp i koho mua ʻia, kali 70 kekona a inā ʻaʻole mākou e hopu i kekahi mea, haʻalele mākou.

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

A laila, ʻike mākou ʻo Yealink maoli ka hāmeʻa a hoʻihoʻi i nā waiwai pono (ip a me mac).

Ke hoʻohana nei i kahi noi kūikawā, ʻike mākou i ka moʻokāki o kēia manawa ma ke kelepona. No ka hana ʻana i kēia, hoʻoiho ʻia ka hoʻonohonoho o kēia manawa mai ke kelepona a paʻi ʻia.

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

E ʻike i ka ʻōlelo huna no kēia moʻokāki. No ka hana ʻana i kēia, huli mākou i ka papa asterisk.sip a me ka kahua ʻikepili i loko.

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

ʻAe, no ka pae hope e hoʻopili mākou iā ldap AD a me ka hoʻohana ʻana i sAMAccountName i loaʻa ma o ka hana getpass.getuser() e lawe i ka cn o ka mea hoʻohana i kēia manawa (ʻo ia ka mea maʻamau ka inoa piha o ka mea hoʻohana).

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

Hoʻopili mākou i kahi papa i hana mua ʻia ma ka waihona (ua hana wau ma laila) a hoʻokomo i nā mea āpau a mākou i aʻo ai, ʻo ia hoʻi: 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()

Hiki iā mākou ke kū ma ʻaneʻi, no ka mea, ua hana mua mākou i kahi puke leka uila, e nīnau paha ʻoe, akā ua hele hou wau a hoʻohui i ka hāʻawi ʻana i nā polokalamu ma aneʻi.

No ka hana ʻana i kēia, hoʻoiho ʻia kahi hoʻonohonoho hoʻohālikelike mai kahi kikowaena tftp i hoʻonohonoho mua ʻia, kahi mākou e hoʻololi ai a mālama iā ia ma mac.cfg. ʻO ia hoʻi, no Yealink aia ʻelua ʻano hoʻonohonoho hoʻonohonoho, hoʻokahi honua, a pili ka lua i kahi kelepona kikoʻī a pono ke ʻano mac_phone.cfg

Ma hope o nā hoʻololi a pau o ka faila a mālama iā ia i ka server tftp, hāʻawi mākou i ke kauoha i ke kelepona e hoʻolako a hoʻomaka hou i ka hāmeʻa.

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

Ma hope o ka hoʻihoʻi hou ʻana i ka hāmeʻa, loaʻa iā mākou ko mākou inoa piha ma ka ʻaoʻao kelepona + kahi puke kikoʻī i hoʻopiha mau ʻia ma ke ʻano o kahi waihona, a laila ʻo nā mea a pau e hoʻohui i ka XML a me kahi PHP liʻiliʻi e hōʻike ikaika i ka ʻike. Nui nā hiʻohiʻona like, ʻo YEALINK ponoʻī iā lākou.

PS: No ka scalability ʻoi aʻe, hiki iā ʻoe ke hoʻoneʻe i nā hoʻonohonoho nui (nā hoʻololi) i kahi faila ʻokoʻa.

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka