mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
Merge pull request #210 from FDH2/testing
control clients allowed to connect
This commit is contained in:
33
README.html
33
README.html
@@ -1,6 +1,6 @@
|
||||
<h1
|
||||
id="uxplay-1.65-airplay-mirror-and-airplay-audio-server-for-linux-macos-and-unix-now-also-runs-on-windows.">UxPlay
|
||||
1.65: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix
|
||||
id="uxplay-1.66-airplay-mirror-and-airplay-audio-server-for-linux-macos-and-unix-now-also-runs-on-windows.">UxPlay
|
||||
1.66: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix
|
||||
(now also runs on Windows).</h1>
|
||||
<h3
|
||||
id="now-developed-at-the-github-site-httpsgithub.comfdh2uxplay-where-all-user-issues-should-be-posted.">Now
|
||||
@@ -124,7 +124,7 @@ and <a href="https://emanuelecozzi.net/docs/airplay2">here</a>; see also
|
||||
<a href="https://pyatv.dev/documentation/protocols">pyatv</a> which
|
||||
could be a resource for adding modern protocols.) While there is no
|
||||
guarantee that future iOS releases will keep supporting “Legacy
|
||||
Protocol”, the recent iOS 16 release continues support.</p>
|
||||
Protocol”, iOS 17 continues support.</p>
|
||||
<p>The UxPlay server and its client must be on the same local area
|
||||
network, on which a <strong>Bonjour/Zeroconf mDNS/DNS-SD server</strong>
|
||||
is also running (only DNS-SD “Service Discovery” service is strictly
|
||||
@@ -441,8 +441,11 @@ other problems.</p>
|
||||
<li><p>By default, UxPlay is locked to its current client until that
|
||||
client drops the connection; since UxPlay-1.58, the option
|
||||
<code>-nohold</code> modifies this behavior so that when a new client
|
||||
requests a connection, it removes the current client and takes
|
||||
over.</p></li>
|
||||
requests a connection, it removes the current client and takes over.
|
||||
UxPlay 1.66 introduces a mechanism ( <code>-restrict</code>,
|
||||
<code>-allow <id></code>, <code>-block <id></code>) to
|
||||
control which clients are allowed to connect, using their immutable
|
||||
“clientID”.</p></li>
|
||||
<li><p>In Mirror mode, GStreamer has a choice of <strong>two</strong>
|
||||
methods to play video with its accompanying audio: prior to UxPlay-1.64,
|
||||
the video and audio streams were both played as soon as possible after
|
||||
@@ -1013,6 +1016,23 @@ when the GStreamer pipeline is closed.</em></p>
|
||||
<p><strong>-nohold</strong> Drops the current connection when a new
|
||||
client attempts to connect. Without this option, the current client
|
||||
maintains exclusive ownership of UxPlay until it disconnects.</p>
|
||||
<p><strong>-restrict</strong> Restrict clients allowed to connect to
|
||||
those specified by <code>-allow <clientID></code>. The ClientID is
|
||||
the true MAC address (in iOS it is listed in Settings->General->Wi
|
||||
Fi Address), which is displayed by UxPlay when the client attempts to
|
||||
connect. It has the format <code>XX:XX:XX:XX:XX:XX</code>, X =
|
||||
0-9,A-F.</p>
|
||||
<p><strong>-restrict no</strong> Remove restrictions (default). This is
|
||||
useful as a command-line argument to overide restrictions set in the
|
||||
Startup file.</p>
|
||||
<p><strong>-allow <em>id</em></strong> Adds the clientID = <em>id</em>
|
||||
to the list of allowed clients when client restrictions are being
|
||||
enforced. Usually this will be an entry in the uxplayrc startup
|
||||
file.</p>
|
||||
<p><strong>-block <em>id</em></strong> Always block clients with
|
||||
clientID = <em>id</em>, even when client restrictions are not being
|
||||
enforced generally. Usually this will be an entry in the uxplayrc
|
||||
startup file.</p>
|
||||
<p><strong>-FPSdata</strong> Turns on monitoring of regular reports
|
||||
about video streaming performance that are sent by the client. These
|
||||
will be displayed in the terminal window if this option is used. The
|
||||
@@ -1366,6 +1386,9 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen,
|
||||
introduced 2017, running tvOS 12.2.1), so it does not seem to matter
|
||||
what UxPlay claims to be.</p>
|
||||
<h1 id="changelog">Changelog</h1>
|
||||
<p>1.66 2023-09-05 Fix IPV6 support. Add option to restrict clients to
|
||||
those on a list of allowed clientIDs, or to block connections from
|
||||
clients on a list of blocked clientIDs.</p>
|
||||
<p>1.65.3 2023-07-23 Add RPM spec file; add warning if required
|
||||
gstreamer libav feature “avdec_aac” is missing: (this occurs in
|
||||
RPM-based distributions that ship an incomplete FFmpeg for Patent or
|
||||
|
||||
24
README.md
24
README.md
@@ -1,4 +1,4 @@
|
||||
# UxPlay 1.65: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).
|
||||
# UxPlay 1.66: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).
|
||||
|
||||
### Now developed at the GitHub site [https://github.com/FDH2/UxPlay](https://github.com/FDH2/UxPlay) (where all user issues should be posted).
|
||||
|
||||
@@ -86,7 +86,7 @@ Apple's AirPlay2 protocol using "Legacy Protocol", but some features are missing
|
||||
[here](https://github.com/SteeBono/airplayreceiver/wiki/AirPlay2-Protocol) and
|
||||
[here](https://emanuelecozzi.net/docs/airplay2); see also [pyatv](https://pyatv.dev/documentation/protocols) which could be
|
||||
a resource for adding modern protocols.) While there is no guarantee that future
|
||||
iOS releases will keep supporting "Legacy Protocol", the recent iOS 16 release continues support.
|
||||
iOS releases will keep supporting "Legacy Protocol", iOS 17 continues support.
|
||||
|
||||
The UxPlay server and its client must be on the same local area network,
|
||||
on which a **Bonjour/Zeroconf mDNS/DNS-SD server** is also running
|
||||
@@ -361,7 +361,9 @@ help with this or other problems.
|
||||
|
||||
* By default, UxPlay is locked to
|
||||
its current client until that client drops the connection; since UxPlay-1.58, the option `-nohold` modifies this
|
||||
behavior so that when a new client requests a connection, it removes the current client and takes over.
|
||||
behavior so that when a new client requests a connection, it removes the current client and takes over. UxPlay 1.66 introduces
|
||||
a mechanism ( `-restrict`, ``-allow <id>``, ```-block <id>```) to control which clients are allowed to connect, using their
|
||||
immutable "clientID".
|
||||
|
||||
* In Mirror mode, GStreamer has a choice of **two** methods to play video with its accompanying audio: prior to UxPlay-1.64,
|
||||
the video and audio streams were both played as soon as possible after they arrived (the GStreamer "_sync=false_" method), with
|
||||
@@ -808,6 +810,19 @@ which will not work if a firewall is running.
|
||||
**-nohold** Drops the current connection when a new client attempts to connect. Without this option,
|
||||
the current client maintains exclusive ownership of UxPlay until it disconnects.
|
||||
|
||||
**-restrict** Restrict clients allowed to connect to those specified by `-allow <clientID>`. The ClientID is the
|
||||
true MAC address (in iOS it is listed in Settings->General->Wi Fi Address), which is displayed by UxPlay when
|
||||
the client attempts to connect. It has the format `XX:XX:XX:XX:XX:XX`, X = 0-9,A-F.
|
||||
|
||||
**-restrict no** Remove restrictions (default). This is useful as a command-line argument to overide restrictions set
|
||||
in the Startup file.
|
||||
|
||||
**-allow _id_** Adds the clientID = _id_ to the list of allowed clients when client restrictions
|
||||
are being enforced. Usually this will be an entry in the uxplayrc startup file.
|
||||
|
||||
**-block _id_** Always block clients with clientID = _id_, even when client restrictions are not
|
||||
being enforced generally. Usually this will be an entry in the uxplayrc startup file.
|
||||
|
||||
**-FPSdata** Turns on monitoring of regular reports about video streaming performance
|
||||
that are sent by the client. These will be displayed in the terminal window if this
|
||||
option is used. The data is updated by the client at 1 second intervals.
|
||||
@@ -1084,6 +1099,9 @@ tvOS 12.2.1), so it does not seem to matter what UxPlay claims to be.
|
||||
|
||||
|
||||
# Changelog
|
||||
1.66 2023-09-05 Fix IPV6 support. Add option to restrict clients to those on a list of allowed clientIDs,
|
||||
or to block connections from clients on a list of blocked clientIDs.
|
||||
|
||||
1.65.3 2023-07-23 Add RPM spec file; add warning if required gstreamer libav feature "avdec_aac" is
|
||||
missing: (this occurs in RPM-based distributions that ship an incomplete FFmpeg for Patent
|
||||
or License reasons, and rely on users installing an externally-supplied complete FFmpeg).
|
||||
|
||||
32
README.txt
32
README.txt
@@ -1,4 +1,4 @@
|
||||
# UxPlay 1.65: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).
|
||||
# UxPlay 1.66: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).
|
||||
|
||||
### Now developed at the GitHub site <https://github.com/FDH2/UxPlay> (where all user issues should be posted).
|
||||
|
||||
@@ -119,8 +119,8 @@ is publicly known about Apple's AirPlay 2 protocol can be found
|
||||
and [here](https://emanuelecozzi.net/docs/airplay2); see also
|
||||
[pyatv](https://pyatv.dev/documentation/protocols) which could be a
|
||||
resource for adding modern protocols.) While there is no guarantee that
|
||||
future iOS releases will keep supporting "Legacy Protocol", the recent
|
||||
iOS 16 release continues support.
|
||||
future iOS releases will keep supporting "Legacy Protocol", iOS 17
|
||||
continues support.
|
||||
|
||||
The UxPlay server and its client must be on the same local area network,
|
||||
on which a **Bonjour/Zeroconf mDNS/DNS-SD server** is also running (only
|
||||
@@ -433,7 +433,10 @@ below for help with this or other problems.
|
||||
- By default, UxPlay is locked to its current client until that client
|
||||
drops the connection; since UxPlay-1.58, the option `-nohold`
|
||||
modifies this behavior so that when a new client requests a
|
||||
connection, it removes the current client and takes over.
|
||||
connection, it removes the current client and takes over. UxPlay
|
||||
1.66 introduces a mechanism ( `-restrict`, `-allow <id>`,
|
||||
`-block <id>`) to control which clients are allowed to connect,
|
||||
using their immutable "clientID".
|
||||
|
||||
- In Mirror mode, GStreamer has a choice of **two** methods to play
|
||||
video with its accompanying audio: prior to UxPlay-1.64, the video
|
||||
@@ -1026,6 +1029,23 @@ closed.*
|
||||
connect. Without this option, the current client maintains exclusive
|
||||
ownership of UxPlay until it disconnects.
|
||||
|
||||
**-restrict** Restrict clients allowed to connect to those specified by
|
||||
`-allow <clientID>`. The ClientID is the true MAC address (in iOS it is
|
||||
listed in Settings-\>General-\>Wi Fi Address), which is displayed by
|
||||
UxPlay when the client attempts to connect. It has the format
|
||||
`XX:XX:XX:XX:XX:XX`, X = 0-9,A-F.
|
||||
|
||||
**-restrict no** Remove restrictions (default). This is useful as a
|
||||
command-line argument to overide restrictions set in the Startup file.
|
||||
|
||||
**-allow *id*** Adds the clientID = *id* to the list of allowed clients
|
||||
when client restrictions are being enforced. Usually this will be an
|
||||
entry in the uxplayrc startup file.
|
||||
|
||||
**-block *id*** Always block clients with clientID = *id*, even when
|
||||
client restrictions are not being enforced generally. Usually this will
|
||||
be an entry in the uxplayrc startup file.
|
||||
|
||||
**-FPSdata** Turns on monitoring of regular reports about video
|
||||
streaming performance that are sent by the client. These will be
|
||||
displayed in the terminal window if this option is used. The data is
|
||||
@@ -1396,6 +1416,10 @@ what UxPlay claims to be.
|
||||
|
||||
# Changelog
|
||||
|
||||
1.66 2023-09-05 Fix IPV6 support. Add option to restrict clients to
|
||||
those on a list of allowed clientIDs, or to block connections from
|
||||
clients on a list of blocked clientIDs.
|
||||
|
||||
1.65.3 2023-07-23 Add RPM spec file; add warning if required gstreamer
|
||||
libav feature "avdec_aac" is missing: (this occurs in RPM-based
|
||||
distributions that ship an incomplete FFmpeg for Patent or License
|
||||
|
||||
@@ -70,6 +70,7 @@ struct raop_callbacks_s {
|
||||
void (*audio_set_progress)(void *cls, unsigned int start, unsigned int curr, unsigned int end);
|
||||
void (*audio_get_format)(void *cls, unsigned char *ct, unsigned short *spf, bool *usingScreen, bool *isMedia, uint64_t *audioFormat);
|
||||
void (*video_report_size)(void *cls, float *width_source, float *height_source, float *width, float *height);
|
||||
void (*report_client_request) (void *cls, char *deviceid, char *model, char *name, bool *admit);
|
||||
};
|
||||
typedef struct raop_callbacks_s raop_callbacks_t;
|
||||
raop_ntp_t *raop_ntp_init(logger_t *logger, raop_callbacks_t *callbacks, const char *remote, int remote_addr_len,
|
||||
|
||||
@@ -354,6 +354,33 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
// First setup
|
||||
char* eiv = NULL;
|
||||
uint64_t eiv_len = 0;
|
||||
|
||||
char *deviceID = NULL;
|
||||
char *model = NULL;
|
||||
char *name = NULL;
|
||||
bool admit_client = true;
|
||||
plist_t req_deviceid_node = plist_dict_get_item(req_root_node, "deviceID");
|
||||
plist_get_string_val(req_deviceid_node, &deviceID);
|
||||
plist_t req_model_node = plist_dict_get_item(req_root_node, "model");
|
||||
plist_get_string_val(req_model_node, &model);
|
||||
plist_t req_name_node = plist_dict_get_item(req_root_node, "name");
|
||||
plist_get_string_val(req_name_node, &name);
|
||||
if (conn->raop->callbacks.report_client_request) {
|
||||
conn->raop->callbacks.report_client_request(conn->raop->callbacks.cls, deviceID, model, name, &admit_client);
|
||||
}
|
||||
free (deviceID);
|
||||
deviceID = NULL;
|
||||
free (model);
|
||||
model = NULL;
|
||||
free (name);
|
||||
name = NULL;
|
||||
if (admit_client == false) {
|
||||
/* client is not authorized to connect */
|
||||
plist_free(res_root_node);
|
||||
plist_free(req_root_node);
|
||||
return;
|
||||
}
|
||||
|
||||
plist_get_data_val(req_eiv_node, &eiv, &eiv_len);
|
||||
memcpy(aesiv, eiv, 16);
|
||||
free(eiv);
|
||||
|
||||
14
uxplay.1
14
uxplay.1
@@ -1,11 +1,11 @@
|
||||
.TH UXPLAY "1" "June 2023" "1.65" "User Commands"
|
||||
.TH UXPLAY "1" "September 2023" "1.66" "User Commands"
|
||||
.SH NAME
|
||||
uxplay \- start AirPlay server
|
||||
.SH SYNOPSIS
|
||||
.B uxplay
|
||||
[\fI\,-n name\/\fR] [\fI\,-s wxh\/\fR] [\fI\,-p \/\fR[\fI\,n\/\fR]] [more \fI OPTIONS \/\fR ...]
|
||||
.SH DESCRIPTION
|
||||
UxPlay 1.65: An open\-source AirPlay mirroring (+ audio streaming) server:
|
||||
UxPlay 1.66: An open\-source AirPlay mirroring (+ audio streaming) server:
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B
|
||||
@@ -92,6 +92,16 @@ UxPlay 1.65: An open\-source AirPlay mirroring (+ audio streaming) server:
|
||||
.TP
|
||||
\fB\-nohold\fR Drop current connection when new client connects.
|
||||
.TP
|
||||
\fB\-restrict\fR Restrict clients to those specified by "-allow clientID".
|
||||
.IP
|
||||
Uxplay displays clientID when a client attempts connection.
|
||||
.IP
|
||||
Use "-restrict no" for no client restrictions (default).
|
||||
.PP
|
||||
\fB\-allow\fR id Permit clientID = id to connect if restrictions are imposed.
|
||||
.TP
|
||||
\fB\-block\fR id Always block connections from clientID = id.
|
||||
.TP
|
||||
\fB\-FPSdata\fR Show video-streaming performance reports sent by client.
|
||||
.TP
|
||||
\fB\-fps\fR n Set maximum allowed streaming framerate, default 30
|
||||
|
||||
72
uxplay.cpp
72
uxplay.cpp
@@ -59,7 +59,7 @@
|
||||
#include "renderers/video_renderer.h"
|
||||
#include "renderers/audio_renderer.h"
|
||||
|
||||
#define VERSION "1.65"
|
||||
#define VERSION "1.66"
|
||||
|
||||
#define SECOND_IN_USECS 1000000
|
||||
#define SECOND_IN_NSECS 1000000000UL
|
||||
@@ -121,6 +121,9 @@ static int max_connections = 2;
|
||||
static unsigned short raop_port;
|
||||
static unsigned short airplay_port;
|
||||
static uint64_t remote_clock_offset = 0;
|
||||
static std::vector<std::string> allowed_clients;
|
||||
static std::vector<std::string> blocked_clients;
|
||||
static bool restrict_clients;
|
||||
|
||||
/* 95 byte png file with a 1x1 white square (single pixel): placeholder for coverart*/
|
||||
static const unsigned char empty_image[] = {
|
||||
@@ -442,6 +445,11 @@ static void print_info (char *name) {
|
||||
printf("-reset n Reset after 3n seconds client silence (default %d, 0=never)\n", NTP_TIMEOUT_LIMIT);
|
||||
printf("-nc do Not Close video window when client stops mirroring\n");
|
||||
printf("-nohold Drop current connection when new client connects.\n");
|
||||
printf("-restrict Restrict clients to those specified by \"-allow <clientID>\"\n");
|
||||
printf(" UxPlay displays clientID when a client attempts connection\n");
|
||||
printf(" Use \"-restrict no\" for no client restrictions (default)\n");
|
||||
printf("-allow <i>Permit clientID = <i> to connect if restrictions are imposed\n");
|
||||
printf("-block <i>Always block connections from clientID = <i>\n");
|
||||
printf("-FPSdata Show video-streaming performance reports sent by client.\n");
|
||||
printf("-fps n Set maximum allowed streaming framerate, default 30\n");
|
||||
printf("-f {H|V|I}Horizontal|Vertical flip, or both=Inversion=rotate 180 deg\n");
|
||||
@@ -599,7 +607,24 @@ static void parse_arguments (int argc, char *argv[]) {
|
||||
// Parse arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg(argv[i]);
|
||||
if (arg == "-n") {
|
||||
if (arg == "-allow") {
|
||||
if (!option_has_value(i, argc, arg, argv[i+1])) exit(1);
|
||||
i++;
|
||||
allowed_clients.push_back(argv[i]);
|
||||
} else if (arg == "-block") {
|
||||
if (!option_has_value(i, argc, arg, argv[i+1])) exit(1);
|
||||
i++;
|
||||
blocked_clients.push_back(argv[i]);
|
||||
} else if (arg == "-restrict") {
|
||||
if (i < argc - 1) {
|
||||
if (strlen(argv[i+1]) == 2 && strncmp(argv[i+1], "no", 2) == 0) {
|
||||
restrict_clients = false;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
restrict_clients = true;
|
||||
} else if (arg == "-n") {
|
||||
if (!option_has_value(i, argc, arg, argv[i+1])) exit(1);
|
||||
server_name = std::string(argv[++i]);
|
||||
} else if (arg == "-nh") {
|
||||
@@ -1040,6 +1065,29 @@ static int start_dnssd(std::vector<char> hw_addr, std::string name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool check_client(char *deviceid) {
|
||||
bool ret = false;
|
||||
int list = allowed_clients.size();
|
||||
for (int i = 0; i < list ; i++) {
|
||||
if (!strcmp(deviceid,allowed_clients[i].c_str())) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool check_blocked_client(char *deviceid) {
|
||||
bool ret = false;
|
||||
int list = blocked_clients.size();
|
||||
for (int i = 0; i < list ; i++) {
|
||||
if (!strcmp(deviceid,blocked_clients[i].c_str())) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Server callbacks
|
||||
extern "C" void conn_init (void *cls) {
|
||||
@@ -1079,6 +1127,23 @@ extern "C" void conn_teardown(void *cls, bool *teardown_96, bool *teardown_110)
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void report_client_request(void *cls, char *deviceid, char * model, char *name, bool * admit) {
|
||||
LOGI("connection request from %s (%s) with deviceID = %s\n", name, model, deviceid);
|
||||
if (restrict_clients) {
|
||||
*admit = check_client(deviceid);
|
||||
if (*admit == false) {
|
||||
LOGI("client connections have been restricted to those with listed deviceID,\nuse \"-allow %s\" to allow this client to connect.\n",
|
||||
deviceid);
|
||||
}
|
||||
} else {
|
||||
*admit = true;
|
||||
}
|
||||
if (check_blocked_client(deviceid)) {
|
||||
*admit = false;
|
||||
LOGI("*** attempt to connect by blocked client (clientID %s): DENIED\n", deviceid);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void audio_process (void *cls, raop_ntp_t *ntp, audio_decode_struct *data) {
|
||||
if (dump_audio) {
|
||||
dump_audio_to_file(data->data, data->data_len, (data->data)[0] & 0xf0);
|
||||
@@ -1274,7 +1339,8 @@ int start_raop_server (unsigned short display[5], unsigned short tcp[3], unsigne
|
||||
raop_cbs.video_report_size = video_report_size;
|
||||
raop_cbs.audio_set_metadata = audio_set_metadata;
|
||||
raop_cbs.audio_set_coverart = audio_set_coverart;
|
||||
|
||||
raop_cbs.report_client_request = report_client_request;
|
||||
|
||||
/* set max number of connections = 2 to protect against capture by new client */
|
||||
raop = raop_init(max_connections, &raop_cbs);
|
||||
if (raop == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user