How to spawn Linux process from Windows application? - windows

My interactive 32-bit Windows app (now moving from Delphi [Ent] 2007 to 2009) uses command-line interactions to spawn child processes that do computationally-intensive tasks, which in turn write text files that the GUI parent app parses and analyzes - resulting in an interactive graphical display of the results.
I have access to a multiprocessor (multi-user) Linux cluster (via ssh), and would like to off-load the heavy lifting to that cluster. My question is how to spawn the processes in Linux from my Windows app. I can envision using secure FTP to put and get files, but not sure how to spawn the child processes in Linux.
Some leads for further reading would be fine - but code/pseudocode would be ideal. I can imagine that this may be more about Windows-Linux interaction than Delphi.

if you have access to ssh, one option is to issue commands through that.
For example:
ssh user#host ls -l ~
will in the ssh terminal show the files in the user's home directory. I'm not sure if this is what you really want. But it would likely work.
If you do this, you almost certainly want to setup SSH password less logins
However, A more ideal solution would likely be to setup a daemon on the linux boxes whose sole job is to run specific long running tasks in the background and let you fetch the results later.

You're going to have to install something on the Linux machine to run the process. You might find some kind of clustering or batch job submission API you can install and access from Windows. You might have to code a custom server. You might be able to run everything over ssh if you can drive an ssh process from Windows and if you have sshd installed on the Linux side. But my preference would be to write a webservice or simple CGI script on the Linux side designed to take your arguments and data and return the result over plain old http (or https as the case might be).
One way or another, this is going to encompass more than just coding on the Windows side.

I would download the full "putty" package.
As well as the excellent secure shell terminal, it includes PSCP to transfer files securely and PLINK to remote execute commands over SSH.
Hint: you will need to set up the full public/private key configuration for PLINK to work without an annoying password prompt. There is a useful guide http://unixwiz.net/techtips/putty-openssh.html>here.

Related

Copy files from remote Windows machines with command-line, through RDP

Our team has ~80 Windows development machines, and activities of each developer are logged as text files on the local storage of those machines.
To analyze the logged activities, I want to gather all log files from those machines. Additionally, the log files are updated constantly, so It is desirable to gather files with the command-line from my machine.
I’ve searched and found some solutions, but all of those are not suitable for our situation:
We cannot use PsExec, because tcp/135 and tcp/445 are both closed (countermeasure for WannaCry).
Administrative share is disabled.
telnet service is not up and is banned by security reasons.
WinRM is disabled on those machines by default.
It is difficult to install new software like OpenSSH on those machines (because of the rule of this project)
RDP is the only way to connect those machines. (I have an account on all machines)
How can I copy files from remote Windows machines with command-line through RDP?
Or, at least, is there any way to execute a command on remote Windows machines with command-line through RDP?
I think you can do this, though it is very hacky :)
For a basic setup, which just copies files once, what you would need to do is
Run a script in the remote session when it logs in. I can think of three ways to do this:
Use the "Alternate Shell" RDP file property. This runs a specified program in place of explorer.exe on login; you can use it to run "cmd.exe /c [your script]" for instance.
If that doesn't work (e.g. the remote machine doesn't respect it), you might be able to use a scheduled task that runs the script on login, but perhaps only for a specified user, or maybe the script could check the WinStation type to make sure this is actually an RDP connection before doing anything.
It's also possible to do this by connecting in RemoteApp mode and using the script as your "application", but that only works for Server and Enterprise editions of Windows.
Enable either drive redirection or clipboard redirection on the RDP connection, to give you a way to get data out.
Drive redirection is much simpler to script; you just have the remote script copy files to e.g. "\\tsclient\C\logs".
Clipboard redirection is theoretically possible - you have the remote script copy, then a local script paste - but would probably be a pain to get working in practice. I'm only mentioning it in case drive redirection isn't available for some reason.
You would probably want to script to then log the session off afterward.
You could then launch that from command-line by running "mstsc.exe [your RDP file]". The RDP files could be programmatically generated if needed (given you're working with 80 machines).
If you want a persistent connection you can execute commands over, that's more complicated, but still technically possible. Two ways I can think of:
Use the previous method to run a program on logon, but this time create a custom application that receives commands using a transport that isn't blocked and executes them in the session. I've done this with WCF over HTTP, for instance; it's not secure, of course.
Develop and install a service on the remote machine that opens an RDP virtual channel, and a corresponding RDP client plugin that communicates with it. You can then do whatever you want across the connection. While this solution would be the most likely to work, it's also the most heavyweight and time-consuming to implement so it's probably a last resort.

How would I create an SFTP connection if my application framework does not contain an API for it?

I am trying to connect to an SFTP server with my AIR application. It doesn't matter that it's an AIR application except that I haven't found any libraries or AIR API methods for it.
My first thought is to find a library in another language and rewrite it in ActionScript. I'd rather not do that and my lack of experience may introduce security issues.
My second thought is to call a native process or command such as sftp or sshpass or curl from my main application and pass the local and remote upload locations to it and let it do the work. The downside to this is if they don't have the command installed they have to install a separate program.
My questions are:
Are these SFTP commands available by default on both Mac and Windows?
Should I store the users login (I do not want to) or prompt them to enter it each time? Does SFTP / public key remove the need for that?
I've found two related questions here and here but some of it is over my head. They also seem to be specific to *nux (which may work for Mac as well but not Windows).
I do not have the experience in this area so I would welcome those with experience to give guidance if this is a good idea or not. Overview type answers are welcome for me as I can attempt to work out the details. If no answer is given, once I've figured it out I'll post an answer. Please do not close this question (rather suggest edits).
FYI I'm using AIR to make a native process call.
An AIR application in the extended desktop profile can execute a file,
as if it were invoked by the command line. It can communicate with the
standard streams of the native process. Standard streams include the
standard input stream (stdin), the output stream (stdout), the
standard error stream (stderr).
I can also create and call a scpt, sh or bat file.
Commands installed on my Mac:
curl_init(), curl_setopt()
ssh
sftp
Commands not installed on my Mac:
sshpass
Are these SFTP commands available by default on both Mac and Windows?
No. There is no sftp nor ssh on windows by default, unless you install it through cygwin or bundle them in your application (also solution).
Should I store the users login (I do not want to) or prompt them to enter it each time?
Prompt is preferred.
Does SFTP / public key remove the need for that?
Yes, but you will have to store private key, which is almost the same like storing password.

Have a Linux shell script stuff a string into a Windows user's copy/paste buffer

We have a script right now which our Windows users run on a Linux host by way of putty. From time to time the script produces a string that the user must copy and paste into a Windows application.
Without running a full-blown X display server on the Windows box, I'd like to modify the script so that the string is populated in the Windows user's copy/paste buffer automatically so that it's more convenient for the user and so that we reduce the error rate (the workflow is clumsy enough, we'd like to make it a little less so).
Here's what I don't consider solutions:
Running a full blown X display manager on the Windows side just for this (if there exists a nearly invisible utility that enables just this one feature that's a different story)
Make the user stop running Windows
Rewrite any other applications
I have full control over the Windows user's environment (can set up whatever putty settings I need to) as well as the Linux host and every node in the network between the two.
If I had to do this I'd probably grab the sources to putty and modify it to suit.
Failing that I don't think you'll be able to easily do this; except by writing a small script on the Linux box that will open a socket to the a small windows deamon and send the text across to be put into the Windows clipboard.
If the remote script doesn't need full terminal support but only does simple stdin/stdout operation, then you might be able to use plink to provide a simple text-only interface which can probably be scripted more easily than a full PuTTY window.
http://ericmason.net/2010/04/putty-ssh-windows-clipboard-integration/
This guy's script patches putty to just what was suggested above. I think it would be more elegant to have just a printer driver you can install in windows to get text to the clipboard, rather than patching putty, but this works!

How to ask a remote windows machine to automatically launch an application?

I have a windows server 2003 up in the internet.
But sometime I need to restart it.
After restart, I want one of the applications to run.
I want to do this all programatically.
I can now remotely restart the server.
But the question is how can I ask that piece of software to be executed (more precisely, I want to execute a .BAT file to ask a tomcat to run)?
Because I don't want to manually log in to the machine and start that application. That is time consuming. Is there any possible way, once the machine is started, my application will be run as well?
If you're developing an application that should always be running on the server, you probably need to implement it as a Windows service. For C#, see the classes in the System.ServiceProcess namespace -- you will need to inherit from ServiceBase.
Alternatively, you can set the program to be run as a scheduled task on boot. See the Task Scheduler API to do this.
You can install Cygwin and then do it the same way we'd do it on a Linux box: via ssh, using keys.
OpenSSH is not part of the default Cygwin install, so be sure to select it. It's in the Net category.
Then, after you've installed Cygwin and sshd, read /usr/share/doc/Cygwin/openssh.README to learn how to set up sshd as a service, so it will answer requests automatically, without you having to start the ssh daemon manually.
Finally, set up keys, as described in the link above.
Part of the ssh protocol is a way to ask a remote machine to launch a program. Setting it up with keys lets you do it without needing a password.
You could try xCmd, which is a freeware app to run a command on a remote machine.

Invoking windows batch file from Linux

I have an application running only on Windows and a batch file that launches it.
I want to invoke this batch file from Linux, meaning something like Linux batch will launch the windows batch with parameters and this in its turn run my application.
Can I do that? How?
You could install an ssh server in the windows box (Cygwin has one), then from linux do something like:
ssh user#windows-box c:/path/to/batch.cmd
and that should launch your application in the windows box.
The most direct way is probably to install an ssh server on the windows box. Cygwin includes an ssh server.
Depending on how precise your timing needs are, you might be able to have an "at" job on the windows box that runs periodically (every 5 minutes?) and runs if it sees that a particular file exists, deleting the file. Then you could use Samba/smbclient to create the file. You would need to turn on filesharing on the windows box for this to work.
If the windows box has a web server, you could write a CGI, and trigger it using wget or cURL.
Our build process currently goes the other way: a windows sever kicks off things on the Linux server using plink (part of PuTTY). You might be able to set something similar up.
This may cause a security issue. Our information security person did not allow me to invoke any programs directly.
The safer way is to set up server on Windows computer. This can be a web-server for example. And then invoke your process inside PHP/Perl/Python script.
Also look at winexe that allows you to execute windows commands/batch scripts without running ssh server.

Resources