Help, I'm unable to connect to openMSX

By konamiman

Paragon (1211)

konamiman's picture

31-07-2023, 16:26

I'd like to experiment with connecting to openMSX and sending commands from within my own scripts/tools, more precisely in C# and from Windows, since I think that would be very useful for my MSX developments. But so far my attempts have been unsuccessful, so I'm here in search for some help.

First, I've read the "Controlling openMSX from External Applications" page. I see here that it's possible to open a connection to openMSX using sockets, that's great since sockets programming in C# is a piece of cake! So here goes my first attempt:

var c = new TcpClient(AddressFamily.InterNetwork);
c.Client.Connect("localhost", 9962); //I've manually read the port from the socket.pid file
var responseBuffer = new byte[10000];
var size = c.Client.Receive(responseBuffer, responseBuffer.Length, SocketFlags.None);
var response = Encoding.ASCII.GetString(responseBuffer, 0, size);
response.Dump(); //I expect to have received "<openmsx-output>" here

But bummer, this doesn't work. The connection succeeds, but it gets closed after a few seconds without having received anything from openMSX.

By doing some googling I come up with this forum thread in which I see that apparently I need to manage some "SSPI authentication". And here goes my first set of questions: why is that? Why isn't this mentioned at all in the documentation, or in any of the documents in the openMSX GitHub repo (I have downloaded the entire repo to verify this) so I had to discover this elsewhere? Why isn't there a config/command line option in openMSX to disable the need for this authentication? That's quite frustrating.

Next I tried using named pipes, but that didn't make things easier. Yes, I can just run openmsx -control pipe and I see the <openmsx-output> prompt, and I guess that from that point I could send commands by typing them (although in practice, typing <openmsx-control> + enter throws "The syntax of the command is incorrect" and closes the program). But how do I control this from code? Second attempt:


var process = new System.Diagnostics.Process();
process.StartInfo.FileName = @"c:\Program Files\openMSX\openmsx.exe";
process.StartInfo.Arguments = "-control pipe";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.StandardOutput.ReadToEnd().Dump();

Result: the code freezes at the last line.

Now, by looking at Catapult, I see that it executes openMSX with a command line argument like -control pipe:Catapult-8664-14. So third attempt: running openmsx -control pipe:foobar and then this:


var client = new NamedPipeClientStream("foobar");
client.Connect();
StreamReader reader = new StreamReader(client);
reader.ReadToEnd().Dump();

Result: the code freezes at the second line.

At this point I decided to give up for now and ask for some help, and that's what I'm doing by writing this.

I'm sure that I'm doing something wrong and that controlling openMSX programmatically is actually easier than I think, so any pointers will be appreciated; but for what's worth, and if I'm allowed to rant a little bit, I think that it shouldn't be so painful for an experienced developer to get this up and running, and it should be enough with some "official" documentation reading, without having to dive through forums or source code repos. And that's it, end of the old man yelling at a cloud for now. :)

Login or register to post comments

By aoineko

Paragon (1138)

aoineko's picture

31-07-2023, 16:46

You may check openMSX debugger application to see how it communicate with a running instance of the emulator.

By edoz

Prophet (2501)

edoz's picture

31-07-2023, 16:38

I would be so cool to have network access in OpenMSX. Also for SymbOS development it is something it would be so nice to have. This will make it much easier for debugging ..

By santiontanon

Paragon (1831)

santiontanon's picture

31-07-2023, 19:47

At work now, but I was able to do this successfully from Java quite easily in the past without any authentication or anything and did a quick "code coverage" test app in Java that ran a ROM and stepped the execution step by step, logging the PC at each step. It was ridiculously slow haha, but it worked. Let me see if I can find the code after work

By wouter_

Hero (535)

wouter_'s picture

31-07-2023, 20:53

There are a few different ways to communicate with openMSX. In short:

  • To communicate with an already running openMSX instance you can connect via a socket.
  • To setup a communication channel with a new openMSX instance you can use a pipe or stdio.
  • If you only need to communicate at the start, then it might be easier to start openMSX with a Tcl script as a command line parameter.
aoineko wrote:

You may check openMSX debugger application to see how it communicate with a running instance of the emulator.

For the first option it's indeed best to look at some existing code, for example the connection code in the openMSX debugger.

On non-windows systems it's indeed as simple as:

  • connect to the unix domain socket
  • send commands
  • receive the response

Unfortunately on windows it's more complex. (Older) windows systems didn't have support for unix domain sockets yet (and for now we'd like openMSX to remain compatible with those systems). The closest approximation on windows are TCP sockets. HOWEVER, unlike unix domain sockets, any user can connect to a TCP socket. And because openMSX commands are a full featured programming language, they can do stuff like delete arbitrary files or copy files containing sensitive information (openMSX commands run with the same privilege level as the user who started the openMSX process). That's a big security risk. So on windows we require an extra authentication step. And unfortunately that's indeed not so easy to setup. But see the example code.

By santiontanon

Paragon (1831)

santiontanon's picture

31-07-2023, 22:16

Ah, then my example code would not be useful, as I use unix, and indeed it was as simple as wouter mentions.

By konamiman

Paragon (1211)

konamiman's picture

01-08-2023, 03:12

Quote:

any user can connect to a TCP socket. And because openMSX commands are a full featured programming language, they can do stuff like delete arbitrary files or copy files containing sensitive information (openMSX commands run with the same privilege level as the user who started the openMSX process). That's a big security risk. So on windows we require an extra authentication step.

Don't get me wrong, I think it's great that the openMSX development team is concerned about security and I understand the rationale for such a mechanism. But I also think there should be a way to explicitly disable it.

For the connection to be exploited to do evil either openMSX would have to be running in a multi-user environment, or the computer would have to be connected to a public network without any kind of firewalling for incoming connections. In most cases (I dare to say in the vast majority of cases) this won't be the case, so the need for authentication is a hurdle more than a help.

So what about adding something like a -control unsafe_socket command line argument, and/or a key for the settings.xml file? Add the explanation about the security risks to the documentation for the argument/setting, and let the user make an informed decision.

A simpler plain user-password authentication mechanism, available only when TLS is used for the connection if you want, would maybe be a good alternative too.

And for the love of Nishi, please update the documentation, right now it mentions absolutely nothing about that security mechanism. Yes I know I could open a pull request myself but so far I don't fully understand it and I'm unable to make it work so it would be quite pointless.