Вақте ки ман барои кор ба ин ширкат омадам, ман аллакай якчанд пойгоҳи додаҳои дастгоҳҳои IP, якчанд серверҳо бо ситорача ва патч дар шакли FreeBPX доштам. Илова бар ин, аналогии PBX Samsung IDCS500 мувозӣ кор мекард ва дар маҷмӯъ системаи асосии алоқа дар ширкат буд, IP телефония танҳо барои шӯъбаи фурӯш кор мекард. Ва ҳама чиз ҳамин тавр пухтан мебуд, аммо як рӯзи хуб фармон дода шуд, ки ҳама ба IP-телефония гузаранд, мӯҳлатҳо мувофиқа карда шуданд, таҷҳизот харидорӣ карда шуданд ва нақшаи интиқоли корхона ба асри 21 амалӣ карда шуд.
Аввалин чизе, ки дар чунин вазъ боиси нигаронӣ мегардад, шумораи зуд афзоишёбандаи телефонҳо мебошад, ки бояд бо ягон роҳ идора карда шаванд, чизи дуюм, ки хеле ташвишовар буд, дафтарчаи телефонӣ буд. Агар Менеҷери Endpoint метавонад дар версияи аввал ба мо кӯмак кунад (воқеан, он аз версияҳои охирини 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 наметавонад ҳамчун дарвоза кор кунад.
Аввалан, мо бояд фаҳмем, ки оё он пайваст аст? ва телефони мо чӣ mac ва ip дорад.
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
Дар ин ҷо мо функсияи sniff-ро аз чаҳорчӯбаи scapy истифода мебарем, бо ёрии он мо бастаи 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: Барои миқёспазирии бештар, шумо метавонед танзимоти асосиро (тағйирёбандаҳо) ба файли алоҳида интиқол диҳед.
Манбаъ: will.com