Added netplay spectator password separate from play password

This commit is contained in:
Gregor Richards 2016-12-14 22:18:24 -05:00
parent 694b7a9723
commit 03415c261d
9 changed files with 64 additions and 27 deletions

View File

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

View File

@ -608,6 +608,7 @@ static int populate_settings_path(settings_t *settings, struct config_path_setti
#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); SETTING_PATH("netplay_password", settings->netplay.password, false, NULL, true);
SETTING_PATH("netplay_spectate_password", settings->netplay.spectate_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,7 +405,8 @@ typedef struct settings
unsigned check_frames; unsigned check_frames;
bool swap_input; bool swap_input;
bool nat_traversal; bool nat_traversal;
char password[127]; char password[128];
char spectate_password[128];
} netplay; } netplay;
#endif #endif

View File

@ -62,7 +62,8 @@ size_t audio_sample_batch_net(const int16_t *data, size_t frames);
* @direct_host : Host to connect to directly, if applicable (client only) * @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) * @play_password : Password required to play (server only)
* @spectate_password : Password required to connect (server only)
* *
* Initializes netplay. * Initializes netplay.
* *
@ -70,7 +71,8 @@ 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, const char *password); bool init_netplay(void *direct_host, const char *server, unsigned port,
const char *play_password, const char *spectate_password);
void deinit_netplay(void); void deinit_netplay(void);

View File

@ -824,7 +824,8 @@ void deinit_netplay(void)
* @direct_host : Host to connect to directly, if applicable (client only) * @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) * @play_password : Password required to play (server only)
* @spectate_password : Password required to connect (server only)
* *
* Initializes netplay. * Initializes netplay.
* *
@ -833,7 +834,7 @@ 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) const char *play_password, const char *spectate_password)
{ {
struct retro_callbacks cbs = {0}; struct retro_callbacks cbs = {0};
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
@ -889,7 +890,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, play_password, spectate_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

@ -240,7 +240,7 @@ 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);
if (netplay->is_server && netplay->password[0]) if (netplay->is_server && (netplay->play_password[0] || netplay->spectate_password[0]))
{ {
/* Demand a password */ /* Demand a password */
if (simple_rand_next == 1) if (simple_rand_next == 1)
@ -542,13 +542,14 @@ bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *c
if (netplay->is_server) if (netplay->is_server)
{ {
if (netplay->password[0]) if (netplay->play_password[0] || netplay->spectate_password[0])
{ {
/* There's a password, so just put them in PRE_PASSWORD mode */ /* There's a password, so just put them in PRE_PASSWORD mode */
connection->mode = NETPLAY_CONNECTION_PRE_PASSWORD; connection->mode = NETPLAY_CONNECTION_PRE_PASSWORD;
} }
else else
{ {
connection->can_play = true;
if (!netplay_handshake_sync(netplay, connection)) if (!netplay_handshake_sync(netplay, connection))
return false; return false;
} }
@ -572,6 +573,7 @@ bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connectio
char password[8+NETPLAY_PASS_LEN]; /* 8 for salt */ char password[8+NETPLAY_PASS_LEN]; /* 8 for salt */
ssize_t recvd; ssize_t recvd;
char msg[512]; char msg[512];
bool correct;
msg[0] = '\0'; msg[0] = '\0';
@ -594,15 +596,32 @@ bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connectio
return false; return false;
} }
/* Calculate the correct password */ /* Calculate the correct password hash(es) and compare */
correct = false;
snprintf(password, sizeof(password), "%08X", connection->salt); snprintf(password, sizeof(password), "%08X", connection->salt);
strlcpy(password + 8, netplay->password, sizeof(password)-8); if (netplay->play_password[0])
sha256_hash(corr_password_buf.password, (uint8_t *) password, strlen(password)); {
strlcpy(password + 8, netplay->play_password, sizeof(password)-8);
sha256_hash(corr_password_buf.password, (uint8_t *) password, strlen(password));
if (!memcmp(password_buf.password, corr_password_buf.password, sizeof(password_buf.password)))
{
correct = true;
connection->can_play = true;
}
}
if (netplay->spectate_password[0])
{
strlcpy(password + 8, netplay->spectate_password, sizeof(password)-8);
sha256_hash(corr_password_buf.password, (uint8_t *) password, strlen(password));
if (!memcmp(password_buf.password, corr_password_buf.password, sizeof(password_buf.password)))
correct = true;
}
/* Compare them */ /* Just disconnect if it was wrong */
if (memcmp(password_buf.password, corr_password_buf.password, sizeof(password_buf.password))) if (!correct)
return false; return false;
/* Otherwise, we're ready! */
if (!netplay_handshake_sync(netplay, connection)) if (!netplay_handshake_sync(netplay, connection))
return false; return false;

View File

@ -388,7 +388,8 @@ 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. * @play_password : Password required to play.
* @spectate_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.
@ -402,9 +403,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,
const char *password, unsigned delay_frames, unsigned check_frames, const char *play_password, const char *spectate_password,
const struct retro_callbacks *cb, bool nat_traversal, const char *nick, unsigned delay_frames, unsigned check_frames, const struct retro_callbacks
uint64_t quirks) *cb, bool nat_traversal, const char *nick, 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)
@ -437,7 +438,8 @@ 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)); strlcpy(netplay->play_password, play_password ? play_password : "", sizeof(netplay->play_password));
strlcpy(netplay->spectate_password, spectate_password ? spectate_password : "", sizeof(netplay->spectate_password));
if (!init_socket(netplay, direct_host, server, port)) if (!init_socket(netplay, direct_host, server, port))
{ {

View File

@ -566,6 +566,9 @@ static bool netplay_get_cmd(netplay_t *netplay,
if (!netplay->is_server) if (!netplay->is_server)
return netplay_cmd_nak(netplay, connection); return netplay_cmd_nak(netplay, connection);
if (!connection->can_play)
break;
/* Find an available player slot */ /* Find an available player slot */
for (player = 0; player <= netplay->player_max; player++) for (player = 0; player <= netplay->player_max; player++)
{ {

View File

@ -260,6 +260,9 @@ struct netplay_connection
/* Salt associated with password transaction */ /* Salt associated with password transaction */
uint32_t salt; uint32_t salt;
/* Is this connection allowed to play (server only)? */
bool can_play;
/* Buffers for sending and receiving data */ /* Buffers for sending and receiving data */
struct socket_buffer send_packet_buffer, recv_packet_buffer; struct socket_buffer send_packet_buffer, recv_packet_buffer;
@ -288,8 +291,11 @@ struct netplay
/* TCP connection for listening (server only) */ /* TCP connection for listening (server only) */
int listen_fd; int listen_fd;
/* Password required to play (server only) */
char play_password[NETPLAY_PASS_LEN];
/* Password required to connect (server only) */ /* Password required to connect (server only) */
char password[NETPLAY_PASS_LEN]; char spectate_password[NETPLAY_PASS_LEN];
/* Our player number */ /* Our player number */
uint32_t self_player; uint32_t self_player;
@ -420,23 +426,24 @@ 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. * @play_password : Password required to play.
* @spectate_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.
* @nat_traversal : If true, attempt NAT traversal. * @nat_traversal : If true, attempt NAT traversal.
* @nick : Nickname of user. * @nick : Nickname of user.
* @quirks : Netplay quirks. * @quirks : Netplay quirks required for this session.
* *
* Creates a new netplay handle. A NULL host means we're * Creates a new netplay handle. A NULL host means we're
* hosting (user 1). * hosting (user 1).
* *
* 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,
uint16_t port, const char *password, unsigned delay_frames, const char *play_password, const char *spectate_password,
unsigned check_frames, const struct retro_callbacks *cb, unsigned delay_frames, unsigned check_frames, const struct retro_callbacks
bool nat_traversal, const char *nick, uint64_t quirks); *cb, bool nat_traversal, const char *nick, uint64_t quirks);
/** /**
* netplay_free: * netplay_free: