I am running an ssh tunnel from an application using a QProcess:
QProcess* process = new QProcess();
process->start("ssh", QStringList()<<"-L"<<"27017:localhost:27017"<<"example.com");
So far it works great, the only problem being that there is no way for me to see when the port has actually been created.
When I run the command on a shell, it takes about 10 seconds to connect to the remote host after which the forwarded port is ready for usage. How do I detect it from my application?
EDIT:
As suggested by vahancho, I used the fact that post-connection there is some output on the terminal that can be used to detect that the connection has succeeded. However, there is a line which is run instantly after launch Pseudo-terminal will not be allocated because stdin is not a terminal, which probably would give a false alarm. The correct output is available in the second signal, emitted a bit later (which is a true indicator of the port having being opened). To get rid of the first message, I am now running ssh using ssh -t -t to force an stdin allocation.
So, the only question left is, can anyone help me without any concerns in this approach?
So, the only question left is, can anyone help me without any concerns in this approach?
This is not a stable and robust solution, unfortunately. It is similarly a broken concept to handling git outputs rather than using an actual library. The main problem is that these softwares do not have any guarantee for output compatibility, rightfully.
Just imagine that what happens if they have an unclear text, a typo, et all, unnoticed. They inherently need to fix the output respectively, and all the applications relying on the output would abruptly break.
This is also the reason behind working on dedicated libraries giving access to the functionality for reuse rather than working with the user facing output directly. In case of git, this means the libgit2 library, for instance.
Qt does not have an ssh mechanism in place by default like you can have such libraries in python, e.g. paramiko.
I would suggest to establish a way in your code by using libssh or libssh2 as you also noted yourself in the comment. I can understand the inconvenience that is not a truly Qt'ish way as of now, but at this point Qt cannot provide anything more robust without third-party.
That being said, it would be nice to see a similar add-on library in the Qt Project for the future, but this may not be happen any soon. If you write your software with proper design in mind, you will be able to switch to such a library withour major issues once someone stands up to maintain such an additional library to Qt or elsewhere.
I had the same problem, but in my case ssh do not output anything - so I couldn't just wait for output. I'm also using ssh to setupt tunnel, so I used QTcpSocket:
program = "ssh";
arguments << m_host << "-N" << "-L" << QString("3306:%1:3306").arg(m_host);
connect(tunnelProcess, &QProcess::started, this, &Database::waitForTunnel);
tunnelProcess->start(program, arguments);
waitForTunnel() slot:
QTcpSocket sock;
sock.connectToHost("127.0.0.1", 3306);
if(sock.waitForConnected(100000))
{
sock.disconnectFromHost();
openDatabaseConnection();
}
else
qDebug() << "timeout";
I hope this will help future people finding this question ;)
Related
I'm writing a transparent intercepting HTTPS capable proxy using boost::asio + openSSL. I have a default server context where I specify that the server is a TLSv1.2 server, when a client connects, I extract the host from the hello and use SSL_set_SSL_CTX to set the context (which either already exists or I've just created it after spoofing the upstream cert) and initiate the server (downstream) read/write volley as well as the upstream.
This was working before I started storing and sharing contexts. On each new incoming connection, I was creating a new client socket and context, loading ca-bundle as verify file, then creating a new server context, getting the spoofed certificate. It was functioning, but I started developing issues where EC_KEY objects were being double freed and such. I learned from another question of mine that I was going about this the wrong way and began refactoring to recycle and share CTX objects. To be specific, I'm using a single client CTX shared across the board that loads, at program startup, the CA-Bundle for verification.
However, since this refactor, I'm getting this on both the client and the server:
decryption failed or bad record mac
..mixed with a bajillion "short read"s. If I try to force everything TLSv1.2, I get
block cipher pad is wrong
Those errors are given to me after a read/write has failed and I call async_shutdown on either upstream or downstream sockets, which in the callback, error is set (so the shutdown failed).
I've scoured the interwebs finding jira posts from places like apache httpd and nginx where this error was fixed in different ways (resizing read buffers to be larger, openSSL patches, forcing SSLv3, so on and so forth).
I thought there might be an issue with multithreading (my io-service uses a thread pool) but I can see in the code that boost do_init sets locking mechanics for openSSL and all of my IO are wrapped into a single strand.
I'm at a total loss and am wondering if anyone can shed light on what might be happening. I realize I've posted no code, that's because I've got hundreds and hundreds of lines of it and don't want to turn people off with a huge code dump. I realize however this is a rather complicated program and thus a complicated issue so please ask and I'll provide whatever I can.
Edit
I guess I should mention for completeness that I'm getting these errors on both openssl 1.0.2 and 1.0.2a, Win 8.1 x64 and I'm intercepting and routing the http/https traffic through my proxy with with WinDivert.
Edit 2
Reduced entire program to 1 thread, same effect. Created new client CTX for each client connection, same issue. Tried disabling AES-NI, issue persists. Tried different computer, same effect. Recompiled openssl from source (was using precompiled binaries), issue persists. Tried setting additional OP_ workaround flags described in current docs related to downgrade detection, padding bugs, so on and so forth, issue persist. I think I'll just start randomly mashing the keyboard and compile button soon.
I was going to just delete this question, but I decided to answer it in light of the fact that nowhere on the net (that I could find) actually pointed to a correct solution to this problem. I've read every single report about this error that one could find and every single one of those reports, the people "solved" or "reduced" this error in a different way. Every single one of them, a different solution. This is what helped make this issue so difficult to reason out, because everyone everywhere has a different underlying causal explanation.
It's complicated, ready? This error will present itself if you cancel/abort a pending async SSL operation. Mind->boom(). It'll be even more confusing if you do what the docs say and use async_shutdown to do so, because even the call back to async_shutdown will fail (error code is set) and your error message will randomly be something stupid like "decryption failed or bad record mac" or "block cipher pad is wrong" or "SSLv3 alert!" so on and so forth. When seeing errors like this, ignore the errors and analyze the control flow of your IO ops, somewhere you're either prematurely ending them or getting them out of order.
In my case, the premature end was (sort of) intentional, since during this stupid heavy refactor I decided to change things outside the scope of the problem, like my HTTPHeader parser, which I bugged out and ended up cause it to fail nearly 100% and thus aborting the connections. :) The error strings were masking the real cause by telling me encryption failed for some reason or another. Dumb mistake I know, but I take comfort in being the first one (apparently) to recognize it. :)
Open a powershell and type this
(Invoke-WebRequest -Uri status.dev.azure.com).StatusDescription
https://devblogs.microsoft.com/devops/deprecating-weak-cryptographic-standards-tls-1-0-and-1-1-in-azure-devops-services/
I was recently asked how/if possible that one could do this. I am not sure if it is even possible, and I have been searching on it for a while now.
Basically let's take Windows for example there is a system command to shut down the computer. Let's say shutdown -s -t 30 -c "Shutdown"
Is there a way to write a program which will listen for a shutdown command, and then run shutdown -a in response to abort that command?
In short, can you make it listen for certain system commands on the computer and execute system commands in response?
This is indeed possible. Your example, however, is probably not the best one to describe a generic problem. There are session events in Windows that applications can listen to, and shutdown is one of them. And after all, shutdown.exe is not the only application that can ask Windows to shut down.
In general, however, applications “listening” for commands being executed will have to integrate tightly with the operating system. You can imagine that anti-virus software does exactly that and a lot more in order to prevent execution of
“bad” programs. I am not familiar with Windows technology but would imagine hooking the Windows system call that executes binaries is the way to do it. For sure that will require "administrative" permissions and can even require to write a kernel module.
You can go this way:
Check if the program is exiting.
If yes, then cancel the program exit call and execute system("shutdown -a);
Else, do what you want.
Well, probably there many more sophisticated ways to do that. And I agree with #VladLazarenko's answer; programs like antiviruses keep listening to system commands. But I guess that would require in-depth knowledge of the API. This is just a simple way to do that. If you are not a newbie, then you must visit this link, http://www.codeproject.com/Articles/2082/API-hooking-revealed (from #RedX's comment). Good Luck! :)
this might be something obvious but i cannot for the life of me figure it out. Ever since we did a server reboot, a C++ program using mysql++ to connect to our database has just returned 0 rows for all queries instantly. My first thought was that my.cnf might not have been loaded correctly but it appears that it was, after checking show variables and comparing.
any suggestions? is it possible that some directory setting is failing to find some .so needed for mysqlpp that I don't know about?
any advice appreciated.
any suggestions?
Sure:
Ensure that you're checking all error code returns if you've disabled exceptions.
If you haven't disabled exceptions, check that each catch block that could be involved isn't just quietly eating the error.
The MySQL C API library (and therefore MySQL++) is probably trying to tell you what went wrong, and you're suppressing it or ignoring it somehow.
Build and run the examples. If they fail in the same way as your program, it means the problem is broad in nature. The examples have good diagnostics, so they may guide you to the problem.
If the examples work fine, then the problem is specific to your program or its data. So, separate the cases:
Does the program work on a different machine against a DB with the same structure as the problem machine, but different contents?
If so, does it still work on that machine when you load a copy of the problem DB into the second machine?
And if that still works, does it work when you access the remote machine's DB directly from the system that does work? (Be careful with this one. You want to have SSL set up on the MySQL DB connection itself, or have some kind of secure channel to it, like a VPN or SSH tunnel.)
If you run that gauntlet successfully, it means the problem is with the program itself on the original machine, or with the program's environment. Libraries or permissions, as you've speculated, are one possibility.
Run your program under a debugger.
Try gdb first, because what we're interested in is whether the debugger sees any exceptions or signals thrown. Maybe the program is core dumping, for example.
If gdb gives the program a clean bill of health, try valgrind. If Valgrind complains about your program, chances are good that it's complaining about something legitimate; maybe harmless, but legitimate. If you get complaints, and you found above that the problem is specific to one machine, I recommend re-trying the Valgrind run on the system where the program runs successfully. Fix those problems, or at least rule out the harmless warnings before continuing debugging on the original problem machine.
is it possible that some directory setting is failing to find some .so needed for mysqlpp that I don't know about?
It's easy to check:
$ ldd myprogram
You should get a report listing all the shared libraries your program is linking to, including their full paths. Any that are missing or unreadable by the user running ldd will be indicated.
Our app is ran from SU or normal user. We have a library we have connected to our project. In that library there is a function we want to call. We have a folder called notRestricted in the directory where we run application from. We have created a new thread. We want to limit access of the thread to file system. What we want to do is simple - call that function but limit its access to write only to that folder (we prefer to let it read from anywhere app can read from).
Update:
So I see that there is no way to disable only one thread from all FS but one folder...
I read your propositions dear SO users and posted some kind of analog to this question here so in there thay gave us a link to sandbox with not a bad api, but I do not really know if it would work on anething but GentOS (but any way such script looks quite intresting in case of using Boost.Process command line to run it and than run desired ex-thread (which migrated to seprate application=)).
There isn't really any way you can prevent a single thread, because its in the same process space as you are, except for hacking methods like function hooking to detect any kind of file system access.
Perhaps you might like to rethink how you're implementing your application - having native untrusted code run as su isn't exactly a good idea. Perhaps use another process and communicate via. RPC, or use a interpreted language that you can check against at run time.
In my opinion, the best strategy would be:
Don't run this code in a different thread, but run it in a different process.
When you create this process (after the fork but before any call to execve), use chroot to change the root of the filesystem.
This will give you some good isolation... However doing so will make your code require root... Don't run the child process as root since root can trivially work around this.
Inject a replacement for open(2) that checks the arguments and returns -EACCES as appropriate.
This doesn't sound like the right thing to do. If you think about it, what you are trying to prevent is a problem well known to the computer games industry. The most common approach to deal with this problem is simply encoding or encrypting the data you don't want others to have access to, in such a way that only you know how to read/understand it.
Is there any way to use the signals without MOC and without the connecting via names? My one problem with Qt is that you have something like
this->connect(this->SaveBtn, SIGNAL(click()), SLOT(SaveClicked()));
And there is no error detection to tell that is wrong other then finding out the button doesn't work or searching through their documentation to find out the signal doesn't exist. Also it seems pointless and a waste of cycles to connect via names instead of classes.
There is error detection, the connect function returns false when it fails to connect, and a warning is output on standard error (or, on Windows, to the weird place which DebugView reads from). Also you can make these warnings into fatal errors by setting QT_FATAL_WARNINGS=1 in your environment.
It's not pointless to connect by name. For example, it means that connections can be established where the signal/slot names are generated at runtime.
Other than the fact that signals are just methods, no I don't think you can use them like they are intended without the intermediate MOC step. It is a pain when you mess up the connection and there is no flag raised. What does your last sentence mean? Can you elaborate what your problem is? Signals/Slots is not a perfect system, I don't think a perfect system exits, but it is pretty intuitive and has worked well for me.
No, there is no real way around that.
You'll have to use MOC and connect via names. But with time you'll find out that it "grows on you" and won't really bother you. Train yourself to add code in small snippets each time, testing that what you added works, and you'll have no trouble with this.
I normally Practice following style of coding,
m_pCancelPushButton = new QPushButton(tr("Cancel"));
m_pCancelPushButton->setObjectName("CancelButton");
//MetaObject Connections
QMetaObject::connectSlotsByName (this);
This enable me to write code
void Class_name::on_CancelButton_clicked()
{
//Do your job here.
reject();
}
I hope it will help you.
Thanks,
Rahul