![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) | ![](https://github.com/gogits/gogs/blob/master/public/img/gogs-large-resize.png?raw=true) | ||||
##### Current version: 0.8.21 | |||||
##### Current version: 0.8.22 | |||||
| Web | UI | Preview | | | Web | UI | Preview | | ||||
|:-------------:|:-------:|:-------:| | |:-------------:|:-------:|:-------:| |
; More detail: https://github.com/gogits/gogs/issues/165 | ; More detail: https://github.com/gogits/gogs/issues/165 | ||||
ENABLE_REVERSE_PROXY_AUTHENTICATION = false | ENABLE_REVERSE_PROXY_AUTHENTICATION = false | ||||
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ||||
; Do not check minimum key size with corresponding type | |||||
DISABLE_MINIMUM_KEY_SIZE_CHECK = false | |||||
; Enable captcha validation for registration | ; Enable captcha validation for registration | ||||
ENABLE_CAPTCHA = true | ENABLE_CAPTCHA = true | ||||
; used to filter keys which are too short | |||||
[service.minimum_key_sizes] | |||||
ED25519 = 256 | |||||
ECDSA = 256 | |||||
NTRU = 1087 | |||||
MCE = 1702 | |||||
McE = 1702 | |||||
RSA = 1024 | |||||
DSA = 1024 | |||||
[webhook] | [webhook] | ||||
; Hook task queue length | ; Hook task queue length | ||||
QUEUE_LENGTH = 1000 | QUEUE_LENGTH = 1000 |
"github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
) | ) | ||||
const APP_VER = "0.8.21.0114" | |||||
const APP_VER = "0.8.22.0115" | |||||
func init() { | func init() { | ||||
runtime.GOMAXPROCS(runtime.NumCPU()) | runtime.GOMAXPROCS(runtime.NumCPU()) |
"github.com/Unknwon/com" | "github.com/Unknwon/com" | ||||
"github.com/go-xorm/xorm" | "github.com/go-xorm/xorm" | ||||
"golang.org/x/crypto/ssh" | |||||
"github.com/gogits/gogs/modules/log" | "github.com/gogits/gogs/modules/log" | ||||
"github.com/gogits/gogs/modules/process" | "github.com/gogits/gogs/modules/process" | ||||
return "", errors.New("only a single line with a single key please") | return "", errors.New("only a single line with a single key please") | ||||
} | } | ||||
// write the key to a file… | |||||
tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest") | |||||
if err != nil { | |||||
return "", err | |||||
fields := strings.Fields(content) | |||||
if len(fields) < 2 { | |||||
return "", errors.New("too less fields") | |||||
} | } | ||||
tmpPath := tmpFile.Name() | |||||
defer os.Remove(tmpPath) | |||||
tmpFile.WriteString(content) | |||||
tmpFile.Close() | |||||
// Check if ssh-keygen recognizes its contents. | |||||
stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-lf", tmpPath) | |||||
key, err := base64.StdEncoding.DecodeString(fields[1]) | |||||
if err != nil { | if err != nil { | ||||
return "", errors.New("ssh-keygen -lf: " + stderr) | |||||
} else if len(stdout) < 2 { | |||||
return "", errors.New("ssh-keygen returned not enough output to evaluate the key: " + stdout) | |||||
return "", fmt.Errorf("StdEncoding.DecodeString: %v", err) | |||||
} | } | ||||
// The ssh-keygen in Windows does not print key type, so no need go further. | |||||
if setting.IsWindows { | |||||
return content, nil | |||||
} | |||||
sshKeygenOutput := strings.Split(stdout, " ") | |||||
if len(sshKeygenOutput) < 4 { | |||||
return content, ErrKeyUnableVerify{stdout} | |||||
} | |||||
// Check if key type and key size match. | |||||
if !setting.Service.DisableMinimumKeySizeCheck { | |||||
keySize := com.StrTo(sshKeygenOutput[0]).MustInt() | |||||
if keySize == 0 { | |||||
return "", errors.New("cannot get key size of the given key") | |||||
} | |||||
keyType := strings.Trim(sshKeygenOutput[len(sshKeygenOutput)-1], " ()\n") | |||||
if minimumKeySize := setting.Service.MinimumKeySizes[keyType]; minimumKeySize == 0 { | |||||
return "", fmt.Errorf("unrecognized public key type: %s", keyType) | |||||
} else if keySize < minimumKeySize { | |||||
return "", fmt.Errorf("the minimum accepted size of a public key %s is %d", keyType, minimumKeySize) | |||||
} | |||||
pkey, err := ssh.ParsePublicKey([]byte(key)) | |||||
if err != nil { | |||||
return "", fmt.Errorf("ParsePublicKey: %v", err) | |||||
} | } | ||||
log.Trace("Key type: %s", pkey.Type()) | |||||
return content, nil | return content, nil | ||||
} | } |
EnableNotifyMail bool | EnableNotifyMail bool | ||||
EnableReverseProxyAuth bool | EnableReverseProxyAuth bool | ||||
EnableReverseProxyAutoRegister bool | EnableReverseProxyAutoRegister bool | ||||
DisableMinimumKeySizeCheck bool | |||||
MinimumKeySizes map[string]int | |||||
EnableCaptcha bool | EnableCaptcha bool | ||||
} | } | ||||
Service.EnableCacheAvatar = sec.Key("ENABLE_CACHE_AVATAR").MustBool() | Service.EnableCacheAvatar = sec.Key("ENABLE_CACHE_AVATAR").MustBool() | ||||
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | ||||
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool() | ||||
Service.DisableMinimumKeySizeCheck = sec.Key("DISABLE_MINIMUM_KEY_SIZE_CHECK").MustBool() | |||||
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() | Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool() | ||||
minimumKeySizes := Cfg.Section("service.minimum_key_sizes").Keys() | |||||
Service.MinimumKeySizes = make(map[string]int) | |||||
for _, key := range minimumKeySizes { | |||||
Service.MinimumKeySizes[key.Name()] = key.MustInt() | |||||
} | |||||
} | } | ||||
var logLevels = map[string]string{ | var logLevels = map[string]string{ |
0.8.21.0114 | |||||
0.8.22.0115 |