Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide configuration to allow camo-media proxying #12802

Merged
merged 13 commits into from
Mar 29, 2022
4 changes: 4 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@ PASSWORD_HASH_ALGO = argon2
CSRF_COOKIE_HTTP_ONLY = true
; Validate against https://haveibeenpwned.com/Passwords to see if a password has been exposed
PASSWORD_CHECK_PWN = false
; Use a camo image proxy - leave empty to not use
CAMO_SERVER_URL =
; HMAC to encode urls with
CAMO_HMAC_KEY =

[openid]
;
Expand Down
2 changes: 2 additions & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ set name for unique queues. Individual queues will default to
- spec - use one or more special characters as ``!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~``
- off - do not check password complexity
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
- `CAMO_SERVER_URL`: **<empty>**: If you would like to use a camo proxy to proxy images from rendered content, set the camo server url here
lunny marked this conversation as resolved.
Show resolved Hide resolved
- `CAMO_HMAC_KEY`: **<empty>**: Provide the HMAC key for encoding urls

## OpenID (`openid`)

Expand Down
35 changes: 35 additions & 0 deletions modules/markup/camo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package markup

import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"strings"

"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)

// CamoEncode encodes a lnk to fit with the go-camo and camo proxy links
wxiaoguang marked this conversation as resolved.
Show resolved Hide resolved
func CamoEncode(link []byte) []byte {
if bytes.HasPrefix(link, []byte(setting.CamoServerURL)) || len(setting.CamoHMACKey) == 0 {
return link
}

hmacKey := []byte(setting.CamoHMACKey)
mac := hmac.New(sha1.New, hmacKey)
_, _ = mac.Write(link) // hmac does not return errors
macSum := b64encode(mac.Sum(nil))
encodedURL := b64encode(link)

return []byte(util.URLJoin(setting.CamoServerURL, macSum, encodedURL))
}

func b64encode(data []byte) string {
return strings.TrimRight(base64.URLEncoding.EncodeToString(data), "=")
}
9 changes: 9 additions & 0 deletions modules/markup/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,17 @@ func (ctx *postProcessCtx) visitNode(node *html.Node, visitText bool) {

lnk := string(link)
lnk = util.URLJoin(prefix, lnk)

link = []byte(lnk)
}
if setting.CamoServerURL != "" {
6543 marked this conversation as resolved.
Show resolved Hide resolved
lnk := string(link)
lnkURL, _ := url.Parse(lnk)
if lnkURL.IsAbs() && !strings.HasPrefix(lnk, setting.AppURL) {
6543 marked this conversation as resolved.
Show resolved Hide resolved
// We should camo this url
link = CamoEncode(link)
}
}
node.Attr[idx].Val = string(link)
}
} else if node.Data == "a" {
Expand Down
4 changes: 4 additions & 0 deletions modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ var (
PasswordComplexity []string
PasswordHashAlgo string
PasswordCheckPwn bool
CamoServerURL string
CamoHMACKey string

// UI settings
UI = struct {
Expand Down Expand Up @@ -746,6 +748,8 @@ func NewContext() {
PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("argon2")
CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true)
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
CamoServerURL = sec.Key("CAMO_SERVER_URL").MustString("")
CamoHMACKey = sec.Key("CAMO_HMAC_KEY").MustString("")

InternalToken = loadInternalToken(sec)

Expand Down