Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xiph.Org
Icecast-Server
Commits
4d7a60d5
Commit
4d7a60d5
authored
Sep 14, 2018
by
Philipp Schafft
🦁
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feature: Added basic support for auth backends to manipulate the client
parent
dabf9337
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
166 additions
and
23 deletions
+166
-23
src/admin.c
src/admin.c
+1
-1
src/auth.c
src/auth.c
+72
-2
src/auth.h
src/auth.h
+21
-0
src/client.c
src/client.c
+32
-13
src/client.h
src/client.h
+3
-1
src/connection.c
src/connection.c
+5
-0
src/errors.c
src/errors.c
+14
-0
src/errors.h
src/errors.h
+1
-0
src/stats.c
src/stats.c
+1
-1
src/xslt.c
src/xslt.c
+15
-4
src/xslt.h
src/xslt.h
+1
-1
No files found.
src/admin.c
View file @
4d7a60d5
...
...
@@ -470,7 +470,7 @@ void admin_send_response(xmlDocPtr doc,
config_release_config
();
ICECAST_LOG_DEBUG
(
"Sending XSLT (%s)"
,
fullpath_xslt_template
);
xslt_transform
(
doc
,
fullpath_xslt_template
,
client
,
200
);
xslt_transform
(
doc
,
fullpath_xslt_template
,
client
,
200
,
NULL
);
free
(
fullpath_xslt_template
);
}
}
...
...
src/auth.c
View file @
4d7a60d5
...
...
@@ -227,9 +227,11 @@ void auth_addref (auth_t *authenticator) {
static
void
auth_client_free
(
auth_client
*
auth_user
)
{
if
(
auth_user
==
NULL
)
if
(
!
auth_user
)
return
;
free
(
auth_user
);
free
(
auth_user
->
alter_client_arg
);
free
(
auth_user
);
}
...
...
@@ -295,6 +297,55 @@ static auth_result auth_remove_client(auth_t *auth, auth_client *auth_user)
return
ret
;
}
static
inline
int
__handle_auth_client_alter
(
auth_t
*
auth
,
auth_client
*
auth_user
)
{
client_t
*
client
=
auth_user
->
client
;
const
char
*
uuid
=
NULL
;
const
char
*
location
=
NULL
;
int
http_status
=
0
;
void
client_send_redirect
(
client_t
*
client
,
const
char
*
uuid
,
int
status
,
const
char
*
location
);
switch
(
auth_user
->
alter_client_action
)
{
case
AUTH_ALTER_NOOP
:
return
0
;
break
;
case
AUTH_ALTER_REWRITE
:
free
(
client
->
uri
);
client
->
uri
=
auth_user
->
alter_client_arg
;
auth_user
->
alter_client_arg
=
NULL
;
return
0
;
break
;
case
AUTH_ALTER_REDIRECT
:
/* fall through */
case
AUTH_ALTER_REDIRECT_SEE_OTHER
:
uuid
=
"be7fac90-54fb-4673-9e0d-d15d6a4963a2"
;
http_status
=
303
;
location
=
auth_user
->
alter_client_arg
;
break
;
case
AUTH_ALTER_REDIRECT_TEMPORARY
:
uuid
=
"4b08a03a-ecce-4981-badf-26b0bb6c9d9c"
;
http_status
=
307
;
location
=
auth_user
->
alter_client_arg
;
break
;
case
AUTH_ALTER_REDIRECT_PERMANENT
:
uuid
=
"36bf6815-95cb-4cc8-a7b0-6b4b0c82ac5d"
;
http_status
=
308
;
location
=
auth_user
->
alter_client_arg
;
break
;
case
AUTH_ALTER_SEND_ERROR
:
client_send_error_by_uuid
(
client
,
auth_user
->
alter_client_arg
);
return
1
;
break
;
}
if
(
uuid
&&
location
&&
http_status
)
{
client_send_redirect
(
client
,
uuid
,
http_status
,
location
);
return
1
;
}
return
-
1
;
}
static
void
__handle_auth_client
(
auth_t
*
auth
,
auth_client
*
auth_user
)
{
auth_result
result
;
...
...
@@ -315,6 +366,11 @@ static void __handle_auth_client (auth_t *auth, auth_client *auth_user) {
auth_user
->
client
->
role
=
strdup
(
auth
->
role
);
}
if
(
result
!=
AUTH_NOMATCH
)
{
if
(
__handle_auth_client_alter
(
auth
,
auth_user
)
==
1
)
return
;
}
if
(
result
==
AUTH_NOMATCH
&&
auth_user
->
on_no_match
)
{
auth_user
->
on_no_match
(
auth_user
->
client
,
auth_user
->
on_result
,
auth_user
->
userdata
);
}
else
if
(
auth_user
->
on_result
)
{
...
...
@@ -743,6 +799,20 @@ auth_t *auth_get_authenticator(xmlNodePtr node)
return
auth
;
}
int
auth_alter_client
(
auth_t
*
auth
,
auth_client
*
auth_user
,
auth_alter_t
action
,
const
char
*
arg
)
{
if
(
!
auth
||
!
auth_user
||
!
arg
)
return
-
1
;
/* TODO: check if auth backend has the permission for this operation */
if
(
replace_string
(
&
(
auth_user
->
alter_client_arg
),
arg
)
!=
0
)
return
-
1
;
auth_user
->
alter_client_action
=
action
;
return
0
;
}
/* these are called at server start and termination */
...
...
src/auth.h
View file @
4d7a60d5
...
...
@@ -65,6 +65,23 @@ typedef enum {
AUTH_MATCHTYPE_NOMATCH
}
auth_matchtype_t
;
typedef
enum
{
/* Used internally by auth system. */
AUTH_ALTER_NOOP
=
0
,
/* Internal rewrite of URI */
AUTH_ALTER_REWRITE
,
/* Redirect to another location. */
AUTH_ALTER_REDIRECT
,
/* See some other resource */
AUTH_ALTER_REDIRECT_SEE_OTHER
,
/* This resource is currently located elsewhere */
AUTH_ALTER_REDIRECT_TEMPORARY
,
/* This resource is now located at new location */
AUTH_ALTER_REDIRECT_PERMANENT
,
/* Send an error report to the client */
AUTH_ALTER_SEND_ERROR
}
auth_alter_t
;
typedef
struct
auth_client_tag
auth_client
;
struct
auth_client_tag
{
client_t
*
client
;
...
...
@@ -72,6 +89,8 @@ struct auth_client_tag {
void
(
*
on_no_match
)(
client_t
*
client
,
void
(
*
on_result
)(
client_t
*
client
,
void
*
userdata
,
auth_result
result
),
void
*
userdata
);
void
(
*
on_result
)(
client_t
*
client
,
void
*
userdata
,
auth_result
result
);
void
*
userdata
;
auth_alter_t
alter_client_action
;
char
*
alter_client_arg
;
auth_client
*
next
;
};
...
...
@@ -154,6 +173,8 @@ void auth_stack_add_client(auth_stack_t *stack,
auth_result
result
),
void
*
userdata
);
int
auth_alter_client
(
auth_t
*
auth
,
auth_client
*
auth_user
,
auth_alter_t
action
,
const
char
*
arg
);
void
auth_stack_release
(
auth_stack_t
*
stack
);
void
auth_stack_addref
(
auth_stack_t
*
stack
);
int
auth_stack_next
(
auth_stack_t
**
stack
);
/* returns -1 on error, 0 on success, +1 if no next element is present */
...
...
src/client.c
View file @
4d7a60d5
...
...
@@ -302,7 +302,7 @@ int client_read_bytes(client_t *client, void *buf, unsigned len)
return
bytes
;
}
static
inline
void
_client_send_
err
or
(
client_t
*
client
,
const
icecast_error_t
*
error
)
static
inline
void
_client_send_
rep
or
t
(
client_t
*
client
,
const
char
*
uuid
,
const
char
*
message
,
int
http_status
,
const
char
*
location
)
{
reportxml_t
*
report
;
admin_format_t
admin_format
;
...
...
@@ -325,17 +325,15 @@ static inline void _client_send_error(client_t *client, const icecast_error_t *e
break
;
}
report
=
client_get_reportxml
(
uuid
,
NULL
,
message
);
report
=
client_get_reportxml
(
error
->
uuid
,
NULL
,
error
->
message
);
client_send_reportxml
(
client
,
report
,
DOCUMENT_DOMAIN_ADMIN
,
xslt
,
admin_format
,
error
->
http_status
);
client_send_reportxml
(
client
,
report
,
DOCUMENT_DOMAIN_ADMIN
,
xslt
,
admin_format
,
http_status
,
location
);
refobject_unref
(
report
);
}
void
client_send_error_by_
id
(
client_t
*
client
,
icecast_error_
id_t
id
)
void
client_send_error_by_
error
(
client_t
*
client
,
const
icecast_error_
t
*
error
)
{
const
icecast_error_t
*
error
=
error_get_by_id
(
id
);
if
(
!
error
)
{
client_send_500
(
client
,
"Unknown error ID"
);
...
...
@@ -347,7 +345,15 @@ void client_send_error_by_id(client_t *client, icecast_error_id_t id)
return
;
}
_client_send_error
(
client
,
error
);
_client_send_report
(
client
,
error
->
uuid
,
error
->
message
,
error
->
http_status
,
NULL
);
}
void
client_send_error_by_uuid
(
client_t
*
client
,
const
char
*
uuid
)
{
client_send_error_by_error
(
client
,
error_get_by_uuid
(
uuid
));
}
void
client_send_error_by_id
(
client_t
*
client
,
icecast_error_id_t
id
)
{
client_send_error_by_error
(
client
,
error_get_by_id
(
id
));
}
void
client_send_101
(
client_t
*
client
,
reuse_t
reuse
)
...
...
@@ -458,8 +464,13 @@ static inline void client_send_500(client_t *client, const char *message)
client_destroy
(
client
);
}
void
client_send_redirect
(
client_t
*
client
,
const
char
*
uuid
,
int
status
,
const
char
*
location
)
{
_client_send_report
(
client
,
uuid
,
"Redirecting"
,
status
,
location
);
}
/* this function sends a reportxml file to the client in the prefered format. */
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
)
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
,
const
char
*
location
)
{
admin_format_t
admin_format
;
xmlDocPtr
doc
;
...
...
@@ -514,13 +525,18 @@ void client_send_reportxml(client_t *client, reportxml_t *report, document_domai
if
(
admin_format
==
ADMIN_FORMAT_RAW
)
{
xmlChar
*
buff
=
NULL
;
size_t
location_length
=
0
;
int
len
=
0
;
size_t
buf_len
;
ssize_t
ret
;
xmlDocDumpMemory
(
doc
,
&
buff
,
&
len
);
buf_len
=
len
+
1024
;
if
(
location
)
{
location_length
=
strlen
(
location
);
}
buf_len
=
len
+
location_length
+
1024
;
if
(
buf_len
<
4096
)
buf_len
=
4096
;
...
...
@@ -536,9 +552,9 @@ void client_send_reportxml(client_t *client, reportxml_t *report, document_domai
client_send_error_by_id
(
client
,
ICECAST_ERROR_GEN_HEADER_GEN_FAILED
);
xmlFree
(
buff
);
return
;
}
else
if
(
buf_len
<
(
size_t
)(
len
+
ret
+
64
))
{
}
else
if
(
buf_len
<
(
size_t
)(
len
+
location_length
+
ret
+
128
))
{
void
*
new_data
;
buf_len
=
ret
+
len
+
64
;
buf_len
=
ret
+
len
+
128
;
new_data
=
realloc
(
client
->
refbuf
->
data
,
buf_len
);
if
(
new_data
)
{
ICECAST_LOG_DEBUG
(
"Client buffer reallocation succeeded."
);
...
...
@@ -563,7 +579,10 @@ void client_send_reportxml(client_t *client, reportxml_t *report, document_domai
}
/* FIXME: in this section we hope no function will ever return -1 */
ret
+=
snprintf
(
client
->
refbuf
->
data
+
ret
,
buf_len
-
ret
,
"Content-Length: %d
\r\n\r\n
%s"
,
xmlStrlen
(
buff
),
buff
);
if
(
location
)
{
ret
+=
snprintf
(
client
->
refbuf
->
data
+
ret
,
buf_len
-
ret
,
"Location: %s
\r\n
"
,
location
);
}
ret
+=
snprintf
(
client
->
refbuf
->
data
+
ret
,
buf_len
-
ret
,
"Content-Length: %d
\r\n\r\n
%s"
,
xmlStrlen
(
buff
),
buff
);
client
->
refbuf
->
len
=
ret
;
xmlFree
(
buff
);
...
...
@@ -598,7 +617,7 @@ void client_send_reportxml(client_t *client, reportxml_t *report, document_domai
ICECAST_LOG_DEBUG
(
"Sending XSLT (%s)"
,
fullpath_xslt_template
);
fastevent_emit
(
FASTEVENT_TYPE_CLIENT_SEND_RESPONSE
,
FASTEVENT_FLAG_MODIFICATION_ALLOWED
,
FASTEVENT_DATATYPE_CLIENT
,
client
);
xslt_transform
(
doc
,
fullpath_xslt_template
,
client
,
status
);
xslt_transform
(
doc
,
fullpath_xslt_template
,
client
,
status
,
location
);
free
(
fullpath_xslt_template
);
}
...
...
src/client.h
View file @
4d7a60d5
...
...
@@ -143,10 +143,12 @@ int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser);
void
client_complete
(
client_t
*
client
);
void
client_destroy
(
client_t
*
client
);
void
client_send_error_by_id
(
client_t
*
client
,
icecast_error_id_t
id
);
void
client_send_error_by_uuid
(
client_t
*
client
,
const
char
*
uuid
);
void
client_send_101
(
client_t
*
client
,
reuse_t
reuse
);
void
client_send_204
(
client_t
*
client
);
void
client_send_426
(
client_t
*
client
,
reuse_t
reuse
);
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
);
void
client_send_redirect
(
client_t
*
client
,
const
char
*
uuid
,
int
status
,
const
char
*
location
);
void
client_send_reportxml
(
client_t
*
client
,
reportxml_t
*
report
,
document_domain_t
domain
,
const
char
*
xsl
,
admin_format_t
admin_format_hint
,
int
status
,
const
char
*
location
);
reportxml_t
*
client_get_reportxml
(
const
char
*
state_definition
,
const
char
*
state_akindof
,
const
char
*
state_text
);
admin_format_t
client_get_admin_format_by_content_negotiation
(
client_t
*
client
);
int
client_send_bytes
(
client_t
*
client
,
const
void
*
buf
,
unsigned
len
);
...
...
src/connection.c
View file @
4d7a60d5
...
...
@@ -105,6 +105,7 @@ static matchfile_t *banned_ip, *allowed_ip;
rwlock_t
_source_shutdown_rwlock
;
static
int
_update_admin_command
(
client_t
*
client
);
static
void
_handle_connection
(
void
);
static
void
get_tls_certificate
(
ice_config_t
*
config
);
...
...
@@ -1277,6 +1278,10 @@ static void _handle_authed_client(client_t *client, void *userdata, auth_result
auth_stack_release
(
client
->
authstack
);
client
->
authstack
=
NULL
;
/* Update admin parameters just in case auth changed our URI */
if
(
_update_admin_command
(
client
)
==
-
1
)
return
;
fastevent_emit
(
FASTEVENT_TYPE_CLIENT_AUTHED
,
FASTEVENT_FLAG_MODIFICATION_ALLOWED
,
FASTEVENT_DATATYPE_CLIENT
,
client
);
if
(
result
!=
AUTH_OK
)
{
...
...
src/errors.c
View file @
4d7a60d5
...
...
@@ -10,6 +10,8 @@
#include <config.h>
#endif
#include <strings.h>
#include "errors.h"
#include "logging.h"
#define CATMODULE "errors"
...
...
@@ -150,3 +152,15 @@ const icecast_error_t * error_get_by_id(icecast_error_id_t id) {
return
NULL
;
}
const
icecast_error_t
*
error_get_by_uuid
(
const
char
*
uuid
)
{
size_t
i
;
for
(
i
=
0
;
i
<
(
sizeof
(
__errors
)
/
sizeof
(
*
__errors
));
i
++
)
{
if
(
strcasecmp
(
__errors
[
i
].
uuid
,
uuid
)
==
0
)
{
return
&
(
__errors
[
i
]);
}
}
return
NULL
;
}
src/errors.h
View file @
4d7a60d5
...
...
@@ -62,5 +62,6 @@ struct icecast_error_tag {
typedef
struct
icecast_error_tag
icecast_error_t
;
const
icecast_error_t
*
error_get_by_id
(
icecast_error_id_t
id
);
const
icecast_error_t
*
error_get_by_uuid
(
const
char
*
uuid
);
#endif
/* __ERRORS_H__ */
src/stats.c
View file @
4d7a60d5
...
...
@@ -1030,7 +1030,7 @@ void stats_transform_xslt(client_t *client)
doc
=
stats_get_xml
(
0
,
mount
,
client
);
xslt_transform
(
doc
,
xslpath
,
client
,
200
);
xslt_transform
(
doc
,
xslpath
,
client
,
200
,
NULL
);
xmlFreeDoc
(
doc
);
free
(
xslpath
);
...
...
src/xslt.c
View file @
4d7a60d5
...
...
@@ -320,7 +320,7 @@ static inline void _send_error(client_t *client, icecast_error_id_t id, int old_
client_send_error_by_id
(
client
,
id
);
}
void
xslt_transform
(
xmlDocPtr
doc
,
const
char
*
xslfilename
,
client_t
*
client
,
int
status
)
void
xslt_transform
(
xmlDocPtr
doc
,
const
char
*
xslfilename
,
client_t
*
client
,
int
status
,
const
char
*
location
)
{
xmlDocPtr
res
;
xsltStylesheetPtr
cur
;
...
...
@@ -374,7 +374,14 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, in
ssize_t
ret
;
int
failed
=
0
;
refbuf_t
*
refbuf
;
size_t
location_length
=
0
;
ssize_t
full_len
=
strlen
(
mediatype
)
+
(
ssize_t
)
len
+
(
ssize_t
)
1024
;
if
(
location
)
{
location_length
=
strlen
(
location
);
full_len
+=
location_length
;
}
if
(
full_len
<
4096
)
full_len
=
4096
;
refbuf
=
refbuf_new
(
full_len
);
...
...
@@ -386,9 +393,9 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, in
ICECAST_LOG_ERROR
(
"Dropping client as we can not build response headers."
);
_send_error
(
client
,
ICECAST_ERROR_GEN_HEADER_GEN_FAILED
,
status
);
}
else
{
if
(
full_len
<
(
ret
+
(
ssize_t
)
len
+
(
ssize_t
)
64
)
)
{
if
(
full_len
<
(
ret
+
(
ssize_t
)
len
+
(
ssize_t
)
128
)
)
{
void
*
new_data
;
full_len
=
ret
+
(
ssize_t
)
len
+
(
ssize_t
)
64
;
full_len
=
ret
+
(
ssize_t
)
len
+
(
ssize_t
)
128
;
new_data
=
realloc
(
refbuf
->
data
,
full_len
);
if
(
new_data
)
{
ICECAST_LOG_DEBUG
(
"Client buffer reallocation succeeded."
);
...
...
@@ -408,7 +415,11 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, in
}
if
(
!
failed
)
{
snprintf
(
refbuf
->
data
+
ret
,
full_len
-
ret
,
"Content-Length: %d
\r\n\r\n
%s"
,
len
,
string
);
/* FIXME: in this section we hope no function will ever return -1 */
if
(
location
)
{
ret
+=
snprintf
(
refbuf
->
data
+
ret
,
full_len
-
ret
,
"Location: %s
\r\n
"
,
location
);
}
ret
+=
snprintf
(
refbuf
->
data
+
ret
,
full_len
-
ret
,
"Content-Length: %d
\r\n\r\n
%s"
,
len
,
string
);
client
->
respcode
=
status
;
client_set_queue
(
client
,
NULL
);
...
...
src/xslt.h
View file @
4d7a60d5
...
...
@@ -16,7 +16,7 @@
#include "icecasttypes.h"
void
xslt_transform
(
xmlDocPtr
doc
,
const
char
*
xslfilename
,
client_t
*
client
,
int
status
);
void
xslt_transform
(
xmlDocPtr
doc
,
const
char
*
xslfilename
,
client_t
*
client
,
int
status
,
const
char
*
location
);
void
xslt_initialize
(
void
);
void
xslt_shutdown
(
void
);
void
xslt_clear_cache
(
void
);
...
...
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