尝试将 Linux 系统作为无头蓝牙服务器运行,要求连接的手机或平板电脑输入 PIN 码
我正在使用一台 Linux 计算机,该计算机在部署时无法与之交互。
它必须启动的唯一(最终用户友好的)接入点是蓝牙接入点。
蓝牙通讯已成功建立,手机无需在控制器上进行任何输入即可与控制器连接。
问题是在这种情况下并不安全,任何东西现在都可以自由配对和连接。
我希望控制器从连接设备请求控制器唯一的引脚,这样只有有权访问该引脚的人才能与控制器连接。
我正在使用 python 来管理处理配对过程的代理,并且我当前正在使用此代码:
import dbus.service
import dbus.mainloop.glib
from gi.repository import GLib
BUS_NAME = 'org.bluez'
ADAPTER_IFACE = 'org.bluez.Adapter1'
ADAPTER_ROOT = '/org/bluez/hci'
AGENT_IFACE = 'org.bluez.Agent1'
AGNT_MNGR_IFACE = 'org.bluez.AgentManager1'
AGENT_PATH = '/my/app/agent'
AGNT_MNGR_PATH = '/org/bluez'
CAPABILITY = 'KeyboardDisplay'
DEVICE_IFACE = 'org.bluez.Device1'
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
def set_trusted(path):
props = dbus.Interface(bus.get_object(BUS_NAME, path), dbus.PROPERTIES_IFACE)
props.Set(DEVICE_IFACE, "Trusted", True)
class Agent(dbus.service.Object):
@dbus.service.method(AGENT_IFACE,
in_signature="", out_signature="")
def Release(self):
print("Release")
@dbus.service.method(AGENT_IFACE,
in_signature='o', out_signature='s')
def RequestPinCode(self, device):
print(f'RequestPinCode {device}')
return '0000'
@dbus.service.method(AGENT_IFACE,
in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
print("RequestConfirmation (%s, %06d)" % (device, passkey))
set_trusted(device)
return
@dbus.service.method(AGENT_IFACE,
in_signature="o", out_signature="")
def RequestAuthorization(self, device):
print("RequestAuthorization (%s)" % (device))
auth = input("Authorize? (yes/no): ")
if (auth == "yes"):
return
raise Rejected("Pairing rejected")
@dbus.service.method(AGENT_IFACE,
in_signature="o", out_signature="u")
def RequestPasskey(self, device):
print("RequestPasskey (%s)" % (device))
set_trusted(device)
passkey = input("Enter passkey: ")
return dbus.UInt32(passkey)
@dbus.service.method(AGENT_IFACE,
in_signature="ouq", out_signature="")
def DisplayPasskey(self, device, passkey, entered):
print("DisplayPasskey (%s, %06u entered %u)" %
(device, passkey, entered))
@dbus.service.method(AGENT_IFACE,
in_signature="os", out_signature="")
def DisplayPinCode(self, device, pincode):
print("DisplayPinCode (%s, %s)" % (device, pincode))
class Adapter:
def __init__(self, idx=0):
bus = dbus.SystemBus()
self.path = f'{ADAPTER_ROOT}{idx}'
self.adapter_object = bus.get_object(BUS_NAME, self.path)
self.adapter_props = dbus.Interface(self.adapter_object,
dbus.PROPERTIES_IFACE)
self.adapter_props.Set(ADAPTER_IFACE,
'DiscoverableTimeout', dbus.UInt32(0))
self.adapter_props.Set(ADAPTER_IFACE,
'Discoverable', True)
self.adapter_props.Set(ADAPTER_IFACE,
'PairableTimeout', dbus.UInt32(0))
self.adapter_props.Set(ADAPTER_IFACE,
'Pairable', True)
if __name__ == '__main__':
agent = Agent(bus, AGENT_PATH)
agnt_mngr = dbus.Interface(bus.get_object(BUS_NAME, AGNT_MNGR_PATH),
AGNT_MNGR_IFACE)
agnt_mngr.RegisterAgent(AGENT_PATH, CAPABILITY)
agnt_mngr.RequestDefaultAgent(AGENT_PATH)
adapter = Adapter()
mainloop = GLib.MainLoop()
try:
mainloop.run()
except KeyboardInterrupt:
agnt_mngr.UnregisterAgent(AGENT_PATH)
mainloop.quit()
我从这里获得了此代码,但说实话,我不明白它。
它定义了一堆 dbus.service.method,我认为它以某种方式选择一个或某个东西。
作为一个习惯了不太抽象的语言的人,我只是不知道它把所有这些东西放在哪里或者它拉到哪里。
我相信在这种情况下它只使用 RequestConfirmation() 方法。所以其他的都只是垃圾。
但我想知道是否/如何修改它,使其在我尝试与控制器配对时要求手机上输入密码或密钥。
I'm working with a linux computer that will have no way to interface with it when it is deployed.
The only (end user friendly) access point it will have to start off is a bluetooth access point.
Bluetooth communication has been succesfully established, and a phone can connect with the controller without having to do any input on the controller.
The problem is that it isn't safe in this situation, anything can now freely pair and connect.
I would like the controller to request a controller unique pin from the connecting device so only people with access to that pin can connect with the controller.
I'm using python to manage the agent that handles the pairing process, and I'm currently using this code:
import dbus.service
import dbus.mainloop.glib
from gi.repository import GLib
BUS_NAME = 'org.bluez'
ADAPTER_IFACE = 'org.bluez.Adapter1'
ADAPTER_ROOT = '/org/bluez/hci'
AGENT_IFACE = 'org.bluez.Agent1'
AGNT_MNGR_IFACE = 'org.bluez.AgentManager1'
AGENT_PATH = '/my/app/agent'
AGNT_MNGR_PATH = '/org/bluez'
CAPABILITY = 'KeyboardDisplay'
DEVICE_IFACE = 'org.bluez.Device1'
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
def set_trusted(path):
props = dbus.Interface(bus.get_object(BUS_NAME, path), dbus.PROPERTIES_IFACE)
props.Set(DEVICE_IFACE, "Trusted", True)
class Agent(dbus.service.Object):
@dbus.service.method(AGENT_IFACE,
in_signature="", out_signature="")
def Release(self):
print("Release")
@dbus.service.method(AGENT_IFACE,
in_signature='o', out_signature='s')
def RequestPinCode(self, device):
print(f'RequestPinCode {device}')
return '0000'
@dbus.service.method(AGENT_IFACE,
in_signature="ou", out_signature="")
def RequestConfirmation(self, device, passkey):
print("RequestConfirmation (%s, %06d)" % (device, passkey))
set_trusted(device)
return
@dbus.service.method(AGENT_IFACE,
in_signature="o", out_signature="")
def RequestAuthorization(self, device):
print("RequestAuthorization (%s)" % (device))
auth = input("Authorize? (yes/no): ")
if (auth == "yes"):
return
raise Rejected("Pairing rejected")
@dbus.service.method(AGENT_IFACE,
in_signature="o", out_signature="u")
def RequestPasskey(self, device):
print("RequestPasskey (%s)" % (device))
set_trusted(device)
passkey = input("Enter passkey: ")
return dbus.UInt32(passkey)
@dbus.service.method(AGENT_IFACE,
in_signature="ouq", out_signature="")
def DisplayPasskey(self, device, passkey, entered):
print("DisplayPasskey (%s, %06u entered %u)" %
(device, passkey, entered))
@dbus.service.method(AGENT_IFACE,
in_signature="os", out_signature="")
def DisplayPinCode(self, device, pincode):
print("DisplayPinCode (%s, %s)" % (device, pincode))
class Adapter:
def __init__(self, idx=0):
bus = dbus.SystemBus()
self.path = f'{ADAPTER_ROOT}{idx}'
self.adapter_object = bus.get_object(BUS_NAME, self.path)
self.adapter_props = dbus.Interface(self.adapter_object,
dbus.PROPERTIES_IFACE)
self.adapter_props.Set(ADAPTER_IFACE,
'DiscoverableTimeout', dbus.UInt32(0))
self.adapter_props.Set(ADAPTER_IFACE,
'Discoverable', True)
self.adapter_props.Set(ADAPTER_IFACE,
'PairableTimeout', dbus.UInt32(0))
self.adapter_props.Set(ADAPTER_IFACE,
'Pairable', True)
if __name__ == '__main__':
agent = Agent(bus, AGENT_PATH)
agnt_mngr = dbus.Interface(bus.get_object(BUS_NAME, AGNT_MNGR_PATH),
AGNT_MNGR_IFACE)
agnt_mngr.RegisterAgent(AGENT_PATH, CAPABILITY)
agnt_mngr.RequestDefaultAgent(AGENT_PATH)
adapter = Adapter()
mainloop = GLib.MainLoop()
try:
mainloop.run()
except KeyboardInterrupt:
agnt_mngr.UnregisterAgent(AGENT_PATH)
mainloop.quit()
I got this code from here, but to be honest, I don't understand it.
It defines a bunch of dbus.service.method's and I think it somehow chooses one or something.
As someone who is used to less abstract languages I just dont know where its putting all this stuff or where its pulling.
I believe it just uses the RequestConfirmation() method in this case. so all the others are just junk.
But I would like to know if/how I can modify this to make it ask for a pin or passkey on my phone when I try to pair with the controller.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试解释代码的作用...
Linux 系统上运行着一个蓝牙守护进程 (
bluetoothd
)。bluetoothd
处理系统上的蓝牙功能。下面是与bluetoothd
进行配对交互的序列图。RegisterAgent()
用于告诉bluetoothd
D-Busorg.bluez.Agent1
接口在哪里创建以及使用此注册代理的功能。当配对请求传入
bluetoothd
时,它会在注册位置调用RequestConfirmation()
。如果返回值为空则确认确认。如果抛出 org.bluez.Error.Rejected 或 org.bluez.Error.Canceled ,则配对将被拒绝。bluetoothd
调用哪个org.bluez.Agent1
方法将取决于收到的配对请求的具体类型。此表<可能最好地总结了功能设置/a>:
如果调用的是
RequestConfirmation()
方法,则传入的参数是设备 D-Bus 路径和 uint32 密钥。由代理中的方法根据该信息决定是否接受请求。org.bluez.Agent1
接口记录在:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/agent-api.txt
BlueZ 官方示例,简单介绍代理位于:
https://git.kernel.org/ pub/scm/bluetooth/bluez.git/tree/test/simple-agent
To try to explain what the code is doing...
There is a Bluetooth daemon (
bluetoothd
) running on a Linux system.bluetoothd
handles the Bluetooth functionality on the system. Below is a sequence diagram of the interactions withbluetoothd
for pairing.RegisterAgent()
is used to tellbluetoothd
where the D-Busorg.bluez.Agent1
interface has been created and which capability to use this registered agent for.When a pairing request comes in to
bluetoothd
it callsRequestConfirmation()
at the registered location. If the returned value back is empty then the confirmation is confirmed. If there is eitherorg.bluez.Error.Rejected
ororg.bluez.Error.Canceled
thrown then the pairing is rejected.Which of the
org.bluez.Agent1
methods gets called bybluetoothd
will depend on exactly what type of pairing request has been received.The capability setting is probably best summarized by this table:
If it is the
RequestConfirmation()
method that is getting called, then the device D-Bus path and a uint32 passkey are the parameters passed in. It is up to the method in the agent to decide, on that information, if it should accept the request or not.The
org.bluez.Agent1
interface is documented at:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/agent-api.txt
The official BlueZ example for a simple agent is at:
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/simple-agent