Спрашчаем працу з Check Point API з дапамогай Python SDK
Уся моц узаемадзеяння з API расчыняецца пры сумесным выкарыстанні з праграмным кодам, калі з'яўляюцца магчымасці дынамічна фармаваць API запыты і прылады для аналізу API адказаў. Аднак, малапрыкметным да гэтага часу застаецца Набор для распрацоўкі праграмнага забеспячэння Python (далей – Python SDK) для Check Point Management API, а дарма. Ён адчувальна спрашчае жыццё распрацоўшчыкам і аматарам аўтаматызацыі. Python набыў велізарную папулярнасць у апошні час і я вырашыў ухіліць прабел і зрабіць агляд асноўных магчымасцяў Check Point API Python Development Kit. Дадзены артыкул служыць выдатным дадаткам іншага артыкула на Хабры Check Point R80.10 API. Упраўленне праз CLI, скрыпты і не толькі. Мы ж разгледзім як напісаць скрыпты з выкарыстаннем Python SDK і спынімся падрабязней на новым функцыянале Management API у версіі 1.6 (падтрымліваецца пачынальна з R80.40). Для разумення артыкула спатрэбяцца базавыя веды па працы з API і Python.
Check Point актыўна развівае API і на дадзены момант на свет з'явіліся:
Python SDK на дадзены момант падтрымлівае ўзаемадзеянне толькі з Management API і Gaia API. Мы разгледзім найважнейшыя класы, метады і зменныя ў дадзеным модулі.
Ўстаноўка модуля
модуль cpapi усталёўваецца хутка і проста з афіцыйнага рэпазітара Check Point на github з дапамогай зярнятка. Падрабязная інструкцыя па ўстаноўцы ёсць у README.md. Гэты модуль адаптаваны для працы з версіямі Python 2.7 і 3.7. У дадзеным артыкуле прыклады будуць прыведзены з выкарыстаннем Python 3.7. Аднак, Python SDK можна запускаць прама з сервера кіравання Check Point (Smart Management), але на іх падтрымліваецца толькі версія Python 2.7, таму ў апошняй частцы будзе прыведзены код для версіі 2.7. Адразу пасля ўстаноўкі модуля рэкамендую паглядзець на прыклады ў дырэкторыях examples_python2 и examples_python3.
Пачатак працы
Для таго каб у нас з'явілася магчымасць працаваць з кампанентамі модуля cpapi неабходна імпартаваць з модуля cpapi як мінімум два неабходныя класы:
APIClient и APIClientArgs
from cpapi import APIClient, APIClientArgs
Клас APIClientArgs адказвае за параметры падлучэння да API сервера, а клас APIClient адказвае за ўзаемадзеянне з API.
Вызначаем параметры падключэння
Каб вызначыць розныя параметры падлучэння да API, трэба стварыць асобнік класа APIClientArgs. У прынцыпе яго параметры наканаваны і пры запуску скрыпту на серверы кіравання іх можна не паказваць.
client_args = APIClientArgs()
Але пры запуску на іншым хасце трэба паказаць як мінімум IP адрас або імя хаста API сервера (ён жа сервер кіравання). У прыкладзе ніжэй мы вызначаем параметр падлучэння server і прысвойваем яму ў выглядзе радка IP адрас сервера кіравання.
Давайце паглядзім на ўсе параметры і іх значэнні па змаўчанні, якія можна выкарыстоўваць пры падлучэнні да API серверу:
Аргументы метаду __init__ класа APIClientArgs
class APIClientArgs:
"""
This class provides arguments for APIClient configuration.
All the arguments are configured with their default values.
"""
# port is set to None by default, but it gets replaced with 443 if not specified
# context possible values - web_api (default) or gaia_api
def __init__(self, port=None, fingerprint=None, sid=None, server="127.0.0.1", http_debug_level=0,
api_calls=None, debug_file="", proxy_host=None, proxy_port=8080,
api_version=None, unsafe=False, unsafe_auto_accept=False, context="web_api"):
self.port = port
# management server fingerprint
self.fingerprint = fingerprint
# session-id.
self.sid = sid
# management server name or IP-address
self.server = server
# debug level
self.http_debug_level = http_debug_level
# an array with all the api calls (for debug purposes)
self.api_calls = api_calls if api_calls else []
# name of debug file. If left empty, debug data will not be saved to disk.
self.debug_file = debug_file
# HTTP proxy server address (without "http://")
self.proxy_host = proxy_host
# HTTP proxy port
self.proxy_port = proxy_port
# Management server's API version
self.api_version = api_version
# Indicates that the client should not check the server's certificate
self.unsafe = unsafe
# Indicates that the client should automatically accept and save the server's certificate
self.unsafe_auto_accept = unsafe_auto_accept
# The context of using the client - defaults to web_api
self.context = context
Мяркую, што аргументы, якія можна выкарыстоўваць у асобніках класа APIClientArgs, інтуітыўна зразумелыя адміністратарам Check Point і ў дадатковых каментарах не маюць патрэбы.
Падключаемся праз APIClient і менеджэр кантэксту
Клас APIClient зручней за ўсё выкарыстоўваць праз менеджэр кантэксту. Усё, што трэба перадаць асобніку класа APIClient гэта параметры падлучэння, якія былі вызначаны ў мінулым кроку.
with APIClient(client_args) as client:
Мэнэджар кантэксту не стане выконваць аўтаматычна login выклік на API сервер, аднак ён выканае выклік logout пры выхадзе з яго. Калі па нейкіх прычынах logout па заканчэнні працы з API выклікамі не патрабуецца, трэба пачаць працу без выкарыстання мэнэджара кантэксту:
client = APIClient(clieng_args)
Праверка злучэння
Праверыць ці праходзіць злучэнне па зададзеных параметрах прасцей за ўсё з дапамогай метаду check_fingerprint. Калі праверка хэш-сумы sha1 для fingerprint сертыфіката API сервера не прайшла(метад вярнуў фальшывы), то звычайна гэта выклікана праблемамі са злучэннем і мы можам спыніць выкананне праграмы(ці даць карыстачу магчымасць выправіць дадзеныя для падлучэння):
if client.check_fingerprint() is False:
print("Could not get the server's fingerprint - Check connectivity with the server.")
exit(1)
Улічыце, што ў далейшым клас APIClient будзе правяраць пры кожным API выкліку (метады api_call и api_query, пра іх гаворка пойдзе крыху далей) sha1 fingerprint сертыфіката на API серверы. А вось калі пры праверцы sha1 fingerprint сертыфіката API сервера будзе выяўлена памылка (сертыфікат невядомы ці быў зменены), метад check_fingerprint прадаставіць магчымасць дадаць/змяніць інфармацыю аб ім на лакальнай машыне ў аўтаматычным рэжыме. Дадзеную праверку можна адключыць зусім (але такое можна рэкамендаваць толькі ў выпадку запуску скрыптоў на самім API серверы, пры падлучэнні да 127.0.0.1), выкарыстаючы аргумент APIClientArgs. unsafe_auto_accept (гл. падрабязней пра APIClientArgs раней у «Вызначаем параметры падлучэння»).
У APIClient ёсць цэлых 3 метаду лагіна на API сервер, і кожны з іх разумее значэнне SID(session-id), якое выкарыстоўвае аўтаматычна ў кожным наступным API выкліку ў загалоўку (імя ў загалоўку ў дадзенага параметру - X-chkp-sid), так што не трэба дадаткова апрацоўваць дадзены параметр.
Метад login
Варыянт з выкарыстаннем лагіна і пароля (у прыкладзе імя карыстальніка admin і пароль 1q2w3e перададзены як пазіцыйныя аргументы):
login = client.login('admin', '1q2w3e')
У метадзе login даступныя таксама дадатковыя апцыянальныя параметры, прыводжу іх імёны і значэнні па змаўчанні:
Варыянт з выкарыстаннем api ключа(падтрымліваецца пачынальна з версіі мэнэджменту R80.40/Management API v1.6, "3TsbPJ8ZKjaJGvFyoFqHFA==" гэта значэнне ключа API для аднаго з карыстачоў на серверы кіравання з метадам аўтарызацыі API key):
У метадзе login_with_api_key даступныя такія ж апцыянальныя параметры як і ў метадзе увайсці.
Метад login_as_root
Варыянт login'а на лакальную машыну з API серверам:
login = client.login_as_root()
Для дадзенага метаду даступныя ўсяго два апцыянальных параметра:
domain=None, payload=None
І нарэшце самі API выклікі
У нас ёсць два варыянты рабіць API выклікі праз метады api_call и api_query. Давайце разбяромся ў чым паміж імі розніца.
api_call
Дадзены метад дастасоўны для любых выклікаў. Нам трэба перадаць апошнюю частку для api выкліку і payload у целе запыту пры неабходнасці. Калі payload пусты, тое яго можна не перадаваць зусім:
Адразу абмоўлюся, што дадзены метад дастасоўны толькі для выклікаў, выснова якіх мяркуе offset(зрух). Такая выснова адбываецца ў тым выпадку, калі ў ім утрымліваецца ці можа ўтрымліваецца вялікая колькасць інфармацыі. Напрыклад, гэта можа быць запыт спісу ўсіх створаных аб'ектаў тыпу хост на сэрвэры кіравання. Для такіх запытаў API вяртае спіс з 50 аб'ектаў па змаўчанні (можна павялічыць ліміт да 500 аб'ектаў у адказе). І для таго, каб не тузаць інфармацыю па некалькі разоў, змяняючы параметр offset у API запыце, ёсць метад api_query, які дадзеную працу прарабляе аўтаматычна. Прыклады выклікаў, дзе патрэбен дадзены метад: show-sessions, show-hosts, show-networks, show-wildcards, show-groups, show-address-ranges, show-simple-gateways, show-simple-clusters, show-access-roles, show-trusted-clients, show-packages. Па факце, у імя гэтых API выклікаў мы бачым словы ў множным ліку, так што гэтыя выклікі будзе прасцей апрацоўваць праз api_query
Пасля гэтага можна выкарыстоўваць зменныя і метады класа APIResponse(як унутры мэнэджара кантэксту, так і звонку). У класа APIResponse наканавана 4 метаду і 5 зменных, на самых важных мы спынімся падрабязней.
поспех
Для пачатку было б нядрэнна ўпэўніцца ў тым, што API выклік прайшоў паспяхова і вярнуў вынік. Для гэтага ёсць метад поспех:
In [49]: api_versions.success
Out[49]: True
Вяртае True калі API выклік прайшоў паспяхова(Код адказу - 200) і False калі не паспяхова(любы іншы код адказу). Зручна выкарыстоўваць адразу пасля API выкліку, каб у залежнасці ад кода адказу вывесці розную інфармацыю.
if api_ver.success:
print(api_versions.data)
else:
print(api_versions.err_message)
statuscode
Вяртае код адказу пасля выканання API выкліку.
In [62]: api_versions.status_code
Out[62]: 400
Магчымыя коды адказаў: 200,400,401,403,404,409,500,501.
set_success_status
Пры гэтым можа быць неабходнасць змяніць значэнне статуту success. Тэхнічна, туды можна змясціць што заўгодна, нават звычайны радок. Але рэальным прыкладам можа быць скід дадзенага параметра ў False пры вызначаных спадарожных умовах. Ніжэй звернеце ўвагу на прыклад, калі ёсць задачы, якія выконваюцца на серверы кіравання, але мы будзем лічыць гэты запыт няўдалым(выставім зменную success у фальшывы, нягледзячы на тое, што API выклік быў паспяховы і вярнуў код 200).
for task in task_result.data["tasks"]:
if task["status"] == "failed" or task["status"] == "partially succeeded":
task_result.set_success_status(False)
break
response()
Метад response дазваляе паглядзець слоўнік з кодам адказу (status_code) і з целам адказу (body).
Дадзеная інфармацыя даступная, толькі калі пры апрацоўцы API запыту ўзнікла памылка (код адказу ня 200). Прыклад вываду
In [107]: api_versions.error_message
Out[107]: 'code: generic_err_invalid_parameter_namenmessage: Unrecognized parameter [1]n'
Карысныя прыклады
Ніжэй пералічаны прыклады, у якіх выкарыстоўваюцца API выклікі, якія былі дададзены ў версію Management API 1.6.
Для пачатку разгледзім працу выклікаў add-host и add-address-range. Дапушчальны, нам трэба стварыць у якасці аб'ектаў тыпу хост усе ip адрасы падсеткі 192.168.0.0/24, апошні актэт якіх роўны 5, а ўсе астатнія ip адрасы запісаць у якасці аб'ектаў тыпу дыяпазон адрасоў. Пры гэтым адрас падсеткі і шырокавяшчальны адрас выключыць.
Такім чынам, ніжэй прадстаўлены скрыпт у якім вырашаецца дадзеная задача і ствараюцца 50 аб'ектаў тыпу хост і 51 аб'ект тыпу дыяпазон адрасоў. На рашэнне задачы патрабуецца 101 API выклік (акрамя фінальнага выкліку publish). Таксама з дапамогай модуля timeit мы падлічваем час на выкананне скрыпту да моманту публікацыі змен.
Скрыпт з выкарыстаннем add-host і add-address-range
import timeit
from cpapi import APIClient, APIClientArgs
start = timeit.default_timer()
first_ip = 1
last_ip = 4
client_args = APIClientArgs(server="192.168.47.240")
with APIClient(client_args) as client:
login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
for ip in range(5,255,5):
add_host = client.api_call("add-host", {"name" : f"h_192.168.0.{ip}", "ip-address": f'192.168.0.{ip}'})
while last_ip < 255:
add_range = client.api_call("add-address-range", {"name": f"r_192.168.0.{first_ip}-{last_ip}", "ip-address-first": f"192.168.0.{first_ip}", "ip-address-last": f"192.168.0.{last_ip}"})
first_ip+=5
last_ip+=5
stop = timeit.default_timer()
publish = client.api_call("publish")
print(f'Time to execute batch request: {stop - start} seconds')
У маім лабараторным асяроддзі на выкананне дадзенага скрыпту сыходзіць ад 30 да 50 секунд у залежнасці ад нагрузкі на сервер кіравання.
А зараз паглядзім як вырашыць гэтую ж задачу з дапамогай API выкліку add-objects-batch, падтрымка якога дададзена ў версію API 1.6. Гэты выклік дазваляе за адзін API запыт стварыць адразу мноства аб'ектаў. Прычым гэта могуць быць аб'екты розных тыпаў (напрыклад хасты, падсеткі і дыяпазоны адрасоў). Такім чынам наша задача можа быць вырашана ў рамках аднаго API выкліку.
Скрыпт з выкарыстаннем add-objects-batch
import timeit
from cpapi import APIClient, APIClientArgs
start = timeit.default_timer()
client_args = APIClientArgs(server="192.168.47.240")
objects_list_ip = []
objects_list_range = []
for ip in range(5,255,5):
data = {"name": f'h_192.168.0.{ip}', "ip-address": f'192.168.0.{ip}'}
objects_list_ip.append(data)
first_ip = 1
last_ip = 4
while last_ip < 255:
data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "ip-address-first": f"192.168.0.{first_ip}", "ip-address-last": f"192.168.0.{last_ip}"}
objects_list_range.append(data)
first_ip+=5
last_ip+=5
data_for_batch = {
"objects" : [ {
"type" : "host",
"list" : objects_list_ip
}, {
"type" : "address-range",
"list" : objects_list_range
}]
}
with APIClient(client_args) as client:
login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
add_objects_batch = client.api_call("add-objects-batch", data_for_batch)
stop = timeit.default_timer()
publish = client.api_call("publish")
print(f'Time to execute batch request: {stop - start} seconds')
А на выкананне дадзенага скрыпту ў маім лабараторным асяроддзі сыходзіць ад 3 да 7 секунд у залежнасці ад нагрузкі на сервер кіравання. Гэта значыць, у сярэднім, на 101 аб'екце API выклік тыпу batch, адпрацоўвае ў 10 разоў хутчэй. На большай колькасці аб'ектаў розніца будзе яшчэ больш уражлівай.
Цяпер давайце паглядзім як працаваць з set-objects-batch. З дапамогай дадзенага API выкліку мы можам масава змяніць любы параметр. Давайце наладзім першай палове адрасоў з мінулага прыкладу (да .124 хаста, прычым і дыяпазонам таксама) колер sienna, а другой палове адрасоў прызначым колер khaki.
Змяненне колеру аб'ектаў, створаных у папярэднім прыкладзе
from cpapi import APIClient, APIClientArgs
client_args = APIClientArgs(server="192.168.47.240")
objects_list_ip_first = []
objects_list_range_first = []
objects_list_ip_second = []
objects_list_range_second = []
for ip in range(5,125,5):
data = {"name": f'h_192.168.0.{ip}', "color": "sienna"}
objects_list_ip_first.append(data)
for ip in range(125,255,5):
data = {"name": f'h_192.168.0.{ip}', "color": "khaki"}
objects_list_ip_second.append(data)
first_ip = 1
last_ip = 4
while last_ip < 125:
data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "color": "sienna"}
objects_list_range_first.append(data)
first_ip+=5
last_ip+=5
while last_ip < 255:
data = {"name": f"r_192.168.0.{first_ip}-{last_ip}", "color": "khaki"}
objects_list_range_second.append(data)
first_ip+=5
last_ip+=5
data_for_batch_first = {
"objects" : [ {
"type" : "host",
"list" : objects_list_ip_first
}, {
"type" : "address-range",
"list" : objects_list_range_first
}]
}
data_for_batch_second = {
"objects" : [ {
"type" : "host",
"list" : objects_list_ip_second
}, {
"type" : "address-range",
"list" : objects_list_range_second
}]
}
with APIClient(client_args) as client:
login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
set_objects_batch_first = client.api_call("set-objects-batch", data_for_batch_first)
set_objects_batch_second = client.api_call("set-objects-batch", data_for_batch_second)
publish = client.api_call("publish")
Выдаліць мноства аб'ектаў у адным API выкліку можна з дапамогай delete-objects-batch. А зараз паглядзім на прыклад кода, які выдаляе ўсе хасты, створаныя раней праз add-objects-batch.
Выдаленне аб'ектаў з дапамогай delete-objects-batch
from cpapi import APIClient, APIClientArgs
client_args = APIClientArgs(server="192.168.47.240")
objects_list_ip = []
objects_list_range = []
for ip in range(5,255,5):
data = {"name": f'h_192.168.0.{ip}'}
objects_list_ip.append(data)
first_ip = 1
last_ip = 4
while last_ip < 255:
data = {"name": f"r_192.168.0.{first_ip}-{last_ip}"}
objects_list_range.append(data)
first_ip+=5
last_ip+=5
data_for_batch = {
"objects" : [ {
"type" : "host",
"list" : objects_list_ip
}, {
"type" : "address-range",
"list" : objects_list_range
}]
}
with APIClient(client_args) as client:
login = client.login_with_api_key('3TsbPJ8ZKjaJGvFyoFqHFA==')
delete_objects_batch = client.api_call("delete-objects-batch", data_for_batch)
publish = client.api_call("publish")
print(delete_objects_batch.data)
Усе функцыі, якія з'яўляюцца ў новых рэлізах ПЗ Check Point, адразу ж знаходзяць і API выклікі. Так, у R80.40 з'явіліся такія фічы як Revert to revision і Smart Task, і для іх адразу ж падрыхтавалі адпаведныя API выклікі. Больш за тое, увесь функцыянал пры пераходзе з Legacy кансоляў у рэжым Unified Policy таксама абрастае падтрымкай API. Напрыклад, доўгачаканым абнаўленнем у версіі ПЗ R80.40 стаў пераезд палітыкі HTTPS Inspection з Legacy рэжыму ў рэжым Unified Policy, і дадзены функцыянал адразу ж атрымаў API выклікі. Вось прыклад кода, які дадае на верхнюю пазіцыю HTTPS Inspection policy правіла, якое выключае з інспекцыі 3 катэгорыі (Здароўе, Фінансы, Дзяржаўныя паслугі), якія забаронена інспектаваць у адпаведнасці з заканадаўствам у шэрагу краін.
Запуск Python скрыптоў на сэрвэры кіравання Check Point
Усё ў тым жа README.md змяшчаецца інфармацыя як запускаць скрыпты на Python прама з сервера кіравання. Гэта можа быць зручна, калі ў вас няма магчымасці падлучыцца да API серверу з іншай машыны. Я запісаў шасціхвіліннае відэа ў якім разглядаю ўстаноўку модуля cpapi і асаблівасці запуску Python скрыптоў на сэрвэры кіравання. У якасці прыкладу запускаецца скрыпт, які аўтаматызуе канфігурацыю новага шлюза для такой задачы, як аўдыт сеткі Security CheckUp. З асаблівасцяў, з якімі прыйшлося сутыкнуцца: у версіі Python 2.7 яшчэ не з'явілася функцыя ўваход, таму для апрацоўкі інфармацыі, якую ўводзіць карыстальнік, выкарыстоўваецца функцыя raw_input. У астатнім, код такі ж як для запуску з іншых машын, толькі зручней выкарыстоўваць функцыю login_as_root, Каб не паказваць свае ж уласныя username, пароль і IP адрас сервера кіравання яшчэ раз.
Скрыпт для хуткай наладкі Security CheckUp
from __future__ import print_function
import getpass
import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from cpapi import APIClient, APIClientArgs
def main():
with APIClient() as client:
# if client.check_fingerprint() is False:
# print("Could not get the server's fingerprint - Check connectivity with the server.")
# exit(1)
login_res = client.login_as_root()
if login_res.success is False:
print("Login failed:n{}".format(login_res.error_message))
exit(1)
gw_name = raw_input("Enter the gateway name:")
gw_ip = raw_input("Enter the gateway IP address:")
if sys.stdin.isatty():
sic = getpass.getpass("Enter one-time password for the gateway(SIC): ")
else:
print("Attention! Your password will be shown on the screen!")
sic = raw_input("Enter one-time password for the gateway(SIC): ")
version = raw_input("Enter the gateway version(like RXX.YY):")
add_gw = client.api_call("add-simple-gateway", {'name' : gw_name, 'ipv4-address' : gw_ip, 'one-time-password' : sic, 'version': version.capitalize(), 'application-control' : 'true', 'url-filtering' : 'true', 'ips' : 'true', 'anti-bot' : 'true', 'anti-virus' : 'true', 'threat-emulation' : 'true'})
if add_gw.success and add_gw.data['sic-state'] != "communicating":
print("Secure connection with the gateway hasn't established!")
exit(1)
elif add_gw.success:
print("The gateway was added successfully.")
gw_uid = add_gw.data['uid']
gw_name = add_gw.data['name']
else:
print("Failed to add the gateway - {}".format(add_gw.error_message))
exit(1)
change_policy = client.api_call("set-access-layer", {"name" : "Network", "applications-and-url-filtering": "true", "content-awareness": "true"})
if change_policy.success:
print("The policy has been changed successfully")
else:
print("Failed to change the policy- {}".format(change_policy.error_message))
change_rule = client.api_call("set-access-rule", {"name" : "Cleanup rule", "layer" : "Network", "action": "Accept", "track": {"type": "Detailed Log", "accounting": "true"}})
if change_rule.success:
print("The cleanup rule has been changed successfully")
else:
print("Failed to change the cleanup rule- {}".format(change_rule.error_message))
# publish the result
publish_res = client.api_call("publish", {})
if publish_res.success:
print("The changes were published successfully.")
else:
print("Failed to publish the changes - {}".format(install_tp_policy.error_message))
install_access_policy = client.api_call("install-policy", {"policy-package" : "Standard", "access" : 'true', "threat-prevention" : 'false', "targets" : gw_uid})
if install_access_policy.success:
print("The access policy has been installed")
else:
print("Failed to install access policy - {}".format(install_tp_policy.error_message))
install_tp_policy = client.api_call("install-policy", {"policy-package" : "Standard", "access" : 'false', "threat-prevention" : 'true', "targets" : gw_uid})
if install_tp_policy.success:
print("The threat prevention policy has been installed")
else:
print("Failed to install threat prevention policy - {}".format(install_tp_policy.error_message))
# add passwords and passphrases to dictionary
with open('additional_pass.conf') as f:
line_num = 0
for line in f:
line_num += 1
add_password_dictionary = client.api_call("run-script", {"script-name" : "Add passwords and passphrases", "script" : "printf "{}" >> $FWDIR/conf/additional_pass.conf".format(line), "targets" : gw_name})
if add_password_dictionary.success:
print("The password dictionary line {} was added successfully".format(line_num))
else:
print("Failed to add the dictionary - {}".format(add_password_dictionary.error_message))
main()
Прыклад файла са слоўнікам пароляў additional_pass.conf {
"passwords" : ["malware","malicious","infected","Infected"],
"phrases" : ["password","Password","Pass","pass","codigo","key","pwd","пароль","Пароль","Ключ","ключ","шифр","Шифр"]
}
Заключэнне
Дадзены артыкул разглядае толькі асноўныя магчымасці працы Python SDK і модуля cpapi(як вы маглі здагадацца, гэта практычна сінонімы), і вывучыўшы код у дадзеным модулі вы адкрыеце сабе яшчэ больш магчымасцяў у працы з ім. Не выключана, што ў вас з'явіцца жаданне дапоўніць яго сваімі класамі, функцыямі, метадамі і зменнымі. Вы заўсёды можаце дзеліцца сваімі напрацоўкамі і праглядаць іншыя скрыпты для Check Point у раздзеле CodeHub у супольнасці CheckMates, якое аб'ядноўвае ў сабе і распрацоўшчыкаў прадуктаў і карыстальнікаў.
Прыемнага кодынгу і дзякуй, што дачыталі да канца!