Compare commits

...

10 Commits

Author SHA1 Message Date
Justin Maggard
1a9b32ee7a Wrap up version 1.3.3. 2023-05-31 01:25:59 -07:00
Justin Maggard
9bd58553fa upnphttp: Fix chunk length parsing 2023-05-31 00:41:07 -07:00
Robert Högberg
d809ab778f locale: Improve Swedish translation 2023-05-31 00:37:50 -07:00
Justin Maggard
b4dd1e28f9 locale: Improve Dutch translation
I am a native Dutch speaker and attached a patch to improve the Dutch
translations. Especially one is important as it was a Swedish text,
instead of Dutch.

Manuel Bilderbeek
2023-05-31 00:31:08 -07:00
Justin Maggard
c7a1c900ab upnpsoap: Error out earlier on certain SQLi attempts 2023-05-31 00:28:21 -07:00
Stefan Eßer
5df410a53d Do not remove kevent from closed request sockwt.
After a successful transfer pass EV_FLAG_CLOSING to the kevent delete
function since the corresponding socket has been been closed and there
is no kevent request record to delete.

This prevents spurious error messages:

    kqueue.c:210: error: kevent() error 9 on 2391 filter:-1 flags:0x4000
2023-05-31 00:02:12 -07:00
Georgy Kibardin
c5c4d9e169 monitor: Fix directory symlink deletion handling
When a symlink to a direcotry is deleted inotify cannot tell it from a
regular file rendering all its children orphans.
This sometimes leads to an unexpected effect - they may appear later in
a newly created directory when it gets an id used by the deleted symlink.
2023-05-30 23:54:44 -07:00
Justin Maggard
0a6e10e821 Wrap up version 1.3.2 2022-08-29 22:42:54 -07:00
Justin Maggard
f140859351 upnphttp: Improve DNS rebinding attack protection
Detect invalid IP addresses in the Host field and reject as needed.
2022-08-29 22:36:53 -07:00
Justin Maggard
f35304a5d2 build: Fix libexif test 2022-08-29 22:36:53 -07:00
13 changed files with 87 additions and 34 deletions

12
NEWS
View File

@ -1,3 +1,15 @@
1.3.3 - Released 1-Jun-2023
--------------------------------
- Fixed HTTP chunk length parsing.
- Improved Dutch and Swedish translations.
- Fixed directory symlink deletion handling.
1.3.2 - Released 30-Aug-2022
--------------------------------
- Improved DNS rebinding attack protection.
- Added Samsung Neo QLED series (2021) support.
- Added webm/rm/rmvb support.
1.3.1 - Released 11-Feb-2022
--------------------------------
- Fixed a potential crash in SSDP request parsing.

View File

@ -9,5 +9,5 @@ export BR2_EXTERNAL=$(realpath .)
cd $BUILDROOT_DIR
make O=output-readymedia defconfig BR2_DEFCONFIG=${BR2_DEFCONFIG}
make O=output-readymedia
echo -e "\n\nStatic binary built in $(realpath output/target/usr/sbin/minidlnad)"
ls -lh $(realpath output/target/usr/sbin/minidlnad)
echo -e "\n\nStatic binary built in $(realpath output-readymedia/target/usr/sbin/minidlnad)"
ls -lh $(realpath output-readymedia/target/usr/sbin/minidlnad)

View File

@ -4,8 +4,9 @@
#
################################################################################
READYMEDIA_VERSION = v1_3_1
READYMEDIA_VERSION = v1_3_3
READYMEDIA_SITE = https://git.code.sf.net/p/minidlna/git
#READYMEDIA_SITE = ssh://localhost/home/jmaggard/source/minidlna
READYMEDIA_SITE_METHOD = git
READYMEDIA_LICENSE = GPL-2.0, BSD-3-Clause
READYMEDIA_LICENSE_FILES = COPYING LICENCE.miniupnpd

View File

@ -404,7 +404,7 @@ for dir in "" /usr/local $SEARCH_DIR; do
AC_CHECK_LIB([exif], [exif_data_new_from_file], [LIBEXIF_LIBS="-lexif"], [unset ac_cv_lib_exif_exif_data_new_from_file; LDFLAGS="$LDFLAGS_SAVE"; continue])
break
done
test x"$ac_cv_lib_jpeg_jpeg_set_defaults" = x"yes" || AC_MSG_ERROR([Could not find libexif])
test x"$ac_cv_lib_exif_exif_data_new_from_file" = x"yes" || AC_MSG_ERROR([Could not find libexif])
AC_SUBST(LIBEXIF_LIBS)
LDFLAGS_SAVE="$LDFLAGS"

View File

@ -366,21 +366,13 @@ monitor_insert_directory(int fd, char *name, const char * path)
}
int
monitor_remove_directory(int fd, const char * path)
monitor_remove_tree(const char * path)
{
char * sql;
char **result;
int64_t detailID = 0;
int rows, i, ret = 1;
/* Invalidate the scanner cache so we don't insert files into non-existent containers */
valid_cache = 0;
#ifdef HAVE_WATCH
if( fd > 0 )
{
monitor_remove_watch(fd, path);
}
#endif
sql = sqlite3_mprintf("SELECT ID from DETAILS where (PATH > '%q/' and PATH <= '%q/%c')"
" or PATH = '%q'", path, path, 0xFF, path);
if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) )
@ -403,3 +395,17 @@ monitor_remove_directory(int fd, const char * path)
return ret;
}
int
monitor_remove_directory(int fd, const char * path)
{
/* Invalidate the scanner cache so we don't insert files into non-existent containers */
valid_cache = 0;
#ifdef HAVE_WATCH
if( fd > 0 )
{
monitor_remove_watch(fd, path);
}
#endif
return monitor_remove_tree(path);
}

View File

@ -1,6 +1,7 @@
int monitor_insert_file(const char *name, const char *path);
int monitor_insert_directory(int fd, char *name, const char * path);
int monitor_remove_file(const char * path);
int monitor_remove_tree(const char * path);
int monitor_remove_directory(int fd, const char * path);
#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)

View File

@ -366,7 +366,16 @@ inotify_thread(void *arg)
if ( event->mask & IN_ISDIR )
monitor_remove_directory(pollfds[0].fd, path_buf);
else
{
monitor_remove_file(path_buf);
/*
* When a symlink to a directory is deleted
* we cannot tell it from a regular file deletion
* to prevent its children from becoming orphans
* we delete the whole tree when it exists
*/
monitor_remove_tree(path_buf);
}
}
free(esc_name);
}

View File

@ -70,7 +70,7 @@ msgstr "Afspeellijst"
#: scanner.c:598
msgid "Recently Added"
msgstr "Nyligen tillagd"
msgstr "Recent toegevoegd"
#: scanner.c:536
msgid "Video"
@ -103,9 +103,9 @@ msgstr "Mappen doorzoeken"
#: scanner.c:690
#, c-format
msgid "Scanning %s\n"
msgstr "Zoeken %s\n"
msgstr "%s aan het scannen\n"
#: scanner.c:766
#, c-format
msgid "Scanning %s finished (%llu files)!\n"
msgstr "Zoeken %s gereed (%llu files)!\n"
msgstr "Scannen van %s gereed (%llu bestanden)!\n"

View File

@ -46,7 +46,7 @@ msgstr "Musik"
#: scanner.c:529
msgid "All Music"
msgstr "All Musik"
msgstr "All musik"
#: scanner.c:530
msgid "Genre"
@ -66,11 +66,11 @@ msgstr "Mappar"
#: scanner.c:534
msgid "Playlists"
msgstr "Spelningslistor"
msgstr "Spellistor"
#: scanner.c:598
msgid "Recently Added"
msgstr "nyligen tillagda"
msgstr "Nyss tillagt"
#: scanner.c:536
msgid "Video"
@ -108,4 +108,5 @@ msgstr "Söker %s\n"
#: scanner.c:766
#, c-format
msgid "Scanning %s finished (%llu files)!\n"
msgstr "Avsökning %s slutförd (%llu filer)!\n"
msgstr "Genomsökning av %s slutförd (%llu filer)!\n"

View File

@ -391,7 +391,7 @@ static void upnp_event_recv(struct upnp_event_notify * obj)
DPRINTF(E_DEBUG, L_HTTP, "%s: (%dbytes) %.*s\n", "upnp_event_recv",
n, n, obj->buffer);
obj->state = EFinished;
event_module.del(&obj->ev, 0);
event_module.del(&obj->ev, EV_FLAG_CLOSING);
if(obj->sub)
{
obj->sub->seq++;

View File

@ -57,7 +57,7 @@
#include <sqlite3.h>
#define MINIDLNA_VERSION "1.3.1"
#define MINIDLNA_VERSION "1.3.3"
#ifdef NETGEAR
# define SERVER_NAME "ReadyDLNA"

View File

@ -432,7 +432,7 @@ next_header:
if (h->req_buflen <= h->req_contentoff)
return;
while( (line < (h->req_buf + h->req_buflen)) &&
(h->req_chunklen = strtol(line, &endptr, 16) > 0) &&
((h->req_chunklen = strtol(line, &endptr, 16)) > 0) &&
(endptr != line) )
{
endptr = strstr(endptr, "\r\n");
@ -915,15 +915,29 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
DPRINTF(E_DEBUG, L_HTTP, "HTTP REQUEST: %.*s\n", h->req_buflen, h->req_buf);
if(h->req_Host && h->req_HostLen > 0) {
const char *ptr = h->req_Host;
const char *port = memchr(h->req_Host, ':', h->req_HostLen);
size_t ip_sz = port ? (port - h->req_Host) : h->req_HostLen;
struct in_addr addr;
char ip_buf[16];
DPRINTF(E_MAXDEBUG, L_HTTP, "Host: %.*s\n", h->req_HostLen, h->req_Host);
for(i = 0; i < h->req_HostLen; i++) {
if(*ptr != ':' && *ptr != '.' && (*ptr > '9' || *ptr < '0')) {
DPRINTF(E_ERROR, L_HTTP, "DNS rebinding attack suspected (Host: %.*s)", h->req_HostLen, h->req_Host);
Send404(h);/* 403 */
if (port) {
const char *ptr = port + 1;
for (i = ip_sz + 2; i < h->req_HostLen; i++) {
if (*ptr > '9' || *ptr < '0')
break;
ptr++;
}
if (i != h->req_HostLen || atoi(port + 1) > 65535) {
DPRINTF(E_ERROR, L_HTTP, "DNS rebinding attack suspected (Host: %.*s)\n", h->req_HostLen, h->req_Host);
Send400(h);
return;
}
ptr++;
}
strncpyt(ip_buf, h->req_Host, MIN(ip_sz + 1, sizeof(ip_buf)));
if (ip_sz >= sizeof(ip_buf) || inet_pton(AF_INET, ip_buf, &addr) <= 0 || !addr.s_addr) {
DPRINTF(E_ERROR, L_HTTP, "DNS rebinding attack suspected (Host: %.*s)\n", h->req_HostLen, h->req_Host);
Send400(h);
return;
}
}
if(strcmp("POST", HttpCommand) == 0)

View File

@ -813,7 +813,7 @@ get_child_count(const char *object, struct magic_container_s *magic)
else if (magic && magic->objectid && *(magic->objectid))
ret = sql_get_int_field(db, "SELECT count(*) from OBJECTS where PARENT_ID = '%s';", *(magic->objectid));
else
ret = sql_get_int_field(db, "SELECT count(*) from OBJECTS where PARENT_ID = '%s';", object);
ret = sql_get_int_field(db, "SELECT count(*) from OBJECTS where PARENT_ID = '%q';", object);
return (ret > 0) ? ret : 0;
}
@ -836,6 +836,9 @@ object_exists(const char *object)
static int
callback(void *args, int argc, char **argv, char **azColName)
{
(void)args;
(void)argc;
(void)azColName;
struct Response *passed_args = (struct Response *)args;
char *id = argv[0], *parent = argv[1], *refID = argv[2], *detailID = argv[3], *class = argv[4], *size = argv[5], *title = argv[6],
*duration = argv[7], *bitrate = argv[8], *sampleFrequency = argv[9], *artist = argv[10], *album = argv[11],
@ -1295,6 +1298,7 @@ callback(void *args, int argc, char **argv, char **azColName)
static void
BrowseContentDirectory(struct upnphttp * h, const char * action)
{
(void)action;
static const char resp0[] =
"<u:BrowseResponse "
"xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">"
@ -1817,6 +1821,7 @@ parse_search_criteria(const char *str, char *sep)
static void
SearchContentDirectory(struct upnphttp * h, const char * action)
{
(void)action;
static const char resp0[] =
"<u:SearchResponse "
"xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">"
@ -2063,6 +2068,7 @@ static void _kodi_decode(char *str)
case '/':
if (!str[1])
*str = '\0';
/* fall through */
default:
str++;
break;
@ -2082,6 +2088,7 @@ static int duration_sec(const char *str)
static void UpdateObject(struct upnphttp * h, const char * action)
{
(void)action;
static const char resp[] =
"<u:UpdateObjectResponse"
" xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">"
@ -2166,6 +2173,7 @@ static void UpdateObject(struct upnphttp * h, const char * action)
static void
SamsungGetFeatureList(struct upnphttp * h, const char * action)
{
(void)action;
static const char resp[] =
"<u:X_GetFeatureListResponse xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">"
"<FeatureList>"
@ -2215,6 +2223,7 @@ SamsungGetFeatureList(struct upnphttp * h, const char * action)
static void
SamsungSetBookmark(struct upnphttp * h, const char * action)
{
(void)action;
static const char resp[] =
"<u:X_SetBookmarkResponse"
" xmlns:u=\"urn:schemas-upnp-org:service:ContentDirectory:1\">"