Add mikrotik SSL support (#17898)

* Update mikrotik.py

* Update mikrotik.py

* Added basic  api_ssl support

Added preliminary support to use api_ssl instead of api. It don't check the validity of the certificate need it.
At Home Assistant side add ssl = true to your sensor configuration, and don't forget to change the port too (to 8729 by default):

device_tracker:
  - platform: mikrotik
    host: 192.168.88.1
    port: 8729
    ssl: true
    username: homeassistant
    password: TopSecret

At MikroTik side you have to add or generate a certificate, and configure api_ssl to use it. Here is an example:

/certificate add common-name="Self signed demo certificate for API" days-valid=3650 name="Self signed demo certificate for API" key-usage=digital-signature,key-encipherment,tls-server,key-cert-sign,crl-sign
/certificate sign "Self signed demo certificate for API"
/ip service set api-ssl certificate="Self signed demo certificate for API"
/ip service enable api-ssl
/ip service disable api
/user group add name=homeassistant policy=read,api,!local,!telnet,!ssh,!ftp,!reboot,!write,!policy,!test,!winbox,!password,!web,!sniff,!sensitive,!romon,!dude,!tikapp
/user add group=homeassistant name=homeassistant
/user set password="TopSecret" homeassistant

* Fixed import missind ssl lib

* SSL support code cleanup, use ssl-api port by default if ssl enabled

* Restored accidentalli deleted method parameter

* Fixed Python 3.5.3 compilation errors

Fixed Python 3.5.3 compilation errors reported by Travis CI

* Removed duplicated MTK_DEFAULT_API_PORT
pull/18585/head
Soós Péter 2018-11-19 16:54:09 +01:00 committed by Paulus Schoutsen
parent de9bac9ee3
commit 3891f2eebe
1 changed files with 28 additions and 5 deletions

View File

@ -6,26 +6,30 @@ https://home-assistant.io/components/device_tracker.mikrotik/
""" """
import logging import logging
import ssl
import voluptuous as vol import voluptuous as vol
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.components.device_tracker import ( from homeassistant.components.device_tracker import (
DOMAIN, PLATFORM_SCHEMA, DeviceScanner) DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_PORT, CONF_METHOD) CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_PORT, CONF_SSL, CONF_METHOD)
REQUIREMENTS = ['librouteros==2.1.1'] REQUIREMENTS = ['librouteros==2.1.1']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
MTK_DEFAULT_API_PORT = '8728' MTK_DEFAULT_API_PORT = '8728'
MTK_DEFAULT_API_SSL_PORT = '8729'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_HOST): cv.string, vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string, vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_METHOD): cv.string, vol.Optional(CONF_METHOD): cv.string,
vol.Optional(CONF_PORT, default=MTK_DEFAULT_API_PORT): cv.port, vol.Optional(CONF_PORT): cv.port,
vol.Optional(CONF_SSL, default=False): cv.boolean
}) })
@ -43,7 +47,14 @@ class MikrotikScanner(DeviceScanner):
self.last_results = {} self.last_results = {}
self.host = config[CONF_HOST] self.host = config[CONF_HOST]
self.port = config[CONF_PORT] self.ssl = config[CONF_SSL]
try:
self.port = config[CONF_PORT]
except KeyError:
if self.ssl:
self.port = MTK_DEFAULT_API_SSL_PORT
else:
self.port = MTK_DEFAULT_API_PORT
self.username = config[CONF_USERNAME] self.username = config[CONF_USERNAME]
self.password = config[CONF_PASSWORD] self.password = config[CONF_PASSWORD]
self.method = config.get(CONF_METHOD) self.method = config.get(CONF_METHOD)
@ -64,9 +75,21 @@ class MikrotikScanner(DeviceScanner):
"""Connect to Mikrotik method.""" """Connect to Mikrotik method."""
import librouteros import librouteros
try: try:
kwargs = {
'port': self.port,
'encoding': 'utf-8'
}
if self.ssl:
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
kwargs['ssl_wrapper'] = ssl_context.wrap_socket
self.client = librouteros.connect( self.client = librouteros.connect(
self.host, self.username, self.password, port=int(self.port), self.host,
encoding='utf-8') self.username,
self.password,
**kwargs
)
try: try:
routerboard_info = self.client( routerboard_info = self.client(