Commit 0246a16beb for freeswitch.com

commit 0246a16beb416aaaa59edbaf131d80c9d7989aea
Author: Dmitry Verenitsin <morbit85@gmail.com>
Date:   Sat Aug 8 23:05:01 2026 +0500

    Merge commit from fork

    `http_directory_auth()` builds the expected "user@domain:password"
    token into `z[256]` and base64-encodes it to compare against the
    client's Authorization header. Encode with `switch_b64_encode`, which
    stops at its output-length argument and always NUL-terminates, and
    size `t` from `sizeof(z)`: base64 emits 4 output bytes per 3 input
    bytes (final partial group rounded up) plus a NUL, so
    `4 * ((sizeof(z) + 2) / 3) + 1` holds the encoding of any `z`. The
    encode is confined to `t`, matching the `switch_b64_decode` already
    used for the inbound header.

    Also in the same function:
    - Drop the now-unused `#include <xmlrpc-c/base64_int.h>`, an xmlrpc-c
      internal header that only declared the removed encoder.
    - Compare 4 bytes, not 3, when stripping a leading `www.` from the
      virtual-host `Host:` name. A 3-byte compare also matches hosts like
      `www2.example.com` and then strips 4 bytes, yielding `.example.com`
      and a failed directory lookup; for a bare `www` it advanced one
      byte past the terminating NUL.

diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
index 0a4e5e1e44..2552d73b91 100644
--- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
+++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
@@ -65,7 +65,6 @@
 #include <xmlrpc-c/abyss.h>
 #include <xmlrpc-c/server.h>
 #include <xmlrpc-c/server_abyss.h>
-#include <xmlrpc-c/base64_int.h>
 #include <../lib/abyss/src/token.h>
 #include <../lib/abyss/src/http.h>
 #include <../lib/abyss/src/session.h>
@@ -397,7 +396,9 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 {
 	char *p = NULL;
 	char *x = NULL;
-	char z[256] = "", t[80] = "";
+	char z[256] = "";
+	/* base64: 4 output bytes per 3 input, rounded up, plus a NUL */
+	char t[4 * ((sizeof(z) + 2) / 3) + 1] = "";
 	char user[512] = "" ;
 	char *pass = NULL;
 	const char *mypass1 = NULL, *mypass2 = NULL;
@@ -429,7 +430,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 				if (!domain_name) {
 					if (globals.virtual_host) {
 						if ((domain_name = (char *) r->requestInfo.host)) {
-							if (!strncasecmp(domain_name, "www.", 3)) {
+							if (!strncasecmp(domain_name, "www.", 4)) {
 								domain_name += 4;
 							}
 						}
@@ -455,7 +456,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 					} else {
 						switch_snprintf(z, sizeof(z), "%s:%s", globals.user, globals.pass);
 					}
-					xmlrpc_base64Encode(z, t);
+					switch_b64_encode((unsigned char *)z, strlen(z), (unsigned char *)t, sizeof(t));

 					if (!strcmp(p, t)) {
 						goto authed;
@@ -479,7 +480,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 					} else {
 						switch_snprintf(z, sizeof(z), "%s:%s", user, mypass1);
 					}
-					xmlrpc_base64Encode(z, t);
+					switch_b64_encode((unsigned char *)z, strlen(z), (unsigned char *)t, sizeof(t));

 					if (!strcmp(p, t)) {
 						goto authed;
@@ -491,7 +492,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 						} else {
 							switch_snprintf(z, sizeof(z), "%s:%s", user, mypass2);
 						}
-						xmlrpc_base64Encode(z, t);
+						switch_b64_encode((unsigned char *)z, strlen(z), (unsigned char *)t, sizeof(t));

 						if (!strcmp(p, t)) {
 							goto authed;
@@ -504,7 +505,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 						} else {
 							switch_snprintf(z, sizeof(z), "%s:%s", box, mypass1);
 						}
-						xmlrpc_base64Encode(z, t);
+						switch_b64_encode((unsigned char *)z, strlen(z), (unsigned char *)t, sizeof(t));

 						if (!strcmp(p, t)) {
 							goto authed;
@@ -517,7 +518,7 @@ static abyss_bool http_directory_auth(TSession *r, char *domain_name)
 								switch_snprintf(z, sizeof(z), "%s:%s", box, mypass2);
 							}

-							xmlrpc_base64Encode(z, t);
+							switch_b64_encode((unsigned char *)z, strlen(z), (unsigned char *)t, sizeof(t));

 							if (!strcmp(p, t)) {
 								goto authed;