kinnay / NintendoClients

Python package to communicate with Switch, Wii U and 3DS servers
MIT License
558 stars 68 forks source link

Friends server example #4

Closed mrexodia closed 5 years ago

mrexodia commented 5 years ago

This is an example implementation of a local friends server. It implements just enough to (in theory) start Super Mario Maker. Any comments are welcome, but this is a work-in-progress (I will confirm if SMM actually 'works' with this friends server)...

All data used is fully anonymized and it does not need a token from the account server to work (since it uses the credentials 1337:password which are hardcoded in the server). I use this as a base for capturing packets and trying things without connecting to Nintendo servers.

Also a question about the .proto files: are those still updated?

kinnay commented 5 years ago

In my opinion an example script should show the proper way to implement something. Hardcoded keys, such as session_key = b'R' * self.settings.get("kerberos.key_size"), are obviously not something you should do on a real server. Also, there is no need to override a method if you just copy the implementation from the base class.

Ideally, the example server would mimic the real server as close as possible. For example, SECURE_SERVER_KEY should be derived from the password of the target account. I'll probably write an example server myself at some point, because I think I know best how the servers are supposed to behave.

The .proto files are still the right way to add methods to the client. The generated python files shouldn't be touched because the changes will be lost if they're regenerated.

kinnay commented 5 years ago

I decided to write an example server myself (example_server.py). I appreciate the effort though.

mrexodia commented 5 years ago

Did you include this fix?

except ConnectionResetError: pass

mrexodia commented 5 years ago

You also seem to have missed the standalone client connection example and the IPs hardcoded in your server don’t work on the local machine. And the actual implementation of the friends server is also missing.

kinnay commented 5 years ago

I fixed the ConnectionResetError and ip address, thanks.

I don't really see the point of adding another client script. The main goal of this package is to provide a way to talk to Nintendo servers. An example script whose sole purpose is to connect to a custom server doesn't really fit here in my view. If you need one anyway you can modify one of the current example scripts.

The purpose of the example scripts is to show how this package can be used because there isn't any documentation for its classes. They should be as simple as possible, but still reflect a possible implementation of a real server or client. Any implementation of the friend service would either be too complex for an example script or far from how it would be implemented in a real server. Your implementation just returns a hardcoded response, which is not really useful. My implementation of the authentication service shows how server methods can be implemented, and if you want any other methods you should implement them yourself.

mrexodia commented 5 years ago

My perspective is a little different. When I started looking into the Nintendo server stuff it would have been tremendously useful to run a completely standalone example environment just to get the tooling up and running (nex-dissector most notably). In addition a completely standalone combination of simple client/server scripts allows for easier testing and bugfixing. And it allows us to share packet captures without risking our accounts or spending significant time anonymizing them.

For example the packet (de)fragmentation is implemented incorrectly currently. Just being able to run a server/client combination locally without touching Nintendo services is, for me, the most comfortable way to fix those kind of things. Standalone working scripts also add to your test harness. While not automated right now, adding more examples that can be run without modifications can give more confidence that changes to the protocol implementation do not break other things.

The friends implementation I did, while hardcoded and dummy (no friends), works on real games and it took me quite a while to figure out how to craft the response correctly. Obviously I already did the work, so nothing is lost for me, but I think it makes sense to store that work in a centralized place so someone else can pick up where I left off, without having to waste time on implementing their own dummy friends server that they could have gotten from here.

Another off-topic question, how do you take contributions to the wiki? I found some missing/incorrect fields, should I just create an issue?

kinnay commented 5 years ago

You might be overestimating the scope of this repo. The main incentive of this project is to research how the game servers work. Developing new servers is what other projects (such as pretendo) are for. The only reason I wrote the server classes was to test an exploit on the real client.

I'm not entirely against expanding the scope however (as long as it stays within certain limits), and you did convince me that a standalone client/server combination could be useful. I'll probably write up a simple example script later today.

I still think a friend server implementation does not belong into an example script. The response is built the same way as in the auth server. You just need to set different attributes, which you can easily look up in the .proto files.

I don't really care how you contact me about the wiki. An issue is fine.

kinnay commented 5 years ago

Here: example_server_login.py. This should be enough to test at least the PRUDP connection, the RMC protocol, authentication, and secure server encryption.

mrexodia commented 5 years ago

Work for me, thanks :) I'll just push whatever implementations I do on a separate branch and open pull requests only for bugfixes or missing features next time.