Created
November 20, 2020 12:03
-
-
Save linuxthor/a66ae4e106478c60c8a6d3ab0e4c5f59 to your computer and use it in GitHub Desktop.
dbus-message.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// linuxthor | |
// | |
// Showing how to open a socket connection to dbus and do 'raw' messages (i.e. just sending | |
// some bytes and not worrying about weird stuff like Dict of{String, Variant} or whatever | |
// for the moment..) | |
// | |
// Started off fun but the whole thing is surprisingly bulky & annoying tbh | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <ctype.h> | |
#include <poll.h> | |
#include <signal.h> | |
#include <sys/un.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include "hexdump.h" | |
int main(void) | |
{ | |
int x,y; | |
struct sockaddr_un *sock; | |
struct msghdr *mhdr; | |
struct msghdr *rxmhdr; | |
struct iovec iov[2]; | |
struct iovec rxv[2]; | |
char take[1024]; | |
socklen_t *socklen; | |
struct pollfd fds; | |
char *dbus_path = "/run/user/1000/bus"; // <-- 'session bus' for uid 1000 | |
char *auth_string = "AUTH EXTERNAL 31303030\r\n"; // <-- other methods per docs but only seen this | |
char *dbus_hello = "l\1\0\1\0\0\0\0\1\0\0\0n\0\0\0\1\1o\0\25\0\0\0/org/freedesktop/DBus\0\0\0\6\1s\0\24\0\0\0\ | |
org.freedesktop.DBus\0\0\0\0\2\1s\0\24\0\0\0org.freedesktop.DBus\0\0\0\0\3\1s\0\5\0\0\0Hello\0\0\0"; | |
char *dbus_mesg = "l\1\0\1\0\0\0\0\2\0\0\0h\0\0\0\1\1o\0\20\0\0\0/org/freedesktop\0\0\0\0\0\0\0\0\2\1s\0\17\0\0\0\ | |
org.freedesktop\0\3\1s\0\7\0\0\0attempt\0\6\1s\0\27\0\0\0org.freedesktop.attempt\0"; | |
sock = malloc(sizeof(struct sockaddr_un)); | |
mhdr = (struct msghdr *)malloc(sizeof(struct msghdr)); | |
rxmhdr = (struct msghdr *)malloc(sizeof(struct msghdr)); | |
socklen = malloc(sizeof (socklen_t)); | |
sock->sun_family = AF_UNIX; | |
strncpy(sock->sun_path, dbus_path, sizeof(sock->sun_path) - 1); | |
socklen[0] = 256; | |
// preamble.. (you MUST do the poll() dance or nothing happens) | |
x = socket(AF_UNIX, SOCK_STREAM, 0); | |
fds.fd = x; | |
fds.events = POLLOUT; | |
printf("Connecting. .\n"); | |
connect(x, (struct sockaddr *)sock, 20); | |
fcntl(x, F_GETFL); | |
fcntl(x, F_SETFL, O_RDWR|O_NONBLOCK); | |
poll(&fds, 1, 0); | |
fds.events = POLLIN; | |
printf("Sending null. .\n"); | |
sendto(x, "\0", 1, MSG_NOSIGNAL, NULL, 0); | |
printf("Sending auth. .\n"); | |
sendto(x, auth_string, strlen(auth_string), MSG_NOSIGNAL, NULL, 0); | |
poll(&fds, 1, -1); | |
read(x, take, 1024); | |
printf("Server replies: %s\n",take); | |
sendto(x, "NEGOTIATE_UNIX_FD\r\n", 19, MSG_NOSIGNAL, NULL, 0); | |
poll(&fds, 1, -1); | |
read(x, take, 1024); | |
printf("Server replies: %s\n",take); | |
sendto(x, "BEGIN\r\n", 7, MSG_NOSIGNAL, NULL, 0); | |
fds.events = POLLIN|POLLOUT; | |
poll(&fds, 1, -1); | |
// tx vectors (like writev/readv) | |
iov[0].iov_base = dbus_hello; | |
iov[0].iov_len = 128; | |
iov[1].iov_base = 0; | |
iov[1].iov_len = 0; | |
mhdr->msg_iov = iov; | |
mhdr->msg_iovlen = 2; | |
// rx vectors | |
rxv[0].iov_base = take; | |
rxv[0].iov_len = 1024; | |
rxv[1].iov_base = 0; | |
rxv[1].iov_len = 0; | |
rxmhdr->msg_namelen = 0; | |
rxmhdr->msg_iov = rxv; | |
rxmhdr->msg_iovlen = 2; | |
// switch to sendmsg / recvmsg and do hello - should check the response here | |
printf("Sending hello\n"); | |
y = sendmsg(x, mhdr, MSG_NOSIGNAL); | |
hexdump(iov[0].iov_base, y); | |
fds.events = POLLIN; | |
poll(&fds, 1, 2500); | |
printf("Server replies\n"); | |
y = recvmsg(x, rxmhdr, MSG_CMSG_CLOEXEC); | |
hexdump(rxv[0].iov_base,y); | |
// end of preamble.. now prepare the actual message | |
iov[0].iov_base = dbus_mesg; | |
iov[0].iov_len = 120; | |
iov[1].iov_base = 0; | |
iov[1].iov_len = 0; | |
mhdr->msg_iov = iov; | |
mhdr->msg_iovlen = 2; | |
// and send it.. | |
printf("Sending message\n"); | |
y = sendmsg(x, mhdr, MSG_NOSIGNAL); | |
hexdump(iov[0].iov_base, y); | |
fds.events = POLLIN; | |
poll(&fds, 1, 2500); | |
printf("Server replies\n"); | |
y = recvmsg(x, rxmhdr, MSG_CMSG_CLOEXEC); | |
hexdump(rxv[0].iov_base,y); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment