Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Acme.Sh
Commits
c74686a1
Unverified
Commit
c74686a1
authored
Jun 03, 2019
by
neil
Committed by
GitHub
Jun 03, 2019
Browse files
Merge pull request #2285 from dkerr64/FreeDNS
Fixes to dns_freedns.sh for multi-part top level domain names
parents
3508e1e6
924e0261
Changes
1
Hide whitespace changes
Inline
Side-by-side
dnsapi/dns_freedns.sh
View file @
c74686a1
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#
#
#Author: David Kerr
#Author: David Kerr
#Report Bugs here: https://github.com/dkerr64/acme.sh
#Report Bugs here: https://github.com/dkerr64/acme.sh
#or here... https://github.com/Neilpang/acme.sh/issues/2305
#
#
######## Public functions #####################
######## Public functions #####################
...
@@ -46,76 +47,34 @@ dns_freedns_add() {
...
@@ -46,76 +47,34 @@ dns_freedns_add() {
_saveaccountconf FREEDNS_COOKIE
"
$FREEDNS_COOKIE
"
_saveaccountconf FREEDNS_COOKIE
"
$FREEDNS_COOKIE
"
# split our full domain name into two parts...
# We may have to cycle through the domain name to find the
i
=
"
$(
echo
"
$fulldomain
"
|
tr
'.'
' '
|
wc
-w
)
"
# TLD that we own...
i
=
"
$(
_math
"
$i
"
- 1
)
"
i
=
1
top_domain
=
"
$(
echo
"
$fulldomain
"
|
cut
-d
.
-f
"
$i
"
-100
)
"
wmax
=
"
$(
echo
"
$fulldomain
"
|
tr
'.'
' '
|
wc
-w
)
"
i
=
"
$(
_math
"
$i
"
- 1
)
"
while
[
"
$i
"
-lt
"
$wmax
"
]
;
do
sub_domain
=
"
$(
echo
"
$fulldomain
"
|
cut
-d
.
-f
-
"
$i
"
)
"
# split our full domain name into two parts...
sub_domain
=
"
$(
echo
"
$fulldomain
"
|
cut
-d
.
-f
-
"
$i
"
)
"
_debug
"top_domain:
$top_domain
"
i
=
"
$(
_math
"
$i
"
+ 1
)
"
_debug
"sub_domain:
$sub_domain
"
top_domain
=
"
$(
echo
"
$fulldomain
"
|
cut
-d
.
-f
"
$i
"
-100
)
"
_debug
"sub_domain:
$sub_domain
"
# Sometimes FreeDNS does not return the subdomain page but rather
_debug
"top_domain:
$top_domain
"
# returns a page regarding becoming a premium member. This usually
# happens after a period of inactivity. Immediately trying again
DNSdomainid
=
"
$(
_freedns_domain_id
"
$top_domain
"
)
"
# returns the correct subdomain page. So, we will try twice to
if
[
"
$?
"
=
"0"
]
;
then
# load the page and obtain our domain ID
_info
"Domain
$top_domain
found at FreeDNS, domain_id
$DNSdomainid
"
attempts
=
2
while
[
"
$attempts
"
-gt
"0"
]
;
do
attempts
=
"
$(
_math
"
$attempts
"
- 1
)
"
htmlpage
=
"
$(
_freedns_retrieve_subdomain_page
"
$FREEDNS_COOKIE
"
)
"
if
[
"
$?
"
!=
"0"
]
;
then
if
[
"
$using_cached_cookies
"
=
"true"
]
;
then
_err
"Has your FreeDNS username and password changed? If so..."
_err
"Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return
1
fi
subdomain_csv
=
"
$(
echo
"
$htmlpage
"
|
tr
-d
"
\n\r
"
| _egrep_o
'<form .*</form>'
|
sed
's/<tr>/@<tr>/g'
|
tr
'@'
'\n'
|
grep
edit.php |
grep
"
$top_domain
"
)
"
_debug3
"subdomain_csv:
$subdomain_csv
"
# The above beauty ends with striping out rows that do not have an
# href to edit.php and do not have the top domain we are looking for.
# So all we should be left with is CSV of table of subdomains we are
# interested in.
# Now we have to read through this table and extract the data we need
lines
=
"
$(
echo
"
$subdomain_csv
"
|
wc
-l
)
"
i
=
0
found
=
0
DNSdomainid
=
""
while
[
"
$i
"
-lt
"
$lines
"
]
;
do
i
=
"
$(
_math
"
$i
"
+ 1
)
"
line
=
"
$(
echo
"
$subdomain_csv
"
|
sed
-n
"
${
i
}
p"
)
"
_debug2
"line:
$line
"
if
[
$found
=
0
]
&&
_contains
"
$line
"
"<td>
$top_domain
</td>"
;
then
# this line will contain DNSdomainid for the top_domain
DNSdomainid
=
"
$(
echo
"
$line
"
| _egrep_o
"edit_domain_id *= *.*>"
|
cut
-d
=
-f
2 |
cut
-d
'>'
-f
1
)
"
_debug2
"DNSdomainid:
$DNSdomainid
"
found
=
1
break
fi
done
if
[
-z
"
$DNSdomainid
"
]
;
then
# If domain ID is empty then something went wrong (top level
# domain not found at FreeDNS).
if
[
"
$attempts
"
=
"0"
]
;
then
# exhausted maximum retry attempts
_err
"Domain
$top_domain
not found at FreeDNS"
return
1
fi
else
# break out of the 'retry' loop... we have found our domain ID
break
break
else
_info
"Domain
$top_domain
not found at FreeDNS, try with next level of TLD"
fi
fi
_info
"Domain
$top_domain
not found at FreeDNS"
_info
"Retry loading subdomain page (
$attempts
attempts remaining)"
done
done
if
[
-z
"
$DNSdomainid
"
]
;
then
# If domain ID is empty then something went wrong (top level
# domain not found at FreeDNS).
_err
"Domain
$top_domain
not found at FreeDNS"
return
1
fi
# Add in new TXT record with the value provided
# Add in new TXT record with the value provided
_debug
"Adding TXT record for
$fulldomain
,
$txtvalue
"
_debug
"Adding TXT record for
$fulldomain
,
$txtvalue
"
_freedns_add_txt_record
"
$FREEDNS_COOKIE
"
"
$DNSdomainid
"
"
$sub_domain
"
"
$txtvalue
"
_freedns_add_txt_record
"
$FREEDNS_COOKIE
"
"
$DNSdomainid
"
"
$sub_domain
"
"
$txtvalue
"
...
@@ -134,80 +93,47 @@ dns_freedns_rm() {
...
@@ -134,80 +93,47 @@ dns_freedns_rm() {
# Need to read cookie from conf file again in case new value set
# Need to read cookie from conf file again in case new value set
# during login to FreeDNS when TXT record was created.
# during login to FreeDNS when TXT record was created.
# acme.sh does not have a _readaccountconf() function
FREEDNS_COOKIE
=
"
$(
_readaccountconf
"FREEDNS_COOKIE"
)
"
FREEDNS_COOKIE
=
"
$(
_read_conf
"
$ACCOUNT_CONF_PATH
"
"FREEDNS_COOKIE"
)
"
_debug
"FreeDNS login cookies:
$FREEDNS_COOKIE
"
_debug
"FreeDNS login cookies:
$FREEDNS_COOKIE
"
# Sometimes FreeDNS does not return the subdomain page but rather
TXTdataid
=
"
$(
_freedns_data_id
"
$fulldomain
"
"TXT"
)
"
# returns a page regarding becoming a premium member. This usually
if
[
"
$?
"
!=
"0"
]
;
then
# happens after a period of inactivity. Immediately trying again
_info
"Cannot delete TXT record for
$fulldomain
, record does not exist at FreeDNS"
# returns the correct subdomain page. So, we will try twice to
return
1
# load the page and obtain our TXT record.
fi
attempts
=
2
_debug
"Data ID's found,
$TXTdataid
"
while
[
"
$attempts
"
-gt
"0"
]
;
do
attempts
=
"
$(
_math
"
$attempts
"
- 1
)
"
# now we have one (or more) TXT record data ID's. Load the page
# for that record and search for the record txt value. If match
htmlpage
=
"
$(
_freedns_retrieve_subdomain_page
"
$FREEDNS_COOKIE
"
)
"
# then we can delete it.
lines
=
"
$(
echo
"
$TXTdataid
"
|
wc
-l
)
"
_debug
"Found
$lines
TXT data records for
$fulldomain
"
i
=
0
while
[
"
$i
"
-lt
"
$lines
"
]
;
do
i
=
"
$(
_math
"
$i
"
+ 1
)
"
dataid
=
"
$(
echo
"
$TXTdataid
"
|
sed
-n
"
${
i
}
p"
)
"
_debug
"
$dataid
"
htmlpage
=
"
$(
_freedns_retrieve_data_page
"
$FREEDNS_COOKIE
"
"
$dataid
"
)
"
if
[
"
$?
"
!=
"0"
]
;
then
if
[
"
$?
"
!=
"0"
]
;
then
if
[
"
$using_cached_cookies
"
=
"true"
]
;
then
_err
"Has your FreeDNS username and password changed? If so..."
_err
"Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return
1
return
1
fi
fi
subdomain_csv
=
"
$(
echo
"
$htmlpage
"
|
tr
-d
"
\n\r
"
| _egrep_o
'<form .*</form>'
|
sed
's/<tr>/@<tr>/g'
|
tr
'@'
'\n'
|
grep
edit.php |
grep
"
$fulldomain
"
)
"
echo
"
$htmlpage
"
|
grep
"value=
\"
"
$txtvalue
"
\"
"
>
/dev/null
_debug3
"subdomain_csv:
$subdomain_csv
"
if
[
"
$?
"
=
"0"
]
;
then
# Found a match... delete the record and return
# The above beauty ends with striping out rows that do not have an
_info
"Deleting TXT record for
$fulldomain
,
$txtvalue
"
# href to edit.php and do not have the domain name we are looking for.
_freedns_delete_txt_record
"
$FREEDNS_COOKIE
"
"
$dataid
"
# So all we should be left with is CSV of table of subdomains we are
return
$?
# interested in.
fi
# Now we have to read through this table and extract the data we need
lines
=
"
$(
echo
"
$subdomain_csv
"
|
wc
-l
)
"
i
=
0
found
=
0
DNSdataid
=
""
while
[
"
$i
"
-lt
"
$lines
"
]
;
do
i
=
"
$(
_math
"
$i
"
+ 1
)
"
line
=
"
$(
echo
"
$subdomain_csv
"
|
sed
-n
"
${
i
}
p"
)
"
_debug3
"line:
$line
"
DNSname
=
"
$(
echo
"
$line
"
| _egrep_o
'edit.php.*</a>'
|
cut
-d
'>'
-f
2 |
cut
-d
'<'
-f
1
)
"
_debug2
"DNSname:
$DNSname
"
if
[
"
$DNSname
"
=
"
$fulldomain
"
]
;
then
DNStype
=
"
$(
echo
"
$line
"
|
sed
's/<td/@<td/g'
|
tr
'@'
'\n'
|
sed
-n
'4p'
|
cut
-d
'>'
-f
2 |
cut
-d
'<'
-f
1
)
"
_debug2
"DNStype:
$DNStype
"
if
[
"
$DNStype
"
=
"TXT"
]
;
then
DNSdataid
=
"
$(
echo
"
$line
"
| _egrep_o
'data_id=.*'
|
cut
-d
=
-f
2 |
cut
-d
'>'
-f
1
)
"
_debug2
"DNSdataid:
$DNSdataid
"
DNSvalue
=
"
$(
echo
"
$line
"
|
sed
's/<td/@<td/g'
|
tr
'@'
'\n'
|
sed
-n
'5p'
|
cut
-d
'>'
-f
2 |
cut
-d
'<'
-f
1
)
"
if
_startswith
"
$DNSvalue
"
"""
;
then
# remove the quotation from the start
DNSvalue
=
"
$(
echo
"
$DNSvalue
"
|
cut
-c
7-
)
"
fi
if
_endswith
"
$DNSvalue
"
"..."
;
then
# value was truncated, remove the dot dot dot from the end
DNSvalue
=
"
$(
echo
"
$DNSvalue
"
|
sed
's/...$//'
)
"
elif
_endswith
"
$DNSvalue
"
"""
;
then
# else remove the closing quotation from the end
DNSvalue
=
"
$(
echo
"
$DNSvalue
"
|
sed
's/......$//'
)
"
fi
_debug2
"DNSvalue:
$DNSvalue
"
if
[
-n
"
$DNSdataid
"
]
&&
_startswith
"
$txtvalue
"
"
$DNSvalue
"
;
then
# Found a match. But note... Website is truncating the
# value field so we are only testing that part that is not
# truncated. This should be accurate enough.
_debug
"Deleting TXT record for
$fulldomain
,
$txtvalue
"
_freedns_delete_txt_record
"
$FREEDNS_COOKIE
"
"
$DNSdataid
"
return
$?
fi
fi
fi
done
done
done
# If we get this far we did not find a match
(after two attempts)
# If we get this far we did not find a match
# Not necessarily an error, but log anyway.
# Not necessarily an error, but log anyway.
_debug3
"
$subdomain_csv
"
_info
"Cannot delete TXT record for
$fulldomain
,
$txtvalue
. Does not exist at FreeDNS"
_info
"Cannot delete TXT record for
$fulldomain
,
$txtvalue
. Does not exist at FreeDNS"
return
0
return
0
}
}
...
@@ -271,6 +197,33 @@ _freedns_retrieve_subdomain_page() {
...
@@ -271,6 +197,33 @@ _freedns_retrieve_subdomain_page() {
return
0
return
0
}
}
# usage _freedns_retrieve_data_page login_cookies data_id
# echo page retrieved (html)
# returns 0 success
_freedns_retrieve_data_page
()
{
export
_H1
=
"Cookie:
$1
"
export
_H2
=
"Accept-Language:en-US"
data_id
=
"
$2
"
url
=
"https://freedns.afraid.org/subdomain/edit.php?data_id=
$2
"
_debug
"Retrieve data page for ID
$data_id
from FreeDNS"
htmlpage
=
"
$(
_get
"
$url
"
)
"
if
[
"
$?
"
!=
"0"
]
;
then
_err
"FreeDNS retrieve data page failed bad RC from _get"
return
1
elif
[
-z
"
$htmlpage
"
]
;
then
_err
"FreeDNS returned empty data page"
return
1
fi
_debug3
"htmlpage:
$htmlpage
"
printf
"%s"
"
$htmlpage
"
return
0
}
# usage _freedns_add_txt_record login_cookies domain_id subdomain value
# usage _freedns_add_txt_record login_cookies domain_id subdomain value
# returns 0 success
# returns 0 success
_freedns_add_txt_record
()
{
_freedns_add_txt_record
()
{
...
@@ -324,3 +277,95 @@ _freedns_delete_txt_record() {
...
@@ -324,3 +277,95 @@ _freedns_delete_txt_record() {
_info
"Deleted acme challenge TXT record for
$fulldomain
at FreeDNS"
_info
"Deleted acme challenge TXT record for
$fulldomain
at FreeDNS"
return
0
return
0
}
}
# usage _freedns_domain_id domain_name
# echo the domain_id if found
# return 0 success
_freedns_domain_id
()
{
# Start by escaping the dots in the domain name
search_domain
=
"
$(
echo
"
$1
"
|
sed
's/\./\\./g'
)
"
# Sometimes FreeDNS does not return the subdomain page but rather
# returns a page regarding becoming a premium member. This usually
# happens after a period of inactivity. Immediately trying again
# returns the correct subdomain page. So, we will try twice to
# load the page and obtain our domain ID
attempts
=
2
while
[
"
$attempts
"
-gt
"0"
]
;
do
attempts
=
"
$(
_math
"
$attempts
"
- 1
)
"
htmlpage
=
"
$(
_freedns_retrieve_subdomain_page
"
$FREEDNS_COOKIE
"
)
"
if
[
"
$?
"
!=
"0"
]
;
then
if
[
"
$using_cached_cookies
"
=
"true"
]
;
then
_err
"Has your FreeDNS username and password changed? If so..."
_err
"Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return
1
fi
domain_id
=
"
$(
echo
"
$htmlpage
"
|
tr
-d
"[:space:]"
|
sed
's/<tr>/@<tr>/g'
|
tr
'@'
'\n'
\
|
grep
"<td>
$search_domain
</td>
\|
<td>
$search_domain
(.*)</td>"
\
| _egrep_o
"edit
\.
php
\?
edit_domain_id=[0-9a-zA-Z]+"
\
|
cut
-d
=
-f
2
)
"
# The above beauty extracts domain ID from the html page...
# strip out all blank space and new lines. Then insert newlines
# before each table row <tr>
# search for the domain within each row (which may or may not have
# a text string in brackets (.*) after it.
# And finally extract the domain ID.
if
[
-n
"
$domain_id
"
]
;
then
printf
"%s"
"
$domain_id
"
return
0
fi
_debug
"Domain
$search_domain
not found. Retry loading subdomain page (
$attempts
attempts remaining)"
done
_debug
"Domain
$search_domain
not found after retry"
return
1
}
# usage _freedns_data_id domain_name record_type
# echo the data_id(s) if found
# return 0 success
_freedns_data_id
()
{
# Start by escaping the dots in the domain name
search_domain
=
"
$(
echo
"
$1
"
|
sed
's/\./\\./g'
)
"
record_type
=
"
$2
"
# Sometimes FreeDNS does not return the subdomain page but rather
# returns a page regarding becoming a premium member. This usually
# happens after a period of inactivity. Immediately trying again
# returns the correct subdomain page. So, we will try twice to
# load the page and obtain our domain ID
attempts
=
2
while
[
"
$attempts
"
-gt
"0"
]
;
do
attempts
=
"
$(
_math
"
$attempts
"
- 1
)
"
htmlpage
=
"
$(
_freedns_retrieve_subdomain_page
"
$FREEDNS_COOKIE
"
)
"
if
[
"
$?
"
!=
"0"
]
;
then
if
[
"
$using_cached_cookies
"
=
"true"
]
;
then
_err
"Has your FreeDNS username and password changed? If so..."
_err
"Please export as FREEDNS_User / FREEDNS_Password and try again."
fi
return
1
fi
data_id
=
"
$(
echo
"
$htmlpage
"
|
tr
-d
"[:space:]"
|
sed
's/<tr>/@<tr>/g'
|
tr
'@'
'\n'
\
|
grep
"<td[a-zA-Z=#]*>
$record_type
</td>"
\
|
grep
"<ahref.*>
$search_domain
</a>"
\
| _egrep_o
"edit
\.
php
\?
data_id=[0-9a-zA-Z]+"
\
|
cut
-d
=
-f
2
)
"
# The above beauty extracts data ID from the html page...
# strip out all blank space and new lines. Then insert newlines
# before each table row <tr>
# search for the record type withing each row (e.g. TXT)
# search for the domain within each row (which is within a <a..>
# </a> anchor. And finally extract the domain ID.
if
[
-n
"
$data_id
"
]
;
then
printf
"%s"
"
$data_id
"
return
0
fi
_debug
"Domain
$search_domain
not found. Retry loading subdomain page (
$attempts
attempts remaining)"
done
_debug
"Domain
$search_domain
not found after retry"
return
1
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment