Terrible first cut at password (sent in plain text D-8)

This commit is contained in:
Gregor Richards 2016-12-13 15:26:20 -05:00
parent 5a0328dc09
commit 763a657f82
7 changed files with 191 additions and 61 deletions

View File

@ -2363,7 +2363,8 @@ bool command_event(enum event_command cmd, void *data)
#ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKING
if (!init_netplay( if (!init_netplay(
data, settings->netplay.server, data, settings->netplay.server,
settings->netplay.port)) settings->netplay.port,
settings->netplay.password))
return false; return false;
#endif #endif
break; break;

View File

@ -607,6 +607,7 @@ static int populate_settings_path(settings_t *settings, struct config_path_setti
SETTING_PATH("core_updater_buildbot_assets_url", settings->network.buildbot_assets_url, false, NULL, true); SETTING_PATH("core_updater_buildbot_assets_url", settings->network.buildbot_assets_url, false, NULL, true);
#ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKING
SETTING_PATH("netplay_ip_address", settings->netplay.server, false, NULL, true); SETTING_PATH("netplay_ip_address", settings->netplay.server, false, NULL, true);
SETTING_PATH("netplay_password", settings->netplay.password, false, NULL, true);
#endif #endif
SETTING_PATH("recording_output_directory", SETTING_PATH("recording_output_directory",
global->record.output_dir, false, NULL, true); global->record.output_dir, false, NULL, true);

View File

@ -405,6 +405,7 @@ typedef struct settings
unsigned check_frames; unsigned check_frames;
bool swap_input; bool swap_input;
bool nat_traversal; bool nat_traversal;
char password[127];
} netplay; } netplay;
#endif #endif

View File

@ -667,6 +667,14 @@ static bool netplay_get_cmd(netplay_t *netplay,
return false; return false;
return ret; return ret;
} }
case NETPLAY_CONNECTION_PRE_PASSWORD:
{
bool ret = netplay_handshake_pre_password(netplay, connection, had_input);
if (connection->mode >= NETPLAY_CONNECTION_CONNECTED &&
!send_cur_input(netplay, connection))
return false;
return ret;
}
case NETPLAY_CONNECTION_PRE_SYNC: case NETPLAY_CONNECTION_PRE_SYNC:
{ {
bool ret = netplay_handshake_pre_sync(netplay, connection, had_input); bool ret = netplay_handshake_pre_sync(netplay, connection, had_input);
@ -1920,6 +1928,7 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
* @direct_host : Netplay host discovered from scanning. * @direct_host : Netplay host discovered from scanning.
* @server : IP address of server. * @server : IP address of server.
* @port : Port of server. * @port : Port of server.
* @password : Password required to connect.
* @delay_frames : Amount of delay frames. * @delay_frames : Amount of delay frames.
* @check_frames : Frequency with which to check CRCs. * @check_frames : Frequency with which to check CRCs.
* @cb : Libretro callbacks. * @cb : Libretro callbacks.
@ -1933,9 +1942,9 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
* Returns: new netplay handle. * Returns: new netplay handle.
**/ **/
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port, netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
unsigned delay_frames, unsigned check_frames, const char *password, unsigned delay_frames, unsigned check_frames,
const struct retro_callbacks *cb, bool nat_traversal, const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
const char *nick, uint64_t quirks) uint64_t quirks)
{ {
netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay)); netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay));
if (!netplay) if (!netplay)
@ -1967,6 +1976,7 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
} }
strlcpy(netplay->nick, nick[0] ? nick : RARCH_DEFAULT_NICK, sizeof(netplay->nick)); strlcpy(netplay->nick, nick[0] ? nick : RARCH_DEFAULT_NICK, sizeof(netplay->nick));
strlcpy(netplay->password, password ? password : "", sizeof(netplay->password));
if (!init_socket(netplay, direct_host, server, port)) if (!init_socket(netplay, direct_host, server, port))
{ {
@ -2452,7 +2462,11 @@ void deinit_netplay(void)
} }
/** /**
* init_netplay: * init_netplay
* @direct_host : Host to connect to directly, if applicable (client only)
* @server : server address to connect to (client only)
* @port : TCP port to host on/connect to
* @password : Password required to connect (server only)
* *
* Initializes netplay. * Initializes netplay.
* *
@ -2460,8 +2474,8 @@ void deinit_netplay(void)
* *
* Returns: true (1) if successful, otherwise false (0). * Returns: true (1) if successful, otherwise false (0).
**/ **/
bool init_netplay(void *direct_host, const char *server, unsigned port,
bool init_netplay(void *direct_host, const char *server, unsigned port) const char *password)
{ {
struct retro_callbacks cbs = {0}; struct retro_callbacks cbs = {0};
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
@ -2516,6 +2530,7 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
netplay_is_client ? direct_host : NULL, netplay_is_client ? direct_host : NULL,
netplay_is_client ? server : NULL, netplay_is_client ? server : NULL,
port ? port : RARCH_DEFAULT_PORT, port ? port : RARCH_DEFAULT_PORT,
password,
settings->netplay.delay_frames, settings->netplay.check_frames, &cbs, settings->netplay.delay_frames, settings->netplay.check_frames, &cbs,
settings->netplay.nat_traversal, settings->username, settings->netplay.nat_traversal, settings->username,
quirks); quirks);

View File

@ -59,8 +59,10 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames);
/** /**
* init_netplay * init_netplay
* @direct_host : Host to connect to directly, if applicable (client only)
* @server : server address to connect to (client only) * @server : server address to connect to (client only)
* @port : TCP port to host on/connect to * @port : TCP port to host on/connect to
* @password : Password required to connect (server only)
* *
* Initializes netplay. * Initializes netplay.
* *
@ -68,7 +70,7 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames);
* *
* Returns: true (1) if successful, otherwise false (0). * Returns: true (1) if successful, otherwise false (0).
**/ **/
bool init_netplay(void *direct_host, const char *server, unsigned port); bool init_netplay(void *direct_host, const char *server, unsigned port, const char *password);
void deinit_netplay(void); void deinit_netplay(void);

View File

@ -27,8 +27,10 @@
#include "../../msg_hash.h" #include "../../msg_hash.h"
#include "../../configuration.h" #include "../../configuration.h"
#include "../../content.h" #include "../../content.h"
#include "../../retroarch.h"
#include "../../runloop.h" #include "../../runloop.h"
#include "../../version.h" #include "../../version.h"
#include "../../menu/widgets/menu_input_dialog.h"
/** /**
* netplay_impl_magic: * netplay_impl_magic:
@ -117,7 +119,7 @@ static bool netplay_endian_mismatch(uint32_t pma, uint32_t pmb)
bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection) bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection)
{ {
uint32_t *content_crc_ptr = NULL; uint32_t *content_crc_ptr = NULL;
uint32_t header[4] = {0}; uint32_t header[5] = {0};
content_get_crc(&content_crc_ptr); content_get_crc(&content_crc_ptr);
@ -125,6 +127,8 @@ bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *
header[1] = htonl(*content_crc_ptr); header[1] = htonl(*content_crc_ptr);
header[2] = htonl(netplay_platform_magic()); header[2] = htonl(netplay_platform_magic());
header[3] = htonl(NETPLAY_COMPRESSION_SUPPORTED); header[3] = htonl(NETPLAY_COMPRESSION_SUPPORTED);
header[4] = htonl((netplay->is_server && netplay->password[0]) ?
NETPLAY_FLAG_PASSWORD_REQUIRED : 0);
if (!netplay_send(&connection->send_packet_buffer, connection->fd, header, if (!netplay_send(&connection->send_packet_buffer, connection->fd, header,
sizeof(header)) || sizeof(header)) ||
@ -140,6 +144,12 @@ struct nick_buf_s
char nick[32]; char nick[32];
}; };
struct password_buf_s
{
uint32_t cmd[2];
char password[128];
};
#define RECV(buf, sz) \ #define RECV(buf, sz) \
recvd = netplay_recv(&connection->recv_packet_buffer, connection->fd, (buf), (sz), false); \ recvd = netplay_recv(&connection->recv_packet_buffer, connection->fd, (buf), (sz), false); \
if (recvd >= 0 && recvd < (sz)) \ if (recvd >= 0 && recvd < (sz)) \
@ -149,9 +159,30 @@ struct nick_buf_s
} \ } \
else if (recvd < 0) else if (recvd < 0)
static netplay_t *handshake_password_netplay;
static void handshake_password(void *ignore, const char *line)
{
uint32_t cmd[2];
netplay_t *netplay = handshake_password_netplay;
struct netplay_connection *connection = &netplay->connections[0];
memset(netplay->password, 0, sizeof(netplay->password));
strlcpy(netplay->password, line, sizeof(netplay->password));
cmd[0] = ntohl(NETPLAY_CMD_PASSWORD);
cmd[1] = ntohl(sizeof(netplay->password));
netplay_send(&connection->send_packet_buffer, connection->fd, cmd, sizeof(cmd)) &&
netplay_send(&connection->send_packet_buffer, connection->fd, netplay->password, sizeof(netplay->password)) &&
netplay_send_flush(&connection->send_packet_buffer, connection->fd, false);
menu_input_dialog_end();
rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
}
bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input) bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
{ {
uint32_t header[4] = {0}; uint32_t header[5] = {0};
ssize_t recvd; ssize_t recvd;
char msg[512]; char msg[512];
struct nick_buf_s nick_buf; struct nick_buf_s nick_buf;
@ -231,6 +262,19 @@ bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *conne
return false; return false;
} }
/* If a password is demanded, ask for it */
if (!netplay->is_server && (ntohl(header[4]) & NETPLAY_FLAG_PASSWORD_REQUIRED))
{
menu_input_ctx_line_t line;
rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
memset(&line, 0, sizeof(line));
handshake_password_netplay = netplay;
line.label = "Enter Netplay server password:";
line.label_setting = "no_setting";
line.cb = handshake_password;
menu_input_dialog_start(&line);
}
/* Send our nick */ /* Send our nick */
nick_buf.cmd[0] = htonl(NETPLAY_CMD_NICK); nick_buf.cmd[0] = htonl(NETPLAY_CMD_NICK);
nick_buf.cmd[1] = htonl(sizeof(nick_buf.nick)); nick_buf.cmd[1] = htonl(sizeof(nick_buf.nick));
@ -285,6 +329,59 @@ static void netplay_handshake_ready(netplay_t *netplay, struct netplay_connectio
netplay->stall = 0; netplay->stall = 0;
} }
bool netplay_handshake_sync(netplay_t *netplay, struct netplay_connection *connection)
{
/* If we're the server, now we send sync info */
uint32_t cmd[5];
uint32_t connected_players;
settings_t *settings = config_get_ptr();
size_t i;
uint32_t device;
retro_ctx_memory_info_t mem_info;
mem_info.id = RETRO_MEMORY_SAVE_RAM;
core_get_memory(&mem_info);
/* Send basic sync info */
cmd[0] = htonl(NETPLAY_CMD_SYNC);
cmd[1] = htonl(3*sizeof(uint32_t) + MAX_USERS*sizeof(uint32_t) + mem_info.size);
cmd[2] = htonl(netplay->self_frame_count);
connected_players = netplay->connected_players;
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
connected_players |= 1<<netplay->self_player;
cmd[3] = htonl(connected_players);
if (netplay->flip)
cmd[4] = htonl(netplay->flip_frame);
else
cmd[4] = htonl(0);
if (!netplay_send(&connection->send_packet_buffer, connection->fd, cmd,
sizeof(cmd)))
return false;
/* Now send the device info */
for (i = 0; i < MAX_USERS; i++)
{
device = htonl(settings->input.libretro_device[i]);
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
&device, sizeof(device)))
return false;
}
/* And finally, the SRAM */
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
mem_info.data, mem_info.size) ||
!netplay_send_flush(&connection->send_packet_buffer, connection->fd,
false))
return false;
/* Now we're ready! */
connection->mode = NETPLAY_CONNECTION_SPECTATING;
netplay_handshake_ready(netplay, connection);
return true;
}
bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input) bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
{ {
struct nick_buf_s nick_buf; struct nick_buf_s nick_buf;
@ -318,54 +415,17 @@ bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *c
if (netplay->is_server) if (netplay->is_server)
{ {
/* If we're the server, now we send sync info */ if (netplay->password[0])
uint32_t cmd[5];
uint32_t connected_players;
settings_t *settings = config_get_ptr();
size_t i;
uint32_t device;
retro_ctx_memory_info_t mem_info;
mem_info.id = RETRO_MEMORY_SAVE_RAM;
core_get_memory(&mem_info);
/* Send basic sync info */
cmd[0] = htonl(NETPLAY_CMD_SYNC);
cmd[1] = htonl(3*sizeof(uint32_t) + MAX_USERS*sizeof(uint32_t) + mem_info.size);
cmd[2] = htonl(netplay->self_frame_count);
connected_players = netplay->connected_players;
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
connected_players |= 1<<netplay->self_player;
cmd[3] = htonl(connected_players);
if (netplay->flip)
cmd[4] = htonl(netplay->flip_frame);
else
cmd[4] = htonl(0);
if (!netplay_send(&connection->send_packet_buffer, connection->fd, cmd,
sizeof(cmd)))
return false;
/* Now send the device info */
for (i = 0; i < MAX_USERS; i++)
{ {
device = htonl(settings->input.libretro_device[i]); /* There's a password, so just put them in PRE_PASSWORD mode */
if (!netplay_send(&connection->send_packet_buffer, connection->fd, connection->mode = NETPLAY_CONNECTION_PRE_PASSWORD;
&device, sizeof(device))) }
else
{
if (!netplay_handshake_sync(netplay, connection))
return false; return false;
} }
/* And finally, the SRAM */
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
mem_info.data, mem_info.size) ||
!netplay_send_flush(&connection->send_packet_buffer, connection->fd,
false))
return false;
/* Now we're ready! */
connection->mode = NETPLAY_CONNECTION_SPECTATING;
netplay_handshake_ready(netplay, connection);
} }
else else
{ {
@ -379,6 +439,44 @@ bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *c
return true; return true;
} }
bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
{
struct password_buf_s password_buf;
ssize_t recvd;
char msg[512];
msg[0] = '\0';
RECV(&password_buf, sizeof(password_buf));
/* Expecting only a nick command */
if (recvd < 0 ||
ntohl(password_buf.cmd[0]) != NETPLAY_CMD_PASSWORD ||
ntohl(password_buf.cmd[1]) != sizeof(password_buf.password))
{
if (netplay->is_server)
strlcpy(msg, msg_hash_to_str(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT),
sizeof(msg));
else
strlcpy(msg,
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST),
sizeof(msg));
RARCH_ERR("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
return false;
}
if (strncmp(netplay->password, password_buf.password, sizeof(password_buf.password)))
return false;
if (!netplay_handshake_sync(netplay, connection))
return false;
*had_input = true;
netplay_recv_flush(&connection->recv_packet_buffer);
return true;
}
bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input) bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
{ {
uint32_t cmd[2]; uint32_t cmd[2];

View File

@ -79,6 +79,9 @@
#define NETPLAY_COMPRESSION_SUPPORTED 0 #define NETPLAY_COMPRESSION_SUPPORTED 0
#endif #endif
/* Netplay connection flags */
#define NETPLAY_FLAG_PASSWORD_REQUIRED (1<<0)
enum netplay_cmd enum netplay_cmd
{ {
/* Basic commands */ /* Basic commands */
@ -103,17 +106,20 @@ enum netplay_cmd
/* Inform the other side of our nick (must be first command) */ /* Inform the other side of our nick (must be first command) */
NETPLAY_CMD_NICK = 0x0020, NETPLAY_CMD_NICK = 0x0020,
/* Give the connection password */
NETPLAY_CMD_PASSWORD = 0x0021,
/* Initial synchronization info (frame, sram, player info) */ /* Initial synchronization info (frame, sram, player info) */
NETPLAY_CMD_SYNC = 0x0021, NETPLAY_CMD_SYNC = 0x0022,
/* Join spectator mode */ /* Join spectator mode */
NETPLAY_CMD_SPECTATE = 0x0022, NETPLAY_CMD_SPECTATE = 0x0023,
/* Join play mode */ /* Join play mode */
NETPLAY_CMD_PLAY = 0x0023, NETPLAY_CMD_PLAY = 0x0024,
/* Report player mode */ /* Report player mode */
NETPLAY_CMD_MODE = 0x0024, NETPLAY_CMD_MODE = 0x0025,
/* Loading and synchronization */ /* Loading and synchronization */
@ -177,6 +183,7 @@ enum rarch_netplay_connection_mode
/* Initialization: */ /* Initialization: */
NETPLAY_CONNECTION_INIT, /* Waiting for header */ NETPLAY_CONNECTION_INIT, /* Waiting for header */
NETPLAY_CONNECTION_PRE_NICK, /* Waiting for nick */ NETPLAY_CONNECTION_PRE_NICK, /* Waiting for nick */
NETPLAY_CONNECTION_PRE_PASSWORD, /* Waiting for password */
NETPLAY_CONNECTION_PRE_SYNC, /* Waiting for sync */ NETPLAY_CONNECTION_PRE_SYNC, /* Waiting for sync */
/* Ready: */ /* Ready: */
@ -268,6 +275,9 @@ struct netplay
/* TCP connection for listening (server only) */ /* TCP connection for listening (server only) */
int listen_fd; int listen_fd;
/* Password required to connect (server only) */
char password[128];
/* Our player number */ /* Our player number */
uint32_t self_player; uint32_t self_player;
@ -394,6 +404,7 @@ void input_poll_net(void);
* @direct_host : Netplay host discovered from scanning. * @direct_host : Netplay host discovered from scanning.
* @server : IP address of server. * @server : IP address of server.
* @port : Port of server. * @port : Port of server.
* @password : Password required to connect.
* @delay_frames : Amount of delay frames. * @delay_frames : Amount of delay frames.
* @check_frames : Frequency with which to check CRCs. * @check_frames : Frequency with which to check CRCs.
* @cb : Libretro callbacks. * @cb : Libretro callbacks.
@ -407,9 +418,9 @@ void input_poll_net(void);
* Returns: new netplay handle. * Returns: new netplay handle.
**/ **/
netplay_t *netplay_new(void *direct_host, const char *server, netplay_t *netplay_new(void *direct_host, const char *server,
uint16_t port, unsigned delay_frames, unsigned check_frames, uint16_t port, const char *password, unsigned delay_frames,
const struct retro_callbacks *cb, bool nat_traversal, unsigned check_frames, const struct retro_callbacks *cb,
const char *nick, uint64_t quirks); bool nat_traversal, const char *nick, uint64_t quirks);
/** /**
* netplay_free: * netplay_free:
@ -493,6 +504,7 @@ bool netplay_send_nickname(netplay_t *netplay, int fd);
bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection); bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection);
bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input); bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input); bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input); bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
uint32_t netplay_impl_magic(void); uint32_t netplay_impl_magic(void);