diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in
index f66d7bd64d..d323d58697 100644
--- a/build_tools/menuselect-deps.in
+++ b/build_tools/menuselect-deps.in
@@ -31,6 +31,7 @@ URIPARSER=@PBX_URIPARSER@
 KQUEUE=@PBX_KQUEUE@
 LDAP=@PBX_LDAP@
 LIBEDIT=@PBX_LIBEDIT@
+LIBJWT=@PBX_LIBJWT@
 LIBXML2=@PBX_LIBXML2@
 LIBXSLT=@PBX_LIBXSLT@
 XMLSTARLET=@PBX_XMLSTARLET@
diff --git a/configure b/configure
index 57deb2e81c..4d4083af6a 100755
--- a/configure
+++ b/configure
@@ -707,6 +707,8 @@ LIBOBJS
 PERMANENT_DLOPEN
 DISABLE_XMLDOC
 CONFIG_LIBXML2
+LIBJWT_LIBS
+LIBJWT_CFLAGS
 JANSSON_LIBS
 JANSSON_CFLAGS
 UUID_LIB
@@ -1063,6 +1065,7 @@ PBX_LIBXML2
 LIBXML2_DIR
 LIBXML2_INCLUDE
 LIBXML2_LIB
+LIBJWT_DIR
 PBX_LIBEDIT_IS_UNICODE
 LIBEDIT_IS_UNICODE_DIR
 LIBEDIT_IS_UNICODE_INCLUDE
@@ -1184,6 +1187,11 @@ PBX_ALSA
 ALSA_DIR
 ALSA_INCLUDE
 ALSA_LIB
+LIBJWT_INCLUDE
+LIBJWT_LIB
+PBX_LIBJWT
+LIBJWT_BUNDLED
+LIBJWT_CONFIGURE_OPTS
 PJPROJECT_INCLUDE
 PJPROJECT_LIB
 PBX_PJPROJECT
@@ -1350,7 +1358,6 @@ infodir
 docdir
 oldincludedir
 includedir
-runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -1382,6 +1389,7 @@ with_externals_cache
 enable_coverage
 with_jansson_bundled
 with_pjproject_bundled
+with_libjwt_bundled
 with_crypto
 with_ssl
 with_asound
@@ -1413,6 +1421,7 @@ with_kqueue
 with_ldap
 with_libcurl
 with_libedit
+with_libjwt
 with_libxml2
 with_libxslt
 with_lua
@@ -1485,11 +1494,14 @@ OPENSSL_CFLAGS
 OPENSSL_LIBS
 JANSSON_CONFIGURE_OPTS
 PJPROJECT_CONFIGURE_OPTS
+LIBJWT_CONFIGURE_OPTS
 LUA_VERSIONS
 LIBEDIT_CFLAGS
 LIBEDIT_LIBS
 JANSSON_CFLAGS
 JANSSON_LIBS
+LIBJWT_CFLAGS
+LIBJWT_LIBS
 ILBC_CFLAGS
 ILBC_LIBS
 NETSNMP_CFLAGS
@@ -1544,7 +1556,6 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1797,15 +1808,6 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
-  -runstatedir | --runstatedir | --runstatedi | --runstated \
-  | --runstate | --runstat | --runsta | --runst | --runs \
-  | --run | --ru | --r)
-    ac_prev=runstatedir ;;
-  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
-  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
-  | --run=* | --ru=* | --r=*)
-    runstatedir=$ac_optarg ;;
-
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1943,7 +1945,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir runstatedir
+		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -2096,7 +2098,6 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
-  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -2157,6 +2158,7 @@ Optional Packages:
   --with-jansson-bundled  Use bundled jansson library
   --with-pjproject-bundled
                           Use bundled pjproject libraries (default)
+  --with-libjwt-bundled   Use bundled libjwt library
   --with-crypto=PATH      use OpenSSL Cryptography files in PATH
   --with-ssl=PATH         use OpenSSL Secure Sockets Layer files in PATH
   --with-asound=PATH      use Advanced Linux Sound Architecture files in PATH
@@ -2191,6 +2193,7 @@ Optional Packages:
   --with-libcurl=PREFIX   look for the curl library in PREFIX/lib and headers
                           in PREFIX/include
   --with-libedit=PATH     use NetBSD Editline library files in PATH
+  --with-libjwt=PATH      use LIBJWT files in PATH
   --with-libxml2=PATH     use LibXML2 files in PATH
   --with-libxslt=PATH     use LibXSLT files in PATH
   --with-lua=PATH         use Lua files in PATH
@@ -2263,6 +2266,8 @@ Some influential environment variables:
               Additional configure options to pass to bundled jansson
   PJPROJECT_CONFIGURE_OPTS
               Additional configure options to pass to bundled pjproject
+  LIBJWT_CONFIGURE_OPTS
+              Additional configure options to pass to bundled libjwt
   LUA_VERSIONS
               A space separated list of target lua versions to test.
   LIBEDIT_CFLAGS
@@ -2273,6 +2278,9 @@ Some influential environment variables:
               C compiler flags for JANSSON, overriding pkg-config
   JANSSON_LIBS
               linker flags for JANSSON, overriding pkg-config
+  LIBJWT_CFLAGS
+              C compiler flags for LIBJWT, overriding pkg-config
+  LIBJWT_LIBS linker flags for LIBJWT, overriding pkg-config
   ILBC_CFLAGS C compiler flags for ILBC, overriding pkg-config
   ILBC_LIBS   linker flags for ILBC, overriding pkg-config
   NETSNMP_CFLAGS
@@ -9265,6 +9273,17 @@ if test "${with_pjproject}" = "no" || test "${with_pjproject}" = "n" ; then
 	PJPROJECT_BUNDLED=no
 fi
 
+LIBJWT_BUNDLED=no
+
+# Check whether --with-libjwt-bundled was given.
+if test "${with_libjwt_bundled+set}" = set; then :
+  withval=$with_libjwt_bundled; case "${withval}" in
+		y|ye|yes) LIBJWT_BUNDLED=yes ;;
+		*) LIBJWT_BUNDLED=no ;;
+	esac
+fi
+
+
 #
 # OpenSSL stuff has to be done here because we want to pass
 # any resulting CFLAGS and LDFLAGS to the bundled pjproject
@@ -10011,9 +10030,9 @@ $as_echo "$as_me: Unable to configure ${JANSSON_DIR}" >&6;}
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bundled jansson" >&5
 $as_echo_n "checking for bundled jansson... " >&6; }
 
-	JANSSON_INCLUDE=-I${JANSSON_DIR}/dest/include
+	JANSSON_INCLUDE=-I${JANSSON_DIR}/dist/usr/include
 	JANSSON_CFLAGS="$JANSSON_INCLUDE"
-	JANSSON_LIB="-L${JANSSON_DIR}/dest/lib -ljansson"
+	JANSSON_LIB="-L${JANSSON_DIR}/dist/usr/lib -ljansson"
 	PBX_JANSSON=1
 
 	# We haven't run install yet
@@ -10225,6 +10244,99 @@ $as_echo "yes" >&6; }
 	fi
 
 
+	if test "$LIBJWT_BUNDLED" = "yes" ; then
+
+	if test "${ac_mandatory_list#*LIBJWT*}" != "$ac_mandatory_list" ; then
+		as_fn_error $? "--with-libjwt and --with-libjwt-bundled can't both be specified" "$LINENO" 5
+	fi
+
+	ac_mandatory_list="$ac_mandatory_list LIBJWT"
+	LIBJWT_DIR="${ac_pwd}/third-party/libjwt"
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded libjwt (may have to download)" >&5
+$as_echo_n "checking for embedded libjwt (may have to download)... " >&6; }
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring" >&5
+$as_echo "configuring" >&6; }
+
+	if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then
+		as_fn_error $? "A download utility (wget, curl, or fetch) is required to download bundled libjwt" "$LINENO" 5
+	fi
+	if test "${GZIP}" = ":" ; then
+		as_fn_error $? "gzip is required to extract the libjwt tar file" "$LINENO" 5
+	fi
+	if test "${TAR}" = ":" ; then
+		as_fn_error $? "tar is required to extract the libjwt tar file" "$LINENO" 5
+	fi
+	if test "${PATCH}" = ":" ; then
+		as_fn_error $? "patch is required to configure bundled libjwt" "$LINENO" 5
+	fi
+	if test "${SED}" = ":" ; then
+		as_fn_error $? "sed is required to configure bundled libjwt" "$LINENO" 5
+	fi
+	if test "${NM}" = ":" ; then
+		as_fn_error $? "nm is required to build bundled libjwt" "$LINENO" 5
+	fi
+	if test "${MD5}" = ":" ; then
+		as_fn_error $? "md5sum is required to build bundled libjwt" "$LINENO" 5
+	fi
+	if test "${CAT}" = ":" ; then
+		as_fn_error $? "cat is required to build bundled libjwt" "$LINENO" 5
+	fi
+	if test "${CUT}" = ":" ; then
+		as_fn_error $? "cut is required to build bundled libjwt" "$LINENO" 5
+	fi
+	if test "${GREP}" = ":" ; then
+		as_fn_error $? "grep is required to build bundled libjwt" "$LINENO" 5
+	fi
+
+
+	this_host=$(./config.sub $(./config.guess))
+	if test "$build" != "$this_host" ; then
+		LIBJWT_CONFIGURE_OPTS+=" --build=$build_alias"
+	fi
+	if test "$host" != "$this_host" ; then
+		LIBJWT_CONFIGURE_OPTS+=" --host=$host_alias"
+	fi
+
+	export TAR PATCH SED NM EXTERNALS_CACHE_DIR AST_DOWNLOAD_CACHE DOWNLOAD_TO_STDOUT DOWNLOAD_TIMEOUT DOWNLOAD MD5 CAT CUT GREP
+	export NOISY_BUILD
+	export JANSSON_CFLAGS
+	export JANSSON_LIBS="${JANSSON_LIB}"
+	${GNU_MAKE} --quiet --no-print-directory -C ${LIBJWT_DIR} \
+		LIBJWT_CONFIGURE_OPTS="$LIBJWT_CONFIGURE_OPTS" \
+		EXTERNALS_CACHE_DIR="${EXTERNALS_CACHE_DIR:-${AST_DOWNLOAD_CACHE}}" \
+		configure
+	if test $? -ne 0 ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: Unable to configure ${LIBJWT_DIR}" >&5
+$as_echo "$as_me: Unable to configure ${LIBJWT_DIR}" >&6;}
+		as_fn_error $? "Re-run the ./configure command with 'NOISY_BUILD=yes' appended to see error details." "$LINENO" 5
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bundled libjwt" >&5
+$as_echo_n "checking for bundled libjwt... " >&6; }
+
+	LIBJWT_INCLUDE=-I${LIBJWT_DIR}/dist/usr/include
+	LIBJWT_CFLAGS="$LIBJWT_INCLUDE"
+	LIBJWT_LIB="-L${LIBJWT_DIR}/dist/usr/lib -ljwt"
+	PBX_LIBJWT=1
+
+	# We haven't run install yet
+
+
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_LIBJWT_BUNDLED 1" >>confdefs.h
+
+
+	fi
+
+
 
 # AST_EXT_LIB_SETUP is used to tell configure to handle variables for
 # various packages.
@@ -11547,6 +11659,38 @@ PBX_LIBEDIT_IS_UNICODE=0
 
 
 
+    LIBJWT_DESCRIP="LIBJWT"
+    LIBJWT_OPTION="libjwt"
+    PBX_LIBJWT=0
+
+# Check whether --with-libjwt was given.
+if test "${with_libjwt+set}" = set; then :
+  withval=$with_libjwt;
+	case ${withval} in
+	n|no)
+	USE_LIBJWT=no
+	# -1 is a magic value used by menuselect to know that the package
+	# was disabled, other than 'not found'
+	PBX_LIBJWT=-1
+	;;
+	y|ye|yes)
+	ac_mandatory_list="${ac_mandatory_list} LIBJWT"
+	;;
+	*)
+	LIBJWT_DIR="${withval}"
+	ac_mandatory_list="${ac_mandatory_list} LIBJWT"
+	;;
+	esac
+
+fi
+
+
+
+
+
+
+
+
     LIBXML2_DESCRIP="LibXML2"
     LIBXML2_OPTION="libxml2"
     PBX_LIBXML2=0
@@ -14711,6 +14855,101 @@ else
 	PBX_JANSSON=1
 fi
 
+source ./third-party/versions.mak
+# Find required JWT support if bundled is not enabled.
+if test "$LIBJWT_BUNDLED" = "no" ; then
+
+   if test "x${PBX_LIBJWT}" != "x1" -a "${USE_LIBJWT}" != "no"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBJWT" >&5
+$as_echo_n "checking for LIBJWT... " >&6; }
+
+if test -n "$LIBJWT_CFLAGS"; then
+    pkg_cv_LIBJWT_CFLAGS="$LIBJWT_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjwt >= \$LIBJWT_VERSION\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libjwt >= $LIBJWT_VERSION") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBJWT_CFLAGS=`$PKG_CONFIG --cflags "libjwt >= $LIBJWT_VERSION" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$LIBJWT_LIBS"; then
+    pkg_cv_LIBJWT_LIBS="$LIBJWT_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjwt >= \$LIBJWT_VERSION\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libjwt >= $LIBJWT_VERSION") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_LIBJWT_LIBS=`$PKG_CONFIG --libs "libjwt >= $LIBJWT_VERSION" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        LIBJWT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libjwt >= $LIBJWT_VERSION" 2>&1`
+        else
+	        LIBJWT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libjwt >= $LIBJWT_VERSION" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$LIBJWT_PKG_ERRORS" >&5
+
+
+            PBX_LIBJWT=0
+
+
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+            PBX_LIBJWT=0
+
+
+else
+	LIBJWT_CFLAGS=$pkg_cv_LIBJWT_CFLAGS
+	LIBJWT_LIBS=$pkg_cv_LIBJWT_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+            PBX_LIBJWT=1
+            LIBJWT_INCLUDE=$(echo ${LIBJWT_CFLAGS} | $SED -e "s|-std=c99||g")
+            LIBJWT_LIB="$LIBJWT_LIBS"
+
+$as_echo "#define HAVE_LIBJWT 1" >>confdefs.h
+
+
+fi
+   fi
+
+else
+	PBX_LIBJWT=1
+fi
+
 # See if clock_gettime is in librt
 
 if test "x${PBX_RT}" != "x1" -a "${USE_RT}" != "no"; then
@@ -15343,7 +15582,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15389,7 +15628,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15413,7 +15652,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15458,7 +15697,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15482,7 +15721,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -16782,8 +17021,6 @@ main ()
     if (*(data + i) != *(data3 + i))
       return 14;
   close (fd);
-  free (data);
-  free (data3);
   return 0;
 }
 _ACEOF
diff --git a/configure.ac b/configure.ac
index d12dad5d9f..694a8ff806 100644
--- a/configure.ac
+++ b/configure.ac
@@ -463,6 +463,15 @@ if test "${with_pjproject}" = "no" || test "${with_pjproject}" = "n" ; then
 	PJPROJECT_BUNDLED=no
 fi
 
+LIBJWT_BUNDLED=no
+AC_ARG_WITH([libjwt-bundled],
+	[AS_HELP_STRING([--with-libjwt-bundled],
+		[Use bundled libjwt library])],
+	[case "${withval}" in
+		y|ye|yes) LIBJWT_BUNDLED=yes ;;
+		*) LIBJWT_BUNDLED=no ;;
+	esac])
+
 #
 # OpenSSL stuff has to be done here because we want to pass
 # any resulting CFLAGS and LDFLAGS to the bundled pjproject
@@ -555,6 +564,7 @@ AST_EXT_LIB_SETUP([LDAP], [OpenLDAP], [ldap])
 AST_LIBCURL_CHECK_CONFIG([], [7.10.1])
 AST_EXT_LIB_SETUP([LIBEDIT], [NetBSD Editline library], [libedit])
 AST_EXT_LIB_SETUP_OPTIONAL([LIBEDIT_IS_UNICODE], [Libedit compiled for unicode], [LIBEDIT], [libedit])
+AST_EXT_LIB_SETUP([LIBJWT], [LIBJWT], [libjwt])
 AST_EXT_LIB_SETUP([LIBXML2], [LibXML2], [libxml2])
 AST_EXT_LIB_SETUP([LIBXSLT], [LibXSLT], [libxslt])
 AST_EXT_LIB_SETUP_OPTIONAL([LIBXSLT_CLEANUP], [LibXSLT Library Cleanup Function], [LIBXSLT], [libxslt])
@@ -741,6 +751,14 @@ else
 	PBX_JANSSON=1
 fi
 
+source ./third-party/versions.mak
+# Find required JWT support if bundled is not enabled.
+if test "$LIBJWT_BUNDLED" = "no" ; then
+	AST_PKG_CONFIG_CHECK([LIBJWT], [libjwt >= $LIBJWT_VERSION])
+else
+	PBX_LIBJWT=1
+fi
+
 # See if clock_gettime is in librt
 AST_EXT_LIB_CHECK([RT], [rt], [clock_gettime], [])
 
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index af6df9d070..bc8a567e94 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -434,6 +434,12 @@
 /* Define to 1 if you have the <libintl.h> header file. */
 #undef HAVE_LIBINTL_H
 
+/* Define if your system has the LIBJWT libraries. */
+#undef HAVE_LIBJWT
+
+/* Define if your system has LIBJWT_BUNDLED */
+#undef HAVE_LIBJWT_BUNDLED
+
 /* Define to 1 if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
diff --git a/makeopts.in b/makeopts.in
index 935876dbd8..a075e0cf84 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -188,6 +188,11 @@ JANSSON_BUNDLED=@JANSSON_BUNDLED@
 JANSSON_INCLUDE=@JANSSON_INCLUDE@
 JANSSON_LIB=@JANSSON_LIB@
 
+LIBJWT_BUNDLED=@LIBJWT_BUNDLED@
+LIBJWT_INCLUDE=@LIBJWT_INCLUDE@
+LIBJWT_LIB=@LIBJWT_LIB@
+LIBJWT_CONFIGURE_OPTS=@LIBJWT_CONFIGURE_OPTS@
+
 URIPARSER_INCLUDE=@URIPARSER_INCLUDE@
 URIPARSER_LIB=@URIPARSER_LIB@
 
diff --git a/third-party/Makefile b/third-party/Makefile
index 7b2afdac32..07e5a3de3d 100644
--- a/third-party/Makefile
+++ b/third-party/Makefile
@@ -1,20 +1,49 @@
 
+-include ../makeopts
 include Makefile.rules
 
-TP_SUBDIRS := pjproject jansson
+TP_ALL_SUBDIRS := jansson pjproject libjwt
+
+TP_SUBDIRS :=
 # Sub directories that contain special install/uninstall targets must be explicitly listed
 # to prevent accidentally running the package's default install target.
-TP_INSTALL_SUBDIRS := pjproject jansson
+TP_INSTALL_SUBDIRS :=
 
-.PHONY: all dist-clean distclean install clean moduleinfo makeopts uninstall $(TP_SUBDIRS)
+ifeq ($(PJPROJECT_BUNDLED),yes)
+TP_SUBDIRS += pjproject
+TP_INSTALL_SUBDIRS += pjproject
+endif
 
-override MAKECMDGOALS?=all
+ifeq ($(JANSSON_BUNDLED),yes)
+TP_SUBDIRS += jansson
+TP_INSTALL_SUBDIRS += jansson
+endif
 
+ifeq ($(LIBJWT_BUNDLED),yes)
+TP_SUBDIRS += libjwt
+TP_INSTALL_SUBDIRS += libjwt
+libjwt: jansson
+export JANSSON_CFLAGS=$(JANSSON_INCLUDE)
+export JANSSON_LIBS=$(JANSSON_LIB)
+endif
+
+override MAKECMDGOALS?=all
 MAKECMDGOALS:=$(subst dist-clean,distclean,$(MAKECMDGOALS))
-MAKECMDGOALS:=$(subst tpclean,clean,$(MAKECMDGOALS))
 
-all distclean dist-clean install uninstall tpclean : $(TP_SUBDIRS)
+.PHONY: all dist-clean distclean install clean moduleinfo makeopts uninstall $(TP_ALL_SUBDIRS)
+
+ifeq ($(findstring clean,$(MAKECMDGOALS)),clean)
+distclean dist-clean clean : $(TP_ALL_SUBDIRS)
+TP_RUN_SUBDIRS := $(TP_ALL_SUBDIRS)
+else
+all install uninstall : $(TP_SUBDIRS)
 install uninstall: $(TP_INSTALL_SUBDIRS)
+TP_RUN_SUBDIRS := $(TP_SUBDIRS)
+endif
+
+ifneq ($(TP_RUN_SUBDIRS),)
 
-$(TP_SUBDIRS):
+$(TP_RUN_SUBDIRS):
 	+$(CMD_PREFIX) $(SUBMAKE) -C $@ $(MAKECMDGOALS)
+
+endif
\ No newline at end of file
diff --git a/third-party/configure.m4 b/third-party/configure.m4
index fa4736d15b..0f36d7a816 100644
--- a/third-party/configure.m4
+++ b/third-party/configure.m4
@@ -7,4 +7,5 @@ AC_DEFUN([THIRD_PARTY_CONFIGURE],
 [
 	JANSSON_CONFIGURE()
 	PJPROJECT_CONFIGURE()
+	LIBJWT_CONFIGURE()
 ])
diff --git a/third-party/jansson/.gitignore b/third-party/jansson/.gitignore
index b7bfd2b878..f51f41a945 100644
--- a/third-party/jansson/.gitignore
+++ b/third-party/jansson/.gitignore
@@ -1,4 +1,4 @@
 source/
-dest/
+dist/
 **.bz2
 .rebuild_needed
diff --git a/third-party/jansson/Makefile b/third-party/jansson/Makefile
index 8c9da1a468..696be4ff95 100644
--- a/third-party/jansson/Makefile
+++ b/third-party/jansson/Makefile
@@ -39,7 +39,7 @@ ifeq ($(SPECIAL_TARGETS),)
             $(warning ASTTOPDIR/menuselect hasn't been run yet.  Can't find debug options.)
         endif
 
-        all: dest/include/jansson.h
+        all: dist/usr/lib/libjansson.a
     else
         all:
     endif
@@ -57,10 +57,10 @@ endif
 ECHO_PREFIX := $(ECHO_PREFIX) echo '[jansson] '
 SHELL_ECHO_PREFIX := echo '[jansson] '
 
-dest/include/jansson.h: source/config.status
+dist/usr/lib/libjansson.a: source/config.status
 	$(ECHO_PREFIX) Building bundled jansson.
 	$(CMD_PREFIX) (cd source; make $(REALLY_QUIET))
-	$(CMD_PREFIX) (cd source; make install DESTDIR= $(REALLY_QUIET))
+	$(CMD_PREFIX) (cd source; make install DESTDIR=$(JANSSON_DIR)/dist $(REALLY_QUIET))
 
 .DELETE_ON_ERROR:
 
@@ -87,7 +87,7 @@ source/.unpacked: $(DOWNLOAD_DIR)/$(TARBALL_FILE)
 source/config.status: source/.unpacked Makefile.rules .rebuild_needed
 	$(ECHO_PREFIX) Configuring
 	$(CMD_PREFIX) (cd source ; ./configure $(QUIET_CONFIGURE) $(JANSSON_CONFIG_OPTS) --disable-shared \
-		--enable-static --prefix=$(JANSSON_DIR)/dest --libdir=$(JANSSON_DIR)/dest/lib CFLAGS="$(OPTIMIZE_CFLAGS)")
+		--enable-static --prefix=/usr --libdir=/usr/lib CFLAGS="$(OPTIMIZE_CFLAGS) -fPIC")
 
 configure: source/config.status
 
@@ -96,8 +96,9 @@ uninstall:
 
 clean:
 	$(ECHO_PREFIX) Cleaning
-	+-$(CMD_PREFIX) test -d source dest && $(SUBMAKE) -C source clean || :
+	+-$(CMD_PREFIX) rm -rf dist
+	+-$(CMD_PREFIX) test -d source && $(SUBMAKE) -C source clean $(REALLY_QUIET) || :
 
 distclean:
 	$(ECHO_PREFIX) Distcleaning
-	-$(CMD_PREFIX) rm -rf source jansson-*.tar.bz2 .rebuild_needed
+	-$(CMD_PREFIX) rm -rf dist source jansson-*.tar.bz2 .rebuild_needed
diff --git a/third-party/jansson/configure.m4 b/third-party/jansson/configure.m4
index 4570de195a..147eb9fce0 100644
--- a/third-party/jansson/configure.m4
+++ b/third-party/jansson/configure.m4
@@ -69,9 +69,9 @@ AC_DEFUN([_JANSSON_CONFIGURE],
 
 	AC_MSG_CHECKING(for bundled jansson)
 
-	JANSSON_INCLUDE=-I${JANSSON_DIR}/dest/include
+	JANSSON_INCLUDE=-I${JANSSON_DIR}/dist/usr/include
 	JANSSON_CFLAGS="$JANSSON_INCLUDE"
-	JANSSON_LIB="-L${JANSSON_DIR}/dest/lib -ljansson"
+	JANSSON_LIB="-L${JANSSON_DIR}/dist/usr/lib -ljansson"
 	PBX_JANSSON=1
 
 	# We haven't run install yet
diff --git a/third-party/libjwt/.gitignore b/third-party/libjwt/.gitignore
new file mode 100644
index 0000000000..4347efe42d
--- /dev/null
+++ b/third-party/libjwt/.gitignore
@@ -0,0 +1,4 @@
+source/
+dist/
+**.gz
+.rebuild_needed
diff --git a/third-party/libjwt/Makefile b/third-party/libjwt/Makefile
new file mode 100644
index 0000000000..2c8fe406e2
--- /dev/null
+++ b/third-party/libjwt/Makefile
@@ -0,0 +1,124 @@
+.PHONY: all install clean distclean configure
+
+.NOTPARALLEL:
+
+include ../versions.mak
+export LIBJWT_DIR := $(shell pwd -P)
+JANSSON_DIR := $(shell realpath $(LIBJWT_DIR)/../jansson)
+
+SPECIAL_TARGETS :=
+
+ifneq ($(findstring configure,$(MAKECMDGOALS)),)
+# Run from $(ASTTOPDIR)/configure
+    SPECIAL_TARGETS += configure
+endif
+
+ifeq ($(findstring clean,$(MAKECMDGOALS)),clean)
+# clean or distclean
+    SPECIAL_TARGETS += clean
+endif
+
+ifeq ($(findstring uninstall,$(MAKECMDGOALS)),uninstall)
+    SPECIAL_TARGETS += uninstall
+endif
+
+
+ifneq ($(wildcard ../../makeopts),)
+    include ../../makeopts
+endif
+
+ifeq ($(SPECIAL_TARGETS),)
+# Run locally or from $(ASTTOPDIR)/Makefile.  All include files should be present
+    ifeq ($(wildcard ../../makeopts),)
+        $(error ASTTOPDIR/configure hasn't been run)
+    endif
+
+    ifeq ($(LIBJWT_BUNDLED),yes)
+        ifneq ($(wildcard ../../menuselect.makeopts),)
+            include ../../menuselect.makeopts
+        else
+            $(warning ASTTOPDIR/menuselect hasn't been run yet.  Can't find debug options.)
+        endif
+
+        all: dist/usr/lib/libjwt.a
+    else
+        all:
+    endif
+endif
+
+include ../../Makefile.rules
+include ../Makefile.rules
+include Makefile.rules
+
+OPTIMIZE_CFLAGS = -g3
+ifeq ($(findstring DONT_OPTIMIZE,$(MENUSELECT_CFLAGS)),)
+    OPTIMIZE_CFLAGS += $(OPTIMIZE)
+endif
+
+ECHO_PREFIX := $(ECHO_PREFIX) echo '[libjwt] '
+SHELL_ECHO_PREFIX := echo '[libjwt] '
+
+dist/usr/lib/libjwt.a: source/config.status
+	$(ECHO_PREFIX) Building bundled libjwt.
+	$(CMD_PREFIX) (cd source; make $(REALLY_QUIET))
+	$(CMD_PREFIX) (cd source; make install DESTDIR=$(LIBJWT_DIR)/dist $(REALLY_QUIET))
+ifeq ($(JANSSON_BUNDLED),yes)
+# Modules that need to use json manipulation functions will do
+# so through the ast_json wrappers which cause the main asterisk
+# executable to link to either the system implementation of jansson
+# or the bundled jansson.  libjwt also needs to call jansson functions
+# directly and if we're not using the bundled version of jansson,
+# this works fine bcause the dynamic linker can get the symbols
+# directly from the system-installed version of jansson when the
+# module using libjwt loads. If we're using bundled jansson however,
+# those symbols exist only in the main asterisk executable and a
+# library can't resolve against them. The result is that a module
+# making jwt_ calls will fail to load at runtime with unresolved
+# json_ symbols.  To address this, we create a combined library
+# containing both bundled libjwt and bundled jansson so a module
+# will have all symbols resolved correctly.
+	$(CMD_PREFIX) mv dist/usr/lib/libjwt.a dist/usr/lib/libjwt_orig.a
+	$(CMD_PREFIX) cd dist/usr/lib ; $(AR) -rcsT libjwt.a libjwt_orig.a \
+		$(JANSSON_DIR)/dist/usr/lib/libjansson.a
+endif
+
+.DELETE_ON_ERROR:
+
+$(DOWNLOAD_DIR)/$(TARBALL_FILE): ../versions.mak
+	$(CMD_PREFIX) ($(TARBALL_EXISTS) && $(TARBALL_VERIFY) && touch $@) || (rm -rf $@ ;\
+	$(TARBALL_DOWNLOAD)) || (rm -rf $@ ;\
+	$(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD))
+
+source/.unpacked: $(DOWNLOAD_DIR)/$(TARBALL_FILE)
+	$(CMD_PREFIX) $(TARBALL_VERIFY) || (rm -rf $@ ;\
+	$(SHELL_ECHO_PREFIX) Retrying download ; $(TARBALL_DOWNLOAD))
+	$(ECHO_PREFIX) Unpacking $<
+	-@rm -rf source libjwt-*/ >/dev/null 2>&1
+	$(CMD_PREFIX) $(TAR) -xf $<
+	@mv libjwt-$(LIBJWT_VERSION) source
+	$(ECHO_PREFIX) Applying patches "$(realpath patches)" "$(realpath .)/source"
+	$(CMD_PREFIX) ../apply_patches $(QUIET_CONFIGURE) "$(realpath patches)" "$(realpath .)/source"
+	-@touch source/.unpacked
+
+.rebuild_needed: $(wildcard ../../.lastclean)
+	$(ECHO_PREFIX) Rebuilding
+	$(CMD_PREFIX) $(MAKE) clean $(REALLY_QUIET)
+
+source/config.status: source/.unpacked Makefile.rules .rebuild_needed
+	$(ECHO_PREFIX) Configuring
+	$(CMD_PREFIX) (cd source ; ./configure $(QUIET_CONFIGURE) $(LIBJWT_CONFIG_OPTS) --disable-shared \
+		--enable-static --prefix=/usr --libdir=/usr/lib CFLAGS="$(OPTIMIZE_CFLAGS) -fPIC")
+
+configure: source/config.status
+
+install:
+uninstall:
+
+clean:
+	$(ECHO_PREFIX) Cleaning
+	+-$(CMD_PREFIX) rm -rf dist
+	+-$(CMD_PREFIX) test -d source && $(SUBMAKE) -C source clean $(REALLY_QUIET) || :
+
+distclean:
+	$(ECHO_PREFIX) Distcleaning
+	-$(CMD_PREFIX) rm -rf dist source libjwt-*.tar.gz .rebuild_needed
diff --git a/third-party/libjwt/Makefile.rules b/third-party/libjwt/Makefile.rules
new file mode 100644
index 0000000000..5b9b8f811b
--- /dev/null
+++ b/third-party/libjwt/Makefile.rules
@@ -0,0 +1,9 @@
+
+PACKAGE_URL ?= https://raw.githubusercontent.com/asterisk/third-party/master/libjwt/$(LIBJWT_VERSION)
+TARBALL_FILE = libjwt-$(LIBJWT_VERSION).tar.gz
+
+# LIBJWT_CONFIGURE_OPTS could come from the command line or could be
+# set/modified by configure.m4 if the build or host tuples aren't the same
+# as the current build environment (cross-compile).
+
+LIBJWT_CONFIG_OPTS = --disable-doxygen-doc --disable-doxygen-dot --without-examples $(LIBJWT_CONFIGURE_OPTS)
diff --git a/third-party/libjwt/configure.m4 b/third-party/libjwt/configure.m4
new file mode 100644
index 0000000000..c9f1aa407b
--- /dev/null
+++ b/third-party/libjwt/configure.m4
@@ -0,0 +1,95 @@
+#
+# If this file is changed, be sure to run ASTTOPDIR/bootstrap.sh
+# before committing.
+#
+
+AC_DEFUN([_LIBJWT_CONFIGURE],
+[
+	if test "${ac_mandatory_list#*LIBJWT*}" != "$ac_mandatory_list" ; then
+		AC_MSG_ERROR(--with-libjwt and --with-libjwt-bundled can't both be specified)
+	fi
+
+	ac_mandatory_list="$ac_mandatory_list LIBJWT"
+	LIBJWT_DIR="${ac_pwd}/third-party/libjwt"
+
+	AC_MSG_CHECKING(for embedded libjwt (may have to download))
+	AC_MSG_RESULT(configuring)
+
+	if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then
+		AC_MSG_ERROR(A download utility (wget, curl, or fetch) is required to download bundled libjwt)
+	fi
+	if test "${GZIP}" = ":" ; then
+		AC_MSG_ERROR(gzip is required to extract the libjwt tar file)
+	fi
+	if test "${TAR}" = ":" ; then
+		AC_MSG_ERROR(tar is required to extract the libjwt tar file)
+	fi
+	if test "${PATCH}" = ":" ; then
+		AC_MSG_ERROR(patch is required to configure bundled libjwt)
+	fi
+	if test "${SED}" = ":" ; then
+		AC_MSG_ERROR(sed is required to configure bundled libjwt)
+	fi
+	if test "${NM}" = ":" ; then
+		AC_MSG_ERROR(nm is required to build bundled libjwt)
+	fi
+	if test "${MD5}" = ":" ; then
+		AC_MSG_ERROR(md5sum is required to build bundled libjwt)
+	fi
+	if test "${CAT}" = ":" ; then
+		AC_MSG_ERROR(cat is required to build bundled libjwt)
+	fi
+	if test "${CUT}" = ":" ; then
+		AC_MSG_ERROR(cut is required to build bundled libjwt)
+	fi
+	if test "${GREP}" = ":" ; then
+		AC_MSG_ERROR(grep is required to build bundled libjwt)
+	fi
+
+	AC_ARG_VAR([LIBJWT_CONFIGURE_OPTS],[Additional configure options to pass to bundled libjwt])
+	this_host=$(./config.sub $(./config.guess))
+	if test "$build" != "$this_host" ; then
+		LIBJWT_CONFIGURE_OPTS+=" --build=$build_alias"
+	fi
+	if test "$host" != "$this_host" ; then
+		LIBJWT_CONFIGURE_OPTS+=" --host=$host_alias"
+	fi
+
+	export TAR PATCH SED NM EXTERNALS_CACHE_DIR AST_DOWNLOAD_CACHE DOWNLOAD_TO_STDOUT DOWNLOAD_TIMEOUT DOWNLOAD MD5 CAT CUT GREP
+	export NOISY_BUILD
+	export JANSSON_CFLAGS
+	export JANSSON_LIBS="${JANSSON_LIB}"
+	${GNU_MAKE} --quiet --no-print-directory -C ${LIBJWT_DIR} \
+		LIBJWT_CONFIGURE_OPTS="$LIBJWT_CONFIGURE_OPTS" \
+		EXTERNALS_CACHE_DIR="${EXTERNALS_CACHE_DIR:-${AST_DOWNLOAD_CACHE}}" \
+		configure
+	if test $? -ne 0 ; then
+		AC_MSG_RESULT(failed)
+		AC_MSG_NOTICE(Unable to configure ${LIBJWT_DIR})
+		AC_MSG_ERROR(Re-run the ./configure command with 'NOISY_BUILD=yes' appended to see error details.)
+	fi
+
+	AC_MSG_CHECKING(for bundled libjwt)
+
+	LIBJWT_INCLUDE=-I${LIBJWT_DIR}/dist/usr/include
+	LIBJWT_CFLAGS="$LIBJWT_INCLUDE"
+	LIBJWT_LIB="-L${LIBJWT_DIR}/dist/usr/lib -ljwt"
+	PBX_LIBJWT=1
+
+	# We haven't run install yet
+
+	AC_SUBST([LIBJWT_BUNDLED])
+	AC_SUBST([PBX_LIBJWT])
+	AC_SUBST([LIBJWT_LIB])
+	AC_SUBST([LIBJWT_INCLUDE])
+	AC_MSG_RESULT(yes)
+	AC_DEFINE([HAVE_LIBJWT_BUNDLED], 1, [Define if your system has LIBJWT_BUNDLED])
+])
+
+AC_DEFUN([LIBJWT_CONFIGURE],
+[
+	if test "$LIBJWT_BUNDLED" = "yes" ; then
+		_LIBJWT_CONFIGURE()
+	fi
+])
+
diff --git a/third-party/libjwt/libjwt-1.15.3.tar.gz.md5 b/third-party/libjwt/libjwt-1.15.3.tar.gz.md5
new file mode 100644
index 0000000000..e66f329f27
--- /dev/null
+++ b/third-party/libjwt/libjwt-1.15.3.tar.gz.md5
@@ -0,0 +1 @@
+f417ef3fe6ee14c0befd86e6836dc4c9  libjwt-1.15.3.tar.gz
diff --git a/third-party/libjwt/patches/README b/third-party/libjwt/patches/README
new file mode 100644
index 0000000000..7765b632a8
--- /dev/null
+++ b/third-party/libjwt/patches/README
@@ -0,0 +1,4 @@
+Patches should be added here once merged to the upstream libjwt project at
+https://github.com/benmcollins/libjwt.  Patch filenames should be generated by
+running 'git format-patch ...' from the libjwt repository, then
+copying the required patches to this folder.
diff --git a/third-party/versions.mak b/third-party/versions.mak
index fae41c6fd4..81b2050dbf 100644
--- a/third-party/versions.mak
+++ b/third-party/versions.mak
@@ -1,2 +1,6 @@
-JANSSON_VERSION = 2.12
-PJPROJECT_VERSION = 2.10
+# This file is also 'sourced' by the
+# configure script so it must follow 'shell'
+# syntax as well as 'make' syntax.
+JANSSON_VERSION=2.12
+PJPROJECT_VERSION=2.10
+LIBJWT_VERSION=1.15.3