Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
77d74b40
Commit
77d74b40
authored
Oct 14, 2021
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Permission: add option "host_permissions"
Closes
https://github.com/MusicPlayerDaemon/MPD/issues/1115
parent
a636d212
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
99 additions
and
5 deletions
+99
-5
NEWS
NEWS
+1
-0
user.rst
doc/user.rst
+5
-0
Permission.cxx
src/Permission.cxx
+41
-3
Permission.hxx
src/Permission.hxx
+7
-0
Listener.cxx
src/client/Listener.cxx
+6
-2
Option.hxx
src/config/Option.hxx
+1
-0
Templates.cxx
src/config/Templates.cxx
+1
-0
ToString.cxx
src/net/ToString.cxx
+29
-0
ToString.hxx
src/net/ToString.hxx
+8
-0
No files found.
NEWS
View file @
77d74b40
...
...
@@ -25,6 +25,7 @@ ver 0.23 (not yet released)
* tags
- new tags "ComposerSort", "Ensemble", "Movement", "MovementNumber", and "Location"
* split permission "player" from "control"
* add option "host_permissions"
* new build-time dependency: libfmt
ver 0.22.11 (2021/08/24)
...
...
doc/user.rst
View file @
77d74b40
...
...
@@ -650,6 +650,9 @@ By default, all clients are unauthenticated and have a full set of permissions.
:
code
:`
local_permissions
`
may
be
used
to
assign
other
permissions
to
clients
connecting
on
a
local
socket
.
:
code
:`
host_permissions
`
may
be
used
to
assign
permissions
to
clients
with
a
certain
IP
address
.
:
code
:`
password
`
allows
the
client
to
send
a
password
to
gain
other
permissions
.
This
option
may
be
specified
multiple
times
with
different
passwords
.
Note
that
the
:
code
:`
password
`
option
is
not
secure
:
passwords
are
sent
in
clear
-
text
over
the
connection
,
and
the
client
cannot
verify
the
server
's identity.
...
...
@@ -659,6 +662,8 @@ Example:
.. code-block:: none
default_permissions "read"
host_permissions "192.168.0.100 read,add,control,admin"
host_permissions "2003:1234:4567::1 read,add,control,admin"
password "the_password@read,add,control"
password "the_admin_password@read,add,control,admin"
...
...
src/Permission.cxx
View file @
77d74b40
...
...
@@ -22,6 +22,9 @@
#include "config/Param.hxx"
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "net/AddressInfo.hxx"
#include "net/Resolver.hxx"
#include "net/ToString.hxx"
#include "util/IterableSplitString.hxx"
#include "util/RuntimeError.hxx"
#include "util/StringView.hxx"
...
...
@@ -55,6 +58,10 @@ static unsigned permission_default;
static
unsigned
local_permissions
;
#endif
#ifdef HAVE_TCP
static
std
::
map
<
std
::
string
,
unsigned
>
host_passwords
;
#endif
static
unsigned
ParsePermission
(
StringView
s
)
{
...
...
@@ -66,10 +73,9 @@ ParsePermission(StringView s)
int
(
s
.
size
),
s
.
data
);
}
static
unsigned
parsePermissions
(
const
char
*
string
)
static
unsigned
parsePermissions
(
std
::
string_view
string
)
{
assert
(
string
!=
nullptr
);
unsigned
permission
=
0
;
for
(
const
auto
i
:
IterableSplitString
(
string
,
PERMISSION_SEPARATOR
))
...
...
@@ -120,8 +126,40 @@ initPermissions(const ConfigData &config)
:
permission_default
;
});
#endif
#ifdef HAVE_TCP
for
(
const
auto
&
param
:
config
.
GetParamList
(
ConfigOption
::
HOST_PERMISSIONS
))
{
permission_default
=
0
;
param
.
With
([](
StringView
value
){
auto
[
host_sv
,
permissions_s
]
=
value
.
Split
(
' '
);
unsigned
permissions
=
parsePermissions
(
permissions_s
);
const
std
::
string
host_s
{
host_sv
};
for
(
const
auto
&
i
:
Resolve
(
host_s
.
c_str
(),
0
,
AI_PASSIVE
,
SOCK_STREAM
))
host_passwords
.
emplace
(
HostToString
(
i
),
permissions
);
});
}
#endif
}
#ifdef HAVE_TCP
int
GetPermissionsFromAddress
(
SocketAddress
address
)
noexcept
{
if
(
auto
i
=
host_passwords
.
find
(
HostToString
(
address
));
i
!=
host_passwords
.
end
())
return
i
->
second
;
return
-
1
;
}
#endif
int
getPermissionFromPassword
(
const
char
*
password
,
unsigned
*
permission
)
noexcept
{
...
...
src/Permission.hxx
View file @
77d74b40
...
...
@@ -23,6 +23,7 @@
#include "config.h"
struct
ConfigData
;
class
SocketAddress
;
static
constexpr
unsigned
PERMISSION_NONE
=
0
;
static
constexpr
unsigned
PERMISSION_READ
=
1
;
...
...
@@ -45,6 +46,12 @@ unsigned
GetLocalPermissions
()
noexcept
;
#endif
#ifdef HAVE_TCP
[[
gnu
::
pure
]]
int
GetPermissionsFromAddress
(
SocketAddress
address
)
noexcept
;
#endif
void
initPermissions
(
const
ConfigData
&
config
);
...
...
src/client/Listener.cxx
View file @
77d74b40
...
...
@@ -32,8 +32,12 @@ GetPermissions(SocketAddress address, int uid) noexcept
#ifdef HAVE_UN
if
(
address
.
GetFamily
()
==
AF_LOCAL
)
return
GetLocalPermissions
();
#else
(
void
)
address
;
#endif
#ifdef HAVE_TCP
if
(
int
permissions
=
GetPermissionsFromAddress
(
address
);
permissions
>=
0
)
return
permissions
;
#endif
return
getDefaultPermissions
();
...
...
src/config/Option.hxx
View file @
77d74b40
...
...
@@ -48,6 +48,7 @@ enum class ConfigOption {
ZEROCONF_NAME
,
ZEROCONF_ENABLED
,
PASSWORD
,
HOST_PERMISSIONS
,
LOCAL_PERMISSIONS
,
DEFAULT_PERMS
,
AUDIO_OUTPUT_FORMAT
,
...
...
src/config/Templates.cxx
View file @
77d74b40
...
...
@@ -44,6 +44,7 @@ const ConfigTemplate config_param_templates[] = {
{
"zeroconf_name"
},
{
"zeroconf_enabled"
},
{
"password"
,
true
},
{
"host_permissions"
,
true
},
{
"local_permissions"
},
{
"default_permissions"
},
{
"audio_output_format"
},
...
...
src/net/ToString.cxx
View file @
77d74b40
...
...
@@ -116,3 +116,32 @@ ToString(SocketAddress address) noexcept
result
.
append
(
serv
);
return
result
;
}
std
::
string
HostToString
(
SocketAddress
address
)
noexcept
{
if
(
address
.
IsNull
())
return
"null"
;
#ifdef HAVE_UN
if
(
address
.
GetFamily
()
==
AF_LOCAL
)
/* return path of local socket */
return
LocalAddressToString
(
address
.
CastTo
<
struct
sockaddr_un
>
(),
address
.
GetSize
());
#endif
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
IPv4Address
ipv4_buffer
;
if
(
address
.
IsV4Mapped
())
address
=
ipv4_buffer
=
address
.
UnmapV4
();
#endif
char
host
[
NI_MAXHOST
],
serv
[
NI_MAXSERV
];
int
ret
=
getnameinfo
(
address
.
GetAddress
(),
address
.
GetSize
(),
host
,
sizeof
(
host
),
serv
,
sizeof
(
serv
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
if
(
ret
!=
0
)
return
"unknown"
;
return
host
;
}
src/net/ToString.hxx
View file @
77d74b40
...
...
@@ -42,4 +42,12 @@ class SocketAddress;
std
::
string
ToString
(
SocketAddress
address
)
noexcept
;
/**
* Generates the string representation of a #SocketAddress into the
* specified buffer, without the port number.
*/
[[
gnu
::
pure
]]
std
::
string
HostToString
(
SocketAddress
address
)
noexcept
;
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment