Skip to content

Commit

Permalink
#112: support of audio capture
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpoelen committed Dec 30, 2020
1 parent 2f197a5 commit 2c6ea60
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 71 deletions.
1 change: 1 addition & 0 deletions projects/jsclient/src/main/js_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class RdpClient

client_info.bitmap_codec_caps.haveRemoteFxCodec = enable_remotefx;
client_info.has_sound_code = get_or(config, "enableSound", false);
client_info.has_sound_capture_code = get_or(config, "enableSoundCapture", false);

uint32_t maxRequestSize = client_info.multi_fragment_update_caps.MaxRequestSize;
set_if(config, "fragmentUpdateMaxRequestSize", maxRequestSize);
Expand Down
61 changes: 16 additions & 45 deletions src/core/channels_authorizations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ ChannelsAuthorizations::ChannelsAuthorizations(std::string_view allow, std::stri
this->rdpdr_restriction_.fill(true);
this->cliprdr_restriction_.fill(true);
this->rdpsnd_restriction_.fill(true);
this->rdpcap_restriction_.fill(true);
}

auto normalize = [this](
Expand All @@ -148,6 +149,7 @@ ChannelsAuthorizations::ChannelsAuthorizations(std::string_view allow, std::stri
::normalize(ids, large_ids, channel_names::cliprdr, set, this->cliprdr_restriction_, cliprde_list());
::normalize(ids, large_ids, channel_names::rdpdr, set, this->rdpdr_restriction_, rdpdr_list());
::normalize(ids, large_ids, channel_names::rdpsnd, set, this->rdpsnd_restriction_, rdpsnd_list());
::normalize(ids, large_ids, CHANNELS::ChannelNameId(), set, this->rdpcap_restriction_, rdpcap_list());
};

normalize(true, allow_ids, allow_large_ids);
Expand All @@ -167,7 +169,7 @@ ChannelsAuthorizations::ChannelsAuthorizations(std::string_view allow, std::stri
cliprdr_up_is_authorized() || cliprdr_down_is_authorized());
bool const is_allowed = (
contains_true(this->rdpdr_restriction_)
|| contains_true(this->rdpsnd_restriction_));
|| contains_true(this->rdpsnd_restriction_));
normalize_channel(channel_names::rdpdr, is_allowed);
normalize_channel(channel_names::rdpsnd, is_allowed);

Expand Down Expand Up @@ -262,45 +264,9 @@ bool ChannelsAuthorizations::rdpsnd_audio_output_is_authorized() const noexcept
return this->rdpsnd_restriction_[0];
}

REDEMPTION_OSTREAM(out, ChannelsAuthorizations const & auth)
bool ChannelsAuthorizations::rdpsnd_audio_input_is_authorized() const noexcept
{
auto p = [&](
std::vector<CHANNELS::ChannelNameId> const & ids,
bool all, bool val_ok, const char * name
) {
if (all) {
out << name << "=*\n";
}
else {
out << name << '=';
for (size_t i = 0; i < auth.cliprdr_restriction_.size(); ++i) {
if (auth.cliprdr_restriction_[i] == val_ok) {
out << ChannelsAuthorizations::cliprde_list()[i].data();
}
}
for (size_t i = 0; i < auth.rdpdr_restriction_.size(); ++i) {
if (auth.rdpdr_restriction_[i] == val_ok) {
out << ChannelsAuthorizations::rdpdr_list()[i].data();
}
}
for (size_t i = 0; i < auth.rdpsnd_restriction_.size(); ++i) {
if (auth.rdpsnd_restriction_[i] == val_ok) {
out << ChannelsAuthorizations::rdpsnd_list()[i].data();
}
}

for (auto && id : ids) {
out << id << ',';
}
out << '\n';
}
};
auto rng_allow = array_view<CHANNELS::ChannelNameId>{auth.allow_and_deny_.data(), auth.allow_and_deny_.data() + auth.allow_and_deny_pivot_};
auto rng_deny = array_view<CHANNELS::ChannelNameId>{auth.allow_and_deny_.data() + auth.allow_and_deny_pivot_, auth.allow_and_deny_.data() + auth.allow_and_deny_.size()};

p(rng_allow, auth.all_allow_, true, "allow");
p(rng_deny, auth.all_deny_, false, "deny");
return out;
return this->rdpcap_restriction_[0];
}

std::pair<std::string,std::string>
Expand Down Expand Up @@ -344,6 +310,7 @@ update_authorized_channels(std::string allow, std::string deny, std::string prox
remove(s, "cliprdr,");
remove(s, "rdpdr,");
remove(s, "rdpsnd,");
// not name for audio capture because not a static channel
for (auto str : ChannelsAuthorizations::cliprde_list()) {
remove(s, {str.data(), str.size()});
}
Expand All @@ -358,9 +325,9 @@ update_authorized_channels(std::string allow, std::string deny, std::string prox
}
}

constexpr struct {
const char * opt;
const char * channel;
static constexpr struct {
std::string_view opt;
std::string_view channel;
} opts_channels[] {
{"RDP_CLIPBOARD_UP", ",cliprdr_up" },
{"RDP_CLIPBOARD_DOWN", ",cliprdr_down" },
Expand All @@ -372,13 +339,16 @@ update_authorized_channels(std::string allow, std::string deny, std::string prox
{"RDP_DRIVE_WRITE", ",rdpdr_drive_write" },
{"RDP_SMARTCARD", ",rdpdr_smartcard" },

{"RDP_AUDIO_OUTPUT", ",rdpsnd_audio_output" }
{"RDP_AUDIO_OUTPUT", ",rdpsnd_audio_output" },

{"RDP_AUDIO_INPUT", ",rdpcap_audio_input" },
};

static_assert(
decltype(ChannelsAuthorizations::cliprde_list())().size()
+ decltype(ChannelsAuthorizations::rdpdr_list())().size()
+ decltype(ChannelsAuthorizations::rdpsnd_list())().size()
+ decltype(ChannelsAuthorizations::rdpdr_list())().size()
+ decltype(ChannelsAuthorizations::rdpsnd_list())().size()
+ decltype(ChannelsAuthorizations::rdpcap_list())().size()
== std::extent<decltype(opts_channels)>::value
, "opts_channels.size() error");

Expand All @@ -391,5 +361,6 @@ update_authorized_channels(std::string allow, std::string deny, std::string prox
s.erase(0,1);
}
}

return {allow, deny};
}
14 changes: 11 additions & 3 deletions src/core/channels_authorizations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#include "core/channel_names.hpp"
#include "utils/sugar/array_view.hpp"
#include "utils/sugar/std_stream_proto.hpp"

#include <vector>
#include <string>
Expand All @@ -49,8 +48,7 @@ class ChannelsAuthorizations
[[nodiscard]] bool rdpdr_drive_write_is_authorized() const noexcept;

[[nodiscard]] bool rdpsnd_audio_output_is_authorized() const noexcept;

REDEMPTION_FRIEND_OSTREAM(out, ChannelsAuthorizations const & auth);
[[nodiscard]] bool rdpsnd_audio_input_is_authorized() const noexcept;

[[nodiscard]] bool cliprdr_up_is_authorized() const noexcept;
[[nodiscard]] bool cliprdr_down_is_authorized() const noexcept;
Expand All @@ -65,6 +63,7 @@ class ChannelsAuthorizations
cstr_array_view("cliprdr_file,"),
}};
}

static constexpr std::array<chars_view, 5> rdpdr_list()
{
return {{
Expand All @@ -75,13 +74,21 @@ class ChannelsAuthorizations
cstr_array_view("rdpdr_smartcard,"),
}};
}

static constexpr std::array<chars_view, 1> rdpsnd_list()
{
return {{
cstr_array_view("rdpsnd_audio_output,"),
}};
}

static constexpr std::array<chars_view, 1> rdpcap_list()
{
return {{
cstr_array_view("rdpcap_audio_input,"),
}};
}

// Boolean structures moved around in other parts of the code
// could merely be restricted to what we have below
// See equivalent fields in : core/file_system_virtual_channel_params.hpp
Expand Down Expand Up @@ -116,6 +123,7 @@ class ChannelsAuthorizations
std::array<bool, decltype(rdpdr_list())().size()> rdpdr_restriction_ {{}};
std::array<bool, decltype(cliprde_list())().size()> cliprdr_restriction_ {{}};
std::array<bool, decltype(rdpsnd_list())().size()> rdpsnd_restriction_ {{}};
std::array<bool, decltype(rdpcap_list())().size()> rdpcap_restriction_ {{}};
};

std::pair<std::string,std::string>
Expand Down
4 changes: 4 additions & 0 deletions src/core/client_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ struct ClientInfo
int rdp_autologin = 0;
int encryptionLevel = 3; /* 1, 2, 3 = low, medium, high */
bool has_sound_code = false; /* 1 = leave sound at server */
bool has_sound_capture_code = false;
uint32_t rdp5_performanceflags = 0;
int brush_cache_code = 0; /* 0 = no cache 1 = 8x8 standard cache
2 = arbitrary dimensions */
Expand Down Expand Up @@ -215,6 +216,9 @@ struct ClientInfo
if (infoPacket.flags & INFO_REMOTECONSOLEAUDIO) {
this->has_sound_code = true;
}
if (infoPacket.flags & INFO_AUDIOCAPTURE) {
this->has_sound_capture_code = true;
}
if (infoPacket.flags & INFO_AUTOLOGON){
this->rdp_autologin = 1;
}
Expand Down
9 changes: 8 additions & 1 deletion src/mod/rdp/rdp_negociation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ RdpNegociation::RdpNegociation(
, cs_monitor_ex(info.cs_monitor_ex)
, perform_automatic_reconnection(mod_rdp_params.perform_automatic_reconnection)
, server_auto_reconnect_packet_ref(mod_rdp_params.server_auto_reconnect_packet_ref)
, info_packet_extra_flags(info.has_sound_code ? INFO_REMOTECONSOLEAUDIO : InfoPacketFlags{})
, info_packet_extra_flags(InfoPacketFlags(
(info.has_sound_code ? INFO_REMOTECONSOLEAUDIO : InfoPacketFlags{})
| (info.has_sound_capture_code ? INFO_AUDIOCAPTURE : InfoPacketFlags{})
))
, has_managed_drive(has_managed_drive)
, convert_remoteapp_to_desktop(convert_remoteapp_to_desktop)
, send_channel_index(0)
Expand Down Expand Up @@ -1626,6 +1629,10 @@ void RdpNegociation::send_client_info_pdu()
infoPacket.flags |= INFO_NOAUDIOPLAYBACK;
}

if (!this->channels_authorizations.rdpsnd_audio_input_is_authorized()) {
infoPacket.flags &= ~INFO_AUDIOCAPTURE;
}

if (this->perform_automatic_reconnection) {
InStream in_s(this->server_auto_reconnect_packet_ref);
RDP::ServerAutoReconnectPacket server_auto_reconnect_packet;
Expand Down
Loading

0 comments on commit 2c6ea60

Please sign in to comment.