How to request serial port permissions with polkit on Linux? - c++

I'm writing a cross-platform app that I would like to run on Linux-based operating systems like Fedora and Ubuntu. I use QSerialPort and it works fine. I can use QSerialPortInfo to get a list of serial ports in the system and present them to the user who can select which one s/he wants to use.
However, on Linux systems, by default the user doesn't have permissions to the serial ports. I know that it is wrong to run my app with sudo and I also know that it is not user friendly to ask the user to run chmod 666 on the serial port manually every time the app is used. So I looked around and it seems to me that polkit is the answer, however I haven't been able to find any example which would show me how to do it.
Can you please tell me how to use polkit (formerly known as policykit) to request permission for my app to use a specific serial port?
EDIT:
What I'm looking for is a way to:
Check if the user has access to the serial port
If not, pop up a dialog that asks for permission (like the Gnome settings app for example)
If the user authenticated successfully, make the serial port available to the app.
Some more thoughts
I do NOT want to set up an udev rule that gives perimission to every serial port
I do NOT want to ask the user to run a script
I do NOT want my app to run as the superuser
I do NOT want any other actions performed as root, just the serial port access
Yes I've found the official polkit docs, but they are not very clear on how to do this.

General thinking:
It is not a good idea to try to make an application "universal".
I understand that you want your software to be easy to use, but for things like this (system's settings), you should rely on the system packagers.
At anytime, polkit can be replaced by another solution, or ressource's name can be changed, or whatever and your application would be no more usable.
I advise you to:
at most, raise a polkit windows that woulde ask for password
or better, to make distribution packages that will do the necessary tweaks through regular scripts
An idea
I didn't do it (but I played a lot in the past with pam :-) )
So here are links that I found and what I understood:
polkit acts the same way as sudo do: it allow you to run program with another identity (explanations)
so you can run your program either as root or as one having enough right access to the serial
So you could create:
an install script that allow to run your program with the good identity (e.g. example). That way you would ask root password once (at the install for creating the polkit policy), and each time the user wanted to run your program. That identity maybe root or any identity as long as that identity has R/W access.
a policy file: you can look either at 1 or documentation
a script for lauching your program containing something like this: pkexec <path>/<pgm>
Here are some pointers:
an admin guide to polkit: 3
(I'm a debian user but I like their docs)
the official documentation: https://www.freedesktop.org/software/polkit/docs/master/index.html

Related

Best way to pass variable to remote (Golang) app from Django View

I'm creating a Django web application that'll assist in barebone server deployments, where a bare bone server will PXE boot to a custom LiveCD to send a cURL command to register itself to a DRF REST API.
When Django receives the POST request it'll start a Go app remotely that'll find the bare bone server based on entries in the REST API then start configuring the server. What would be the best way to identify/introduce the bare bone server to my Go server?
My thought is either to use a parser parameter to identify the server then Go will pull the bare bone server info from the REST API or add a Boolean field in the REST API and the Go app will look for entries that are TRUE then flip it to FALSE when it starts setting up the bare bone server.
Would that be the best way to get this done or is there a better way?
Actually, PXELINUX comes with an identification mechanism based on the systems MAC dress and the configuration can be customized accordingly. Since you need to do accounting of your bare metal servers anyway (port security anyone? ;) ), you should know the MAC dresses of all the interfaces on your bare metal servers anyway.
Your directory usually looks like this (path prefix may be different).
/srv/pxe/pxelinux.cfg/default
Now what happens is that your system starts up, sends a DHCP Request and gets an offer containing the DHCP options "next-server" and "filename". When the system selects said offer, it will connect to the "next-server" and request "filename", usually pxelinux.0. Here is your first potential hook: Write a tftp server which deals with the request and registers your system.
Now pxelinux.0 is executed , it will read the above config file. But here is the thing: Say the Mac address of the system is 23:67:33:5a:cc:e8, and the file
/srv/pxe/pxelinux.cfg/23-67-33-5a-cc-e8
exists, this will be read instead. Which is your second hook: the request will be logged by tftp.
Regardless of wether the default or a system specific config file is used, basically we are talking of GRUB config file. Assuming you use Kickstart to install the system, it will look something like this
default linux
prompt 0
timeout 1
label linux
kernel /images/yourdistro/vmlinuz
ipappend 2
append initrd=/images/yourdistro/initrd.img console=ttyS0,115200
Now, here is the thing: you have several possibilities to execute a custom program on boot:
Append the path to your executable to the append parameter. By convention, the Kernel will send all parameters it does not know to pid 1. Though I have not tested wether systemd adheres to the convention and simply executes a parameter it does not know in turn, I assume as much.
cron. Most cron implementations nowadays support the #boot time definition.
the init system, be it either systemd or openrc or good ol' SYSV init.
Last but not least, how to configure the machine. I strongly suggest against reinventing the wheel. I had quite similar requirements in a (closed source) project. We used kickstart to do the basic system installation and simply shot a curl command after reboot to Ansible Tower, triggering the more detailed configuration. Since we had a DHCP server with the MAC, an IP reserved for said MAC and a hostname readily configured (dnsmasq, caugh, caugh), that was not much of a problem. Basically, all we had to do manually is to register the MAC address and assign an IP and a hostname, then fire up the machine.

Send keystrokes to guest os with vmrun

I can't find documentation or examples of how use typeKeystrokesInGuest command of vmrun tool.
I tried send key code, like 30 and I try send Some text, but always got
Insufficient permissions in the host operating system. I think, I must give right permission, but I don't know where, and I don't know is I use described command in properly way.
If I remember right, vmrun uses the VIX API which is slated to be deprecated. A new option is to use the PutUsbScanCodes method that is available with the vSphere 6.5 API and does not have a dependency of VMware Tools running on the guest OS.
More information is available at the following: https://www.virtuallyghetto.com/2017/09/automating-vm-keystrokes-using-the-vsphere-api-powercli.html
Govc it's supposed to do this job as well I have found a bug which I'm hoping they'll fix soon

Telnet server within C++ app

I am writing an application to run on a robot. Currently, it is headless, but I want to be able to telnet directly to the application with no authentication and access a shell that I will write.
Is this possible? Would it be practical or are there much easier solutions?
It is entirely possible.
However, if you are using Linux, you may just as well just let your application do it's I/O to the terminal, and use telnet to log in. If you set up a user to use your application as the "login-shell", it will allow direct access to that user called "robot" (for example) (and you can set it to have no password too) - then just do telnet -l robot machine port.
This would save you the effort of writing your own telnet client, and give you almost identical functionality.
If you're using a custom shell, why would you need telnet? Your shell can have a daemon component to listen on given port and then hand over the interaction to whatever REPL your shell would implement.

Run Linux command remotely from Window based application

I want to run Linux command remotely from Window based Qt C++ application programmatically. What is the simpliest way to do it?
You need some sort of server on the Linux machine and your Windows machine will be a client. I'd say the easiest way would be just make a php script to run your command and drop it in your www root and have your Windows machine fetch that URL.
At the end of the day, without knowing what your requirements are with regard to security and with regard to what kind of commands you'll be running is, it's very difficult to give a definitive answer to this question.
Simply connect to telnet server on the linux using sockets, and send the commands.
This actually requires very little code. Check the Java version here:
Sending telnet commands and reading the response with Java
You can do similarly with Qt/C++ as well.
Simple server-side program witch will handle the requests and then using ex system() function will be this "remotely" part of solution.
And on client-side simple text field handled by function witch will be able to connect to server to send command run request.
The most important thing in this solution will be to take care about security.
One way to do it is, to have a client-server model, the server resides in linux and client can be your computer. That way you can send commands to the server and have its output thrown at you. That's one way I think of this problem.
Use UPnP to get past the firewall(or use NAT traversal or UDP/TCP hole punching). Otherwise (without forwarding the port) it would be impossible to reach the server.
The second is to write your own RSH and SSH utility. (or use putty or other pre-existing software)
You could use Plink if you are on Windows whatever version. If you can run PuTTY, then you can run PLink. PuTTY Plink Documentation. Using that you could use the executable, and automate things. Otherwise, if you're looking for a specific programming language, they'd still be dependent upon some SSH Library. If you're writing your own installer, you could include the PLink.exe in your installer, and distribute it with your application.
From the documentation page:
Z:\sysosd>plink login.example.com 'echo "Hello World"'

how to read list of running processes on a remote computer in C++

What can be done to know and list all running processes on a remote computer?
One idea is to have a server listening to our request on the remote machine and the other one is to use ssh.
The problem is i dont know whether there will be such a server running on the remote machine and i cannot use ssh because it needs authentication.
Is there any other way out ?
If you
cannot install a server program on the remote machine
cannot use anything that requires authentication
then you should not be allowed to know the list of all running processes on a machine. That request would be a security nightmare!
You can do something much simpler without (as many) security problems: scan the publicly-available ports for programs that are running. Programs like nmap.org let you know a fair bit of information about the publicly-running programs on machines.
I have done something similar in the past using SNMP. I don't have the specifics in front of me, but something like "snmpwalk -v2 -c public hostname prTable" got me the process table. I recall later configuring SNMP to generate errors when the number of processes didn't meet our specified requirement, like httpd must have at least 1 and less than 50.
I suggest you look at the code for a remote login, rlogin. You could remotely login to an account that has the privileges that you need. Once logged in, you can fetch a list of processes.
This looks like a good application for a script rather than a C or C++ program.