srvrco / getssl

obtain free SSL certificates from letsencrypt ACME server Suitable for automating the process on remote servers.
GNU General Public License v3.0
2.07k stars 372 forks source link

date_epoc fails to convert date from cyrilic #818

Open mslavkov opened 8 months ago

mslavkov commented 8 months ago

Describe the bug When locale is set to Bulgarian (bg_BG.UTF-8) date is unable to convert the string to check the certificate validity. ... local cert is for domains: www.example.tld Failed conversion of Feb 5 05:16:58 2024 GMT'' using format%b %d %T %Y %Z'' date: illegal time format usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format]

www.example.tld: certificate needs renewal ...

After adding LC_ALL=C in front of date in date_epoc function:

... local cert is valid until Feb 5 05:25:12 2024 GMT

local cert is for domains: www.example.tld www.example.tld: certificate is valid for more than 30 days (until Feb 5 05:25:12 2024 GMT) ...

To Reproduce On bsd system set locale to Bulgarian (bg_BG.UTF-8) and try to renew cert.

Expected behavior local cert is valid until Feb 5 05:25:12 2024 GMT

local cert is for domains: www.example.tld www.example.tld: certificate is valid for more than 30 days (until Feb 5 05:25:12 2024 GMT)

Operating system (please complete the following information):

Additional context Add any other context about the problem here.

mslavkov commented 8 months ago
diff --git a/getssl b/getssl
index 30d8837..607044c 100755
--- a/getssl
+++ b/getssl
@@ -1256,14 +1256,14 @@ create_order() {

 date_epoc() { # convert the date into epoch time
   if [[ "$os" == "bsd" ]]; then
-    date -j -f "%b %d %T %Y %Z" "$1" +%s
+    LC_ALL=C date -j -f "%b %d %T %Y %Z" "$1" +%s
   elif [[ "$os" == "mac" ]]; then
-    date -j -f "%b %d %T %Y %Z" "$1" +%s
+    LC_ALL=C date -j -f "%b %d %T %Y %Z" "$1" +%s
   elif [[ "$os" == "busybox" ]]; then
     de_ld=$(echo "$1" | awk '{print $1 " " $2 " " $3 " " $4}')
-    date -D "%b %d %T %Y" -d "$de_ld" +%s
+    LC_ALL=C date -D "%b %d %T %Y" -d "$de_ld" +%s
   else
-    date -d "$1" +%s
+    LC_ALL=C date -d "$1" +%s
   fi

 }

This is how I got it to work on my FreeBSD machine.

timkimber commented 7 months ago

Hi @mslavkov

Thanks for this, and especially thanks for posting a fix. I'll add some tests and merge that in.

Note: I currently have very little time to work on getssl due to work commitments

tlhackque commented 4 months ago

There are probably other dependencies on locale. This may be the tip of an iceberg.

Might be safer to save locale at startup and set (and export) LC_ALL="C" globally. If there are any cases where the current locale is needed, special case them. Will probably get in trouble either way, but system tools like getssl tend to be happier in the C locale. "It's not fair, but it's history."

tlhackque commented 3 months ago

Actually, getssl does `export LANG=C. I even was the one who did it (for another reason) in this commit.

So you must have LC_TIME set in your environment.

I've switchedtoLC_ALL` in my current PR (#841), which should solve this and any cousin bugs.