From patchwork Tue Sep 1 06:10:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabrice Fontaine X-Patchwork-Id: 1354750 Return-Path: X-Original-To: incoming-buildroot@patchwork.ozlabs.org Delivered-To: patchwork-incoming-buildroot@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=busybox.net (client-ip=140.211.166.136; helo=silver.osuosl.org; envelope-from=buildroot-bounces@busybox.net; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=UIxyUQU6; dkim-atps=neutral Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BgcDJ1jtyz9sTN for ; Tue, 1 Sep 2020 16:12:16 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 7D2D922CCE; Tue, 1 Sep 2020 06:12:14 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tjPb7Rgb5-re; Tue, 1 Sep 2020 06:11:41 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by silver.osuosl.org (Postfix) with ESMTP id A185422DEC; Tue, 1 Sep 2020 06:10:56 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by ash.osuosl.org (Postfix) with ESMTP id 00BC11BF39F for ; Tue, 1 Sep 2020 06:10:55 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 48D8622E6E for ; Tue, 1 Sep 2020 06:10:54 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VGKOIvYj4ZO0 for ; Tue, 1 Sep 2020 06:10:42 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) by silver.osuosl.org (Postfix) with ESMTPS id 25BCF2036C for ; Tue, 1 Sep 2020 06:10:42 +0000 (UTC) Received: by mail-wm1-f41.google.com with SMTP id e11so210458wme.0 for ; Mon, 31 Aug 2020 23:10:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=c3PndcgCLl+WPcGCg2SmWpSfWoMEc7T4NJj76BRBE3M=; b=UIxyUQU6Ib3t5yv4E4a17a1glorXIRoVMhqSJXX92kFPOuZlgsSWpMGeUTPvU/qePZ ZVcZ+VBZ488M6JXPZreIVuDZeHuQ83G/Xj8TYiwqyjEWYWMc261CBGAs1/y2+kRjFgob U6Pmftmr2ljfNwNPzortH/aHTamAR7xhz6i/f2+dqSNhqvY4mhN0Bn790YFFDCLxUl8R QrGwvx11PvnUOMSeUNVTCialqS4qYCDKWxQ76aen/nMkjG/Rsgl36+hqijBUcuqJD+02 7NS/HIYf59fEGMdAdCgHB+EBz4H8uUN1hY8Fvr8Kkz588GnkHr7fariQNBjy2ThBj3ay cnKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=c3PndcgCLl+WPcGCg2SmWpSfWoMEc7T4NJj76BRBE3M=; b=SmDzMgt1CD7eW/BVF8mychfsSBx+l/3BZeVc7LHplrbMKR1YL4v/hA90SqFLcWyfzT NTK+J3a7dIqcO1f01VuVXr5uXNrfqRRHpkHclWv1G5MKs5VgfOMZ4mkwJv1+TFe4lKF8 QiOM+sHnvOKdumkPp/Hzgw5p6dGzC7r4YE0ILwxCg0nH+5plqkpR+YiRk1AAuOEgI5nw cDBYNrnQDgIxRfm8gJvA7JCQvpvvkW4hjTMldwYwDAgcEJ1yQo2wSXDjzCNL1/Fx6TU2 qDjrew/twRnWeBMtIaHxGbL6pBTneFYNVQGmQURo0aTo6VdP/em1b3c9eU433lPRjmPc yZKw== X-Gm-Message-State: AOAM533priZHO/U92aZg05Z68WuYwYROuEmu2w77ygnE1x84gUKrQ2SI zsRR31a76FPtPvAJjlNY7uSwXiWlJSI= X-Google-Smtp-Source: ABdhPJxdVvK6G7SWs9YJDdwTyt5KfduPk95oqLLHhem1khqwmBJBdHhGeSppKP9gSUY3W8PcMCzxuw== X-Received: by 2002:a1c:4e01:: with SMTP id g1mr145905wmh.112.1598940639970; Mon, 31 Aug 2020 23:10:39 -0700 (PDT) Received: from kali.home (2a01cb0881b76d00c2afd0dfa851d2b9.ipv6.abo.wanadoo.fr. [2a01:cb08:81b7:6d00:c2af:d0df:a851:d2b9]) by smtp.gmail.com with ESMTPSA id v7sm969907wma.1.2020.08.31.23.10.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2020 23:10:39 -0700 (PDT) From: Fabrice Fontaine To: buildroot@buildroot.org Date: Tue, 1 Sep 2020 08:10:26 +0200 Message-Id: <20200901061027.2294973-5-fontaine.fabrice@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200901061027.2294973-1-fontaine.fabrice@gmail.com> References: <20200901061027.2294973-1-fontaine.fabrice@gmail.com> MIME-Version: 1.0 Subject: [Buildroot] [PATCH/next v2, 5/6] package/ushare: add libupnp 1.14.x support X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bernd Kuhls , Hiroshi Kawashima , Simon Dawson , Fabrice Fontaine Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" This switch is needed to fix CallStranger a.k.a. CVE-2020-12695 Signed-off-by: Fabrice Fontaine --- .../0004-switch-to-libupnp-1.14.x-API.patch | 433 ++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 package/ushare/0004-switch-to-libupnp-1.14.x-API.patch diff --git a/package/ushare/0004-switch-to-libupnp-1.14.x-API.patch b/package/ushare/0004-switch-to-libupnp-1.14.x-API.patch new file mode 100644 index 0000000000..e200bb1926 --- /dev/null +++ b/package/ushare/0004-switch-to-libupnp-1.14.x-API.patch @@ -0,0 +1,433 @@ +From 4643b9cb9e6c0331fd663437a7ed8061b9edf971 Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Mon, 24 Aug 2020 19:26:03 +0200 +Subject: [PATCH] switch to libupnp 1.14.x API + +Use the new libupnp 1.14.x API (i.e. UpnpInit2) to allow ushare to be +protected against CallStranger a.k.a. CVE-2020-12695 + +Signed-off-by: Fabrice Fontaine +[Retrieved from: +https://github.com/ddugovic/uShare/commit/4643b9cb9e6c0331fd663437a7ed8061b9edf971] +--- + configure | 2 -- + src/http.c | 50 +++++++++++++++++++++++++++++++------------------- + src/http.h | 24 ++++++++++++++++++------ + src/services.c | 28 ++++++++++++++++++---------- + src/services.h | 6 +++--- + src/ushare.c | 36 ++++++++++++++++++------------------ + src/ushare.h | 2 +- + 7 files changed, 89 insertions(+), 59 deletions(-) + +diff --git a/configure b/configure +index 20a08ed..4a3efe0 100755 +--- a/configure ++++ b/configure +@@ -638,8 +638,6 @@ fi + echolog "Checking for libixml ..." + check_lib upnp/ixml.h ixmlRelaxParser -lixml || die "Error, can't find libixml !" + +-echolog "Checking for libthreadutil ..." +-check_lib upnp/ThreadPool.h ThreadPoolAdd "-lthreadutil -lpthread" || die "Error, can't find libthreadutil !" + add_extralibs -lpthread + + libupnp_min_version="1.4.2" +diff --git a/src/http.c b/src/http.c +index 8a4e67d..1e5b350 100644 +--- a/src/http.c ++++ b/src/http.c +@@ -68,17 +68,19 @@ struct web_file_t { + + + static inline void +-set_info_file (struct File_Info *info, const size_t length, ++set_info_file (UpnpFileInfo *info, const size_t length, + const char *content_type) + { +- info->file_length = length; +- info->last_modified = 0; +- info->is_directory = 0; +- info->is_readable = 1; +- info->content_type = ixmlCloneDOMString (content_type); ++ UpnpFileInfo_set_FileLength(info, length); ++ UpnpFileInfo_set_LastModified(info, 0); ++ UpnpFileInfo_set_IsDirectory(info, 0); ++ UpnpFileInfo_set_IsReadable(info, 1); ++ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString (content_type)); + } + +-int http_get_info (const char *filename, struct File_Info *info) ++int http_get_info (const char *filename, UpnpFileInfo *info, ++ const void* cookie __attribute__((unused)), ++ const void** requestCookie __attribute__((unused))) + { + extern struct ushare_t *ut; + struct upnp_entry_t *entry = NULL; +@@ -143,15 +145,15 @@ int http_get_info (const char *filename, struct File_Info *info) + { + if (errno != EACCES) + return -1; +- info->is_readable = 0; ++ UpnpFileInfo_set_IsReadable(info, 0); + } + else +- info->is_readable = 1; ++ UpnpFileInfo_set_IsReadable(info, 1); + + /* file exist and can be read */ +- info->file_length = st.st_size; +- info->last_modified = st.st_mtime; +- info->is_directory = S_ISDIR (st.st_mode); ++ UpnpFileInfo_set_FileLength(info, st.st_size); ++ UpnpFileInfo_set_LastModified(info, st.st_mtime); ++ UpnpFileInfo_set_IsDirectory(info, S_ISDIR (st.st_mode)); + + protocol = + #ifdef HAVE_DLNA +@@ -172,11 +174,11 @@ int http_get_info (const char *filename, struct File_Info *info) + + if (content_type) + { +- info->content_type = ixmlCloneDOMString (content_type); ++ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString (content_type)); + free (content_type); + } + else +- info->content_type = ixmlCloneDOMString (""); ++ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString ("")); + + return 0; + } +@@ -197,7 +199,9 @@ get_file_memory (const char *fullpath, const char *description, + return ((UpnpWebFileHandle) file); + } + +-UpnpWebFileHandle http_open (const char *filename, enum UpnpOpenFileMode mode) ++UpnpWebFileHandle http_open (const char *filename, enum UpnpOpenFileMode mode, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))) + { + extern struct ushare_t *ut; + struct upnp_entry_t *entry = NULL; +@@ -250,7 +254,9 @@ UpnpWebFileHandle http_open (const char *filename, enum UpnpOpenFileMode mode) + return ((UpnpWebFileHandle) file); + } + +-int http_read (UpnpWebFileHandle fh, char *buf, size_t buflen) ++int http_read (UpnpWebFileHandle fh, char *buf, size_t buflen, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))) + { + struct web_file_t *file = (struct web_file_t *) fh; + ssize_t len = -1; +@@ -285,14 +291,18 @@ int http_read (UpnpWebFileHandle fh, char *buf, size_t buflen) + + int http_write (UpnpWebFileHandle fh __attribute__((unused)), + char *buf __attribute__((unused)), +- size_t buflen __attribute__((unused))) ++ size_t buflen __attribute__((unused)), ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))) + { + log_verbose ("http write\n"); + + return 0; + } + +-int http_seek (UpnpWebFileHandle fh, off_t offset, int origin) ++int http_seek (UpnpWebFileHandle fh, off_t offset, int origin, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))) + { + struct web_file_t *file = (struct web_file_t *) fh; + off_t newpos = -1; +@@ -366,7 +376,9 @@ int http_seek (UpnpWebFileHandle fh, off_t offset, int origin) + return 0; + } + +-int http_close (UpnpWebFileHandle fh) ++int http_close (UpnpWebFileHandle fh, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))) + { + struct web_file_t *file = (struct web_file_t *) fh; + +diff --git a/src/http.h b/src/http.h +index 32d6bcc..c912a7b 100644 +--- a/src/http.h ++++ b/src/http.h +@@ -25,18 +25,30 @@ + #include + #include + +-int http_get_info (const char *filename, struct File_Info *info); ++int http_get_info (const char *filename, UpnpFileInfo *info, ++ const void* cookie __attribute__((unused)), ++ const void** requestCookie __attribute__((unused))); + +-UpnpWebFileHandle http_open (const char *filename, enum UpnpOpenFileMode mode); ++UpnpWebFileHandle http_open (const char *filename, enum UpnpOpenFileMode mode, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))); + +-int http_read (UpnpWebFileHandle fh, char *buf, size_t buflen); ++int http_read (UpnpWebFileHandle fh, char *buf, size_t buflen, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))); + +-int http_seek (UpnpWebFileHandle fh, off_t offset, int origin); ++int http_seek (UpnpWebFileHandle fh, off_t offset, int origin, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))); + + int http_write (UpnpWebFileHandle fh __attribute__((unused)), + char *buf __attribute__((unused)), +- size_t buflen __attribute__((unused))); ++ size_t buflen __attribute__((unused)), ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))); + +-int http_close (UpnpWebFileHandle fh); ++int http_close (UpnpWebFileHandle fh, ++ const void* cookie __attribute__((unused)), ++ const void* requestCookie __attribute__((unused))); + + #endif /* _HTTP_H_ */ +diff --git a/src/services.c b/src/services.c +index aec9cf8..287df55 100644 +--- a/src/services.c ++++ b/src/services.c +@@ -62,25 +62,28 @@ static struct service_t services[] = { + }; + + bool +-find_service_action (struct Upnp_Action_Request *request, ++find_service_action (UpnpActionRequest *request, + struct service_t **service, + struct service_action_t **action) + { + int c, d; ++ const char *actionName = NULL; + + *service = NULL; + *action = NULL; ++ ++ actionName = UpnpActionRequest_get_ActionName_cstr(request); + +- if (!request || !request->ActionName) ++ if (!request || !actionName) + return false; + + for (c = 0; services[c].id != NULL; c++) +- if (!strcmp (services[c].id, request->ServiceID)) ++ if (!strcmp (services[c].id, UpnpActionRequest_get_ServiceID_cstr(request))) + { + *service = &services[c]; + for (d = 0; services[c].actions[d].name; d++) + { +- if (!strcmp (services[c].actions[d].name, request->ActionName)) ++ if (!strcmp (services[c].actions[d].name, actionName)) + { + *action = &services[c].actions[d]; + return true; +@@ -97,6 +100,7 @@ upnp_add_response (struct action_event_t *event, char *key, const char *value) + { + char *val; + int res; ++ IXML_Document* actionResult = NULL; + + if (!event || !event->status || !key || !value) + return false; +@@ -105,8 +109,9 @@ upnp_add_response (struct action_event_t *event, char *key, const char *value) + if (!val) + return false; + +- res = UpnpAddToActionResponse (&event->request->ActionResult, +- event->request->ActionName, ++ actionResult = UpnpActionRequest_get_ActionResult(event->request); ++ res = UpnpAddToActionResponse (&actionResult, ++ UpnpActionRequest_get_ActionName_cstr(event->request), + event->service->type, key, val); + + if (res != UPNP_E_SUCCESS) +@@ -120,14 +125,17 @@ upnp_add_response (struct action_event_t *event, char *key, const char *value) + } + + char * +-upnp_get_string (struct Upnp_Action_Request *request, const char *key) ++upnp_get_string (UpnpActionRequest *request, const char *key) + { + IXML_Node *node = NULL; ++ IXML_Document *actionRequest = NULL; + +- if (!request || !request->ActionRequest || !key) ++ actionRequest = UpnpActionRequest_get_ActionRequest(request); ++ ++ if (!request || !actionRequest || !key) + return NULL; + +- node = (IXML_Node *) request->ActionRequest; ++ node = (IXML_Node *) actionRequest; + if (!node) + { + log_verbose ("Invalid action request document\n"); +@@ -157,7 +165,7 @@ upnp_get_string (struct Upnp_Action_Request *request, const char *key) + } + + int +-upnp_get_ui4 (struct Upnp_Action_Request *request, const char *key) ++upnp_get_ui4 (UpnpActionRequest *request, const char *key) + { + char *value; + int val; +diff --git a/src/services.h b/src/services.h +index 89c072e..d5726b4 100644 +--- a/src/services.h ++++ b/src/services.h +@@ -39,15 +39,15 @@ struct service_t { + + #define SERVICE_CONTENT_TYPE "text/xml" + +-bool find_service_action (struct Upnp_Action_Request *request, ++bool find_service_action (UpnpActionRequest *request, + struct service_t **service, + struct service_action_t **action); + + bool upnp_add_response (struct action_event_t *event, + char *key, const char *value); + +-char * upnp_get_string (struct Upnp_Action_Request *request, const char *key); ++char * upnp_get_string (UpnpActionRequest *request, const char *key); + +-int upnp_get_ui4 (struct Upnp_Action_Request *request, const char *key); ++int upnp_get_ui4 (UpnpActionRequest *request, const char *key); + + #endif /* _SERVICES_H_ */ +diff --git a/src/ushare.c b/src/ushare.c +index 28fd67e..92e2345 100644 +--- a/src/ushare.c ++++ b/src/ushare.c +@@ -177,7 +177,7 @@ ushare_signal_exit (void) + } + + static void +-handle_action_request (struct Upnp_Action_Request *request) ++handle_action_request (UpnpActionRequest *request) + { + struct service_t *service; + struct service_action_t *action; +@@ -187,25 +187,25 @@ handle_action_request (struct Upnp_Action_Request *request) + if (!request || !ut) + return; + +- if (request->ErrCode != UPNP_E_SUCCESS) ++ if (UpnpActionRequest_get_ErrCode(request) != UPNP_E_SUCCESS) + return; + +- if (strcmp (request->DevUDN + 5, ut->udn)) ++ if (strcmp (UpnpActionRequest_get_DevUDN_cstr(request) + 5, ut->udn)) + return; + +- ip = (*(struct sockaddr_in *)&request->CtrlPtIPAddr).sin_addr.s_addr; ++ ip = (*(struct sockaddr_in *)UpnpActionRequest_get_CtrlPtIPAddr(request)).sin_addr.s_addr; + ip = ntohl (ip); + sprintf (val, "%d.%d.%d.%d", + (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); + + if (ut->verbose) + { +- DOMString str = ixmlPrintDocument (request->ActionRequest); ++ DOMString str = ixmlPrintDocument (UpnpActionRequest_get_ActionRequest(request)); + log_verbose ("***************************************************\n"); + log_verbose ("** New Action Request **\n"); + log_verbose ("***************************************************\n"); +- log_verbose ("ServiceID: %s\n", request->ServiceID); +- log_verbose ("ActionName: %s\n", request->ActionName); ++ log_verbose ("ServiceID: %s\n", UpnpActionRequest_get_ServiceID_cstr(request)); ++ log_verbose ("ActionName: %s\n", UpnpActionRequest_get_ActionName_cstr(request)); + log_verbose ("CtrlPtIP: %s\n", val); + log_verbose ("Action Request:\n%s\n", str); + ixmlFreeDOMString (str); +@@ -220,11 +220,11 @@ handle_action_request (struct Upnp_Action_Request *request) + event.service = service; + + if (action->function (&event) && event.status) +- request->ErrCode = UPNP_E_SUCCESS; ++ UpnpActionRequest_set_ErrCode(request, UPNP_E_SUCCESS); + + if (ut->verbose) + { +- DOMString str = ixmlPrintDocument (request->ActionResult); ++ DOMString str = ixmlPrintDocument (UpnpActionRequest_get_ActionResult(request)); + log_verbose ("Action Result:\n%s", str); + log_verbose ("***************************************************\n"); + log_verbose ("\n"); +@@ -235,22 +235,22 @@ handle_action_request (struct Upnp_Action_Request *request) + } + + if (service) /* Invalid Action name */ +- strcpy (request->ErrStr, "Unknown Service Action"); ++ UpnpActionRequest_strcpy_ErrStr(request, "Unknown Service Action"); + else /* Invalid Service name */ +- strcpy (request->ErrStr, "Unknown Service ID"); ++ UpnpActionRequest_strcpy_ErrStr(request, "Unknown Service ID"); + +- request->ActionResult = NULL; +- request->ErrCode = UPNP_SOAP_E_INVALID_ACTION; ++ UpnpActionRequest_set_ActionResult(request, NULL); ++ UpnpActionRequest_set_ErrCode(request, UPNP_SOAP_E_INVALID_ACTION); + } + + static int +-device_callback_event_handler (Upnp_EventType type, void *event, ++device_callback_event_handler (Upnp_EventType type, const void *event, + void *cookie __attribute__((unused))) + { + switch (type) + { + case UPNP_CONTROL_ACTION_REQUEST: +- handle_action_request ((struct Upnp_Action_Request *) event); ++ handle_action_request ((UpnpActionRequest *) event); + break; + case UPNP_CONTROL_ACTION_COMPLETE: + case UPNP_EVENT_SUBSCRIPTION_REQUEST: +@@ -323,7 +323,7 @@ init_upnp (struct ushare_t *ut) + #endif /* HAVE_DLNA */ + + log_info (_("Initializing UPnP subsystem ...\n")); +- res = UpnpInit (ut->ip, ut->port); ++ res = UpnpInit2 (ut->interface, ut->port); + if (res != UPNP_E_SUCCESS) + { + log_error (_("Cannot initialize UPnP subsystem\n")); +@@ -351,7 +351,7 @@ init_upnp (struct ushare_t *ut) + log_info (_("UPnP MediaServer listening on %s:%d\n"), + UpnpGetServerIpAddress (), ut->port); + +- UpnpEnableWebserver (TRUE); ++ UpnpEnableWebserver (1); + + #define upnp_set_callback(cb, func) \ + do { \ +@@ -371,7 +371,7 @@ init_upnp (struct ushare_t *ut) + upnp_set_callback(Write, http_write); + upnp_set_callback(Close, http_close); + +- res = UpnpAddVirtualDir (VIRTUAL_DIR); ++ res = UpnpAddVirtualDir (VIRTUAL_DIR, NULL, NULL); + if (res != UPNP_E_SUCCESS) + { + log_error (_("Cannot add virtual directory for web server\n")); +diff --git a/src/ushare.h b/src/ushare.h +index a29da01..cd86cef 100644 +--- a/src/ushare.h ++++ b/src/ushare.h +@@ -125,7 +125,7 @@ struct ushare_t { + }; + + struct action_event_t { +- struct Upnp_Action_Request *request; ++ UpnpActionRequest *request; + bool status; + struct service_t *service; + };