Skip to content

Commit b4b586f

Browse files
Gustedearl-warren
authored andcommitted
[PRIVACY] Add a DNS method to fetch new updates
- Use TXT records in order to determine the latest available version. - This addresses a valid privacy issue, as with HTTP requests the server can keep track(estimated) of how many instances are using Forgejo, with DNS that's basically not possible as the server will never receive any data, as the only ones receiving data are DNS resolvers. (cherry picked from commit 0baefb546ab96bc3c06d90feffdb14873c2c2a3a) (cherry picked from commit e8ee41880b775532e6a68bd2052ed96d369dee78) (cherry picked from commit 7eca4f3bf1faa3f063c9668d1bb354b842361007) (cherry picked from commit 5c1567836c39b08b982005048f2610c3ad6d029a) (cherry picked from commit 953afbc67f85f7c15a064405f83b9973273d4d7b) (cherry picked from commit fd9d97ab9f304f0acea977130c74c63024c40182) (cherry picked from commit 40fbd45effed8e37c0d23dec4896473a437fb7eb) (cherry picked from commit c5c904b04ba8ddbab108c9fb2559109c1cef1166) (cherry picked from commit 48659bb3ab268203f14d8d7e6f2f0de4ce1eaa23) (cherry picked from commit b1fccd50938a0e63a8a80d127c6c81a78d31215a) (cherry picked from commit 5e69573)
1 parent 8a745dd commit b4b586f

File tree

5 files changed

+76
-10
lines changed

5 files changed

+76
-10
lines changed

custom/conf/app.example.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,6 +2212,7 @@ ROUTER = console
22122212
;ENABLE_SUCCESS_NOTICE = false
22132213
;SCHEDULE = @every 168h
22142214
;HTTP_ENDPOINT = https://dl.gitea.io/gitea/version.json
2215+
;DOMAIN_ENDPOINT = release.forgejo.org
22152216

22162217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22172218
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

docs/content/doc/administration/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ Default templates for project boards:
10501050
- `ENABLE_SUCCESS_NOTICE`: **true**: Set to false to switch off success notices.
10511051
- `SCHEDULE`: **@every 168h**: Cron syntax for scheduling a work, e.g. `@every 168h`.
10521052
- `HTTP_ENDPOINT`: **https://dl.gitea.io/gitea/version.json**: the endpoint that Gitea will check for newer versions
1053+
- `DOMAIN_ENDPOINT`: **release.forgejo.org**: the domain that, if specified, Gitea will check for newer versions. This is preferred over `HTTP_ENDPOINT`.
10531054

10541055
#### Cron - Delete all old system notices from database (`cron.delete_old_system_notices`)
10551056

modules/updatechecker/update_checker.go

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
package updatechecker
55

66
import (
7+
"errors"
78
"io"
9+
"net"
810
"net/http"
11+
"strings"
912

1013
"code.gitea.io/gitea/modules/json"
1114
"code.gitea.io/gitea/modules/proxy"
@@ -26,7 +29,51 @@ func (r *CheckerState) Name() string {
2629
}
2730

2831
// GiteaUpdateChecker returns error when new version of Gitea is available
29-
func GiteaUpdateChecker(httpEndpoint string) error {
32+
func GiteaUpdateChecker(httpEndpoint, domainEndpoint string) error {
33+
var version string
34+
var err error
35+
if domainEndpoint != "" {
36+
version, err = getVersionDNS(domainEndpoint)
37+
} else {
38+
version, err = getVersionHTTP(httpEndpoint)
39+
}
40+
41+
if err != nil {
42+
return err
43+
}
44+
45+
return UpdateRemoteVersion(version)
46+
}
47+
48+
// getVersionDNS will request the TXT records for the domain. If a record starts
49+
// with "forgejo_versions=" everything after that will be used as the latest
50+
// version available.
51+
func getVersionDNS(domainEndpoint string) (version string, err error) {
52+
records, err := net.LookupTXT(domainEndpoint)
53+
if err != nil {
54+
return "", err
55+
}
56+
57+
if len(records) == 0 {
58+
return "", errors.New("no TXT records were found")
59+
}
60+
61+
for _, record := range records {
62+
if strings.HasPrefix(record, "forgejo_versions=") {
63+
// Get all supported versions, separated by a comma.
64+
supportedVersions := strings.Split(strings.TrimPrefix(record, "forgejo_versions="), ",")
65+
// For now always return the latest supported version.
66+
return supportedVersions[len(supportedVersions)-1], nil
67+
}
68+
}
69+
70+
return "", errors.New("there is no TXT record with a valid value")
71+
}
72+
73+
// getVersionHTTP will make an HTTP request to the endpoint, and the returned
74+
// content is JSON. The "latest.version" path's value will be used as the latest
75+
// version available.
76+
func getVersionHTTP(httpEndpoint string) (version string, err error) {
3077
httpClient := &http.Client{
3178
Transport: &http.Transport{
3279
Proxy: proxy.Proxy(),
@@ -35,16 +82,16 @@ func GiteaUpdateChecker(httpEndpoint string) error {
3582

3683
req, err := http.NewRequest("GET", httpEndpoint, nil)
3784
if err != nil {
38-
return err
85+
return "", err
3986
}
4087
resp, err := httpClient.Do(req)
4188
if err != nil {
42-
return err
89+
return "", err
4390
}
4491
defer resp.Body.Close()
4592
body, err := io.ReadAll(resp.Body)
4693
if err != nil {
47-
return err
94+
return "", err
4895
}
4996

5097
type respType struct {
@@ -55,10 +102,9 @@ func GiteaUpdateChecker(httpEndpoint string) error {
55102
respData := respType{}
56103
err = json.Unmarshal(body, &respData)
57104
if err != nil {
58-
return err
105+
return "", err
59106
}
60-
61-
return UpdateRemoteVersion(respData.Latest.Version)
107+
return respData.Latest.Version, nil
62108
}
63109

64110
// UpdateRemoteVersion updates the latest available version of Gitea
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2023 The Forgejo Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package updatechecker
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestDNSUpdate(t *testing.T) {
13+
version, err := getVersionDNS("release.forgejo.org")
14+
assert.NoError(t, err)
15+
assert.NotEmpty(t, version)
16+
}

services/cron/tasks_extended.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,20 @@ func registerDeleteOldActions() {
142142
func registerUpdateGiteaChecker() {
143143
type UpdateCheckerConfig struct {
144144
BaseConfig
145-
HTTPEndpoint string
145+
HTTPEndpoint string
146+
DomainEndpoint string
146147
}
147148
RegisterTaskFatal("update_checker", &UpdateCheckerConfig{
148149
BaseConfig: BaseConfig{
149150
Enabled: false,
150151
RunAtStart: false,
151152
Schedule: "@every 168h",
152153
},
153-
HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
154+
HTTPEndpoint: "https://dl.gitea.io/gitea/version.json",
155+
DomainEndpoint: "release.forgejo.org",
154156
}, func(ctx context.Context, _ *user_model.User, config Config) error {
155157
updateCheckerConfig := config.(*UpdateCheckerConfig)
156-
return updatechecker.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint)
158+
return updatechecker.GiteaUpdateChecker(updateCheckerConfig.HTTPEndpoint, updateCheckerConfig.DomainEndpoint)
157159
})
158160
}
159161

0 commit comments

Comments
 (0)