I was using the pidgin dbus api to print the names of my gtalk buddies and their status by writing the following python code snippet:
import dbus
# Initiate a connection to the Session Bus
bus = dbus.SessionBus()
# Associate Pidgin's D-Bus interface with Python objects
obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
# Iterate through every active account
for acctID in purple.PurpleAccountsGetAllActive():
for buddy in purple.PurpleFindBuddies(acctID,""):
print purple.PurpleBuddyGetName(buddy),'Online' if purple.PurpleBuddyIsOnline(buddy) else 'Offline'
In Pidgin when i hover my mouse over a particular buddy, it also shows the Resource string of that buddy for example gtalk, android etc... which tells me which resource the user is logged in from.
Is there a way to fetch this Resource string using pidgins dbus api or some other way ?
Please Help
Thank You
you can use the script from the wiki page:
#!/usr/bin/env python
def my_func(account, sender, message, conversation, flags):
print sender, "said:", message
import dbus, gobject
from dbus.mainloop.glib import DBusGMainLoop
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(my_func,
dbus_interface="im.pidgin.purple.PurpleInterface",
signal_name="ReceivedImMsg")
loop = gobject.MainLoop()
loop.run()
sender here will be smth like this:
'example#gmail.com/androidXXXXXXXX' in case of using android or 'example#gmail.com/gmail.XXXXXXXX' for gtalk or
'example#gmail.com/XXXXXXXX' for other im, where X is a hex value.
Related
I'm working on an asynchronous communication script that will act as a middleman between a react native app and another agent. To do this I used python with DBUS to implement the communication between the two.
To implement this we created two processes one for the BLE and one for the communication with the agent. In cases where the agent replies immediately (with a non-blocking call) the communication always works as intended. For the case where we attach to a signal to continuously monitor an update status this error occurs most of the time at random points during the process:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
I have tested both the BLE process and the agent process separately and they work as intended.
I'm currently suspecting that it could be related to messages "crashing" on the system bus or some race conditions but we are unsure how to validate that.
Any advice on what could be causing this issue or how I could avoid it?
For completeness I've attached a simplified version of the class that handles the communication with the agent.
import multiprocessing
from enum import Enum
import dbus
import dbus.mainloop.glib
from dbus.proxies import ProxyObject
from gi.repository import GLib
from omegaconf import DictConfig
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
class ClientUpdateStatus(Enum):
SUCCESS = 0
PENDING = 1
IN_PROGRESS = 2
FAILED = 3
class DBUSManager:
GLIB_LOOP = GLib.MainLoop()
COMMUNICATION_QUEUE = multiprocessing.Queue()
def __init__(self, config: DictConfig) -> None:
dbus_system_bus = dbus.SystemBus()
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
self._config = config
self._dbus_object = dbus_system_bus.get_object(self._config['dbus_interface'],
self._config['dbus_object_path'], introspect=False)
def get_version(self) -> str:
version = self._dbus_object.GetVersion("clientSimulator", dbus_interface=self._config['dbus_interface'])
return version
def check_for_update(self) -> str:
update_version = self._dbus_object.CheckForUpdate("clientSimulator",
dbus_interface=self._config['dbus_interface'])
return update_version
def run_update(self) -> ClientUpdateStatus:
raw_status = self._dbus_object.ExecuteUpdate(dbus_interface=self._config['dbus_interface'])
update_status = ClientUpdateStatus(raw_status)
# Launch listening process
signal_update_proc = multiprocessing.Process(target=DBUSManager.start_listener_process,
args=(self._dbus_object, self._config['dbus_interface'],))
signal_update_proc.start()
while True:
raw_status = DBUSManager.COMMUNICATION_QUEUE.get()
update_status = ClientUpdateStatus(raw_status)
if ClientUpdateStatus.SUCCESS == update_status:
break
signal_update_proc.join()
return update_status
#staticmethod
def start_listener_process(dbus_object: ProxyObject, dbus_interface: str) -> None:
dbus_object.connect_to_signal("UpdateStatusChanged", DBUSManager.status_change_handler,
dbus_interface=dbus_interface)
# Launch loop to acquire signals
DBUSManager.GLIB_LOOP.run() # This listening loop exits on GLIB_LOOP.quit()
#staticmethod
def status_change_handler(new_status: int) -> None:
DBUSManager.COMMUNICATION_QUEUE.put(new_status)
if ClientUpdateStatus.SUCCESS == ClientUpdateStatus(new_status):
DBUSManager.GLIB_LOOP.quit()
At this stage I would recommend to do a dbus-monitor to see if agent and BLE are reacting to requests properly.
Maybe to help others in the future I haven't found the solution but at least a way to work around it. We have encountered that problem at various places in our project and what generally helped, don't ask me why, was to always re-instantiate all needed dbus objects. So instead of having a single class that has a system bus variable self._system_bus = dbus.SystemBus() or a interface variable self._manager_interface = dbus.Interface(proxy_object, "org.freedesktop.DBus.ObjectManager") we would always re-instiate them.
If somebody knows what the problem is I'm happy to hear it.
I am currently underway with my Senior Capstone project, in which I am to write a somewhat basic program which allows a custom interface on my iPhone6 device to remotely control or issue critical commands to a NIDS (Suricata) established at my home RaspberryPi(3B+) VPN. My question, however, is whether it's feasible to write said program which can allow remote access control of basic functions/response options on the Pi's IDS, given that I am utilizing it as a device within the VPN network. The main issue would be establish remote signaling to the iOS device whenever there is an anomaly and allowing it to respond back and execute root-level commands on the NIDS.
If it is of any good use, I am currently using Pythonista as a runtime environment on my mobile device and have set my VPN's connection methods to UDP, but I'm not sure if enabling SSH would assist me. I have a rather basic understanding of how to operate programming in regards to network connectivity. I very much appreciate any and all the help given!
from tkinter import *
window=Tk()
window.geometry("450x450")
window.title("IDS Response Manager")
label1=Label(window,text="Intrusion Response Options",fg= 'black',bg ='white',relief="solid",font=("times new roman",12,"bold"))
label1.pack()
button1=Button(window,text="Terminate Session",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button1.place(x=50,y=110) #GROOVE ,RIDGE ,SUNKEN ,RAISED
button2=Button(window,text="Packet Dump",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button2.place(x=220,y=110) #GROOVE ,RIDGE ,SUNKEN ,RAISED
button3=Button(window,text="Block Port",fg='white', bg='brown',relief=RIDGE,font=("arial",12,"bold"))
button3.place(x=110,y=170) #GROOVE ,RIDGE ,SUNKEN ,RAISED
Very basic options as are shown here.
You can use a flask server with an API, which you can send post requests to. You can then send get requests to receive the commands. To host your API, look at Heroku (free tier available, and very much functional, with already configured app_name.herokuapp.com).
Search up to send a post request with the technologies you are using to build your app. Send keyword command with the command to the /send_commands along with the password, "password_here" (changeable to anything you want).
Python:
Modules: Flask (server), request (client)
Server Code:
from flask import Flask
app = Flask(__name__)
commands = []
#app.route('/get_commands', methods=['GET'])
def get_commands():
tmp_commands = commands[::]
commands = []
return {'commands': tmp_commands}
#app.route('/send_commands', methods=['POST'])
def send_commands():
if request.json['password'] == "password_here":
commands.append(request.json['command'])
return {'worked': True}
else:
return {'worked': False}
if __name__ == '__main__':
app.run(debug=True)
Client Code:
import requests
URL = "url_here/get_commands"
commands = requests.get(url = URL)
for command in commands:
os.system(command)
I am attempting to capture ssh bruteforce attempts using a simple ssh server, the code is bellow and works, I am however unable to match Username/Password combinations with their originating IP address.
This is as simple as I can get it thus far, it does not log yet just prints to stdout. I used the buildProtocol definition to print out the IP address of a new connection when it is made. I would however like to get the IP address along with the username and password credentials so that I can track multiple ssh bruteforce attempts from different clients at the same time. As it stands I can only get the IP address as the connection is made, which makes tracking multiple connections concurrently impossible.
Just to clarify, when I refer to connection or connections I am not referring to a successful login, this is impossible with my code and is not intended. I am referring to a single connection to the ssh server which allows 3 password attempts before you have to reconnect.
from zope.interface import implements
from twisted.conch.unix import UnixSSHRealm
from twisted.cred import portal
from twisted.cred.credentials import IUsernamePassword
from twisted.cred.checkers import ICredentialsChecker
from twisted.cred.error import UnauthorizedLogin
from twisted.conch.ssh import factory, userauth, keys, session
from twisted.internet import reactor, defer
with open('id_rsa') as privateBlobFile:
privateKey = privateBlobFile.read()
with open('id_rsa.pub') as publicBlobFile:
publicKey = publicBlobFile.read()
class FailDB:
credentialInterfaces = IUsernamePassword, implements(ICredentialsChecker)
def requestAvatarId(self, credentials):
print"%s:%s" % ( credentials.username, credentials.password)
return defer.fail(UnauthorizedLogin("invalid password"))
class UnixSSHdFactory(factory.SSHFactory):
publicKeys = {
'ssh-rsa': keys.Key.fromString(data=publicKey)
}
privateKeys = {
'ssh-rsa': keys.Key.fromString(data=privateKey)
}
services = {
'ssh-userauth': userauth.SSHUserAuthServer
}
def buildProtocol(self, addr):
print addr
return factory.SSHFactory.buildProtocol(self, addr)
if __name__ == '__main__':
portal = portal.Portal(UnixSSHRealm())
portal.registerChecker(FailDB())
UnixSSHdFactory.portal = portal
reactor.listenTCP(2022, UnixSSHdFactory())
reactor.run()
Example output:
IPv4Address(TCP, '127.0.0.1', 42141)
root:password123
root:123456
root:letmein
You can get the address from a failed login attempt by deriving from SSHUserAuthServer and overriding the _ebBadAuth method. Example:
class AuthServer(userauth.SSHUserAuthServer):
def _ebBadAuth(self, reason):
addr = self.transport.getPeer().address.host
print("addr {} failed to log in as {} using {}"
.format(addr, self.user, self.method))
userauth.SSHUserAuthServer._ebBadAuth(self, reason)
In case you also wanted to allow connections to succeed, you would have to not override the SSHFactory.services, but only update it with your derived class, like factory.services.update({'ssh-userauth': AuthServer}).
I need to have a python client that can discover queues on a restarted RabbitMQ server exchange, and then start up a clients to resume consuming messages from each queue. How can I discover queues from some RabbitMQ compatible python api/library?
There does not seem to be a direct AMQP-way to manage the server but there is a way you can do it from Python. I would recommend using a subprocess module combined with the rabbitmqctl command to check the status of the queues.
I am assuming that you are running this on Linux. From a command line, running:
rabbitmqctl list_queues
will result in:
Listing queues ...
pings 0
receptions 0
shoveled 0
test1 55199
...done.
(well, it did in my case due to my specific queues)
In your code, use this code to get output of rabbitmqctl:
import subprocess
proc = subprocess.Popen("/usr/sbin/rabbitmqctl list_queues", shell=True, stdout=subprocess.PIPE)
stdout_value = proc.communicate()[0]
print stdout_value
Then, just come up with your own code to parse stdout_value for your own use.
As far as I know, there isn't any way of doing this. That's nothing to do with Python, but because AMQP doesn't define any method of queue discovery.
In any case, in AMQP it's clients (consumers) that declare queues: publishers publish messages to an exchange with a routing key, and consumers determine which queues those routing keys go to. So it does not make sense to talk about queues in the absence of consumers.
You can add plugin rabbitmq_management
sudo /usr/lib/rabbitmq/bin/rabbitmq-plugins enable rabbitmq_management
sudo service rabbitmq-server restart
Then use rest-api
import requests
def rest_queue_list(user='guest', password='guest', host='localhost', port=15672, virtual_host=None):
url = 'http://%s:%s/api/queues/%s' % (host, port, virtual_host or '')
response = requests.get(url, auth=(user, password))
queues = [q['name'] for q in response.json()]
return queues
I'm using requests library in this example, but it is not significantly.
Also I found library that do it for us - pyrabbit
from pyrabbit.api import Client
cl = Client('localhost:15672', 'guest', 'guest')
queues = [q['name'] for q in cl.get_queues()]
Since I am a RabbitMQ beginner, take this with a grain of salt, but there's an interesting Management Plugin, which exposes an HTTP interface to "From here you can manage exchanges, queues, bindings, virtual hosts, users and permissions. Hopefully the UI is fairly self-explanatory."
http://www.rabbitmq.com/blog/2010/09/07/management-plugin-preview-release/
I use https://github.com/bkjones/pyrabbit. It's talks directly to RabbitMQ's mgmt plugin's API interface, and is very handy for interrogating RabbitMQ.
Management features are due in a future version of AMQP. So for now you will have to wait till for a new version that will come with that functionality.
I found this works for me, /els being my demo vhost name..
rabbitmqctl list_queues --vhost /els
pyrabbit didn't work so well for me; However, the Management Plugin itself has its own command line script that you can download from your own admin GUI and use later on (for example, I downloaded mine from
http://localhost:15672/cli/
for local use)
I would use simply this:
Just replace the user(default= guest), passwd(default= guest) and port with your values.
import requests
import json
def call_rabbitmq_api(host, port, user, passwd):
url = 'http://%s:%s/api/queues' % (host, port)
r = requests.get(url, auth=(user,passwd))
return r
def get_queue_name(json_list):
res = []
for json in json_list:
res.append(json["name"])
return res
if __name__ == '__main__':
host = 'rabbitmq_host'
port = 55672
user = 'guest'
passwd = 'guest'
res = call_rabbitmq_api(host, port, user, passwd)
print ("--- dump json ---")
print (json.dumps(res.json(), indent=4))
print ("--- get queue name ---")
q_name = get_queue_name(res.json())
print (q_name)
Referred from here: https://gist.github.com/hiroakis/5088513#file-example_rabbitmq_api-py-L2
It's the first time I'm using DBus so please bear with me.
This is my code:
import gobject
import pprint
gobject.threads_init()
from dbus import glib
glib.init_threads()
import dbus
bus = dbus.SessionBus()
remote_object = bus.get_object("org.freedesktop.UDisks", # Connection name
"/org/freedesktop/UDisks" # Object's path
)
print ("Introspection data:\n")
print remote_object.Introspect()
print remote_object.get_dbus_method("ListNames",dbus_interface="org.freedesktop.DBus")
for item in remote_object.ListNames():
print item
The error I'm getting is:
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.UDisks was not provided by any .service files
From the udisk-demon manpage
udisks-daemon provides the org.freedesktop.UDisks service on the system message bus. Users or administrators should never need to start this daemon as it will be automatically started by dbus-daemon(1) whenever an application calls into the org.freedesktop.UDisks service. See the udisks(7) man page for information on how to customize how udisks-daemon works.
EDIT: So it was SystemSession() and not SessionBus()
You can try using DFeet to check if this dbus object really exists.
The following worked for me, but I don't see the ListNames method you used, so I used EnumerateDevices.
import dbus
bus = dbus.SystemBus()
udisks = bus.get_object("org.freedesktop.UDisks", "/org/freedesktop/UDisks")
udisks = dbus.Interface(udisks, 'org.freedesktop.UDisks')
devices = udisks.get_dbus_method('EnumerateDevices')()