17 files changed

+254
-80
lines changed
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Gitblit is an open source, pure Java Git solution for managing, viewing, and ser
55

66
More information about Gitblit can be found [here](http://gitblit.com).
77

8-
<a href='https://.com/fzs/gitblit/releases/latest'><img src='https://img.shields.io/badge/dynamic/json?color=9cf&label=Download&query=%24.name&url=https%3A%2F%2Fapi..com%2Frepos%2Ffzs%2Fgitblit%2Freleases%2Flatest'></a>
8+
<a href='https://.com/gitblit/gitblit/releases/latest'><img src='https://img.shields.io/badge/dynamic/json?color=9cf&label=Download&query=%24.name&url=https%3A%2F%2Fapi..com%2Frepos%2Fgitblit%2Fgitblit%2Freleases%2Flatest'></a>
99

1010
License
1111
-------
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ name: Gitblit
1010
description: pure Java Git solution
1111
groupId: com.gitblit
1212
artifactId: gitblit
13-
version: 1.9.0-SNAPSHOT
13+
version: 1.9.1-SNAPSHOT
1414
inceptionYear: 2011
1515

1616
# Current stable release
17-
releaseVersion: 1.8.0
18-
releaseDate: 2016-06-22
17+
releaseVersion: 1.9.0
18+
releaseDate: 2020-02-01
1919

2020
# Project urls
2121
url: 'http://gitblit.com'
@@ -96,8 +96,8 @@ dependencyDirectory: ext
9696
registeredRepositories:
9797
- { id: central, url: 'https://repo1.maven.org/maven2' }
9898
- { id: mavencentral, url: 'https://repo1.maven.org/maven2' }
99-
- { id: eclipse, url: 'http://repo.eclipse.org/content/groups/releases' }
100-
- { id: eclipse-snapshots, url: 'http://repo.eclipse.org/content/groups/snapshots' }
99+
- { id: eclipse, url: 'https://repo.eclipse.org/content/groups/releases' }
100+
- { id: eclipse-snapshots, url: 'https://repo.eclipse.org/content/groups/snapshots' }
101101
- { id: gitblit, url: 'http://gitblit..io/gitblit-maven' }
102102

103103
# Source all dependencies from the following repositories in the specified order
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,50 @@
11
#
22
# ${project.version} release
33
#
4-
r30: {
4+
r31: {
55
title: ${project.name} ${project.version} released
66
id: ${project.version}
77
date: ${project.buildDate}
8+
note: ''
9+
When you have Gitblit installed as a service under Linux or Windows, you may need to edit your service script/definition. The command line to start Gitblit needs to be different, the classpath and class are speficied now.
10+
11+
See notes for release 1.9.0.
12+
''
13+
html: ~
14+
text: ''
15+
!! IMPORTANT BUG FIX FOR PASSWORD HASH UPGRADE !!
16+
17+
There is a severe bug in version 1.9.0, which can lock users out from their accounts.
18+
When updating from a previous version to 1.9.0, existing stored passwords are rehashed
19+
with a more secure password hash mechanism when a user first logs in after the update.
20+
This happens when the password hashing mechanism was left at default and not specifically
21+
set in the configuration. An error in the implementation will destroy the stored password
22+
instead and the user can no longer log in.
23+
24+
Only certain circumstances will lead to this wrong behaviour. It will most likely
25+
affect users of the Gitblit Docker container. If you did not encounter any problems,
26+
update to 1.9.1 to be on the safe side. If you were hit by this bug, we are deeply sorry.
27+
There is no way to fix the affected accounts other than to set a new password.
28+
29+
This is fixed in 1.9.1. Updates of existing installations should be made to 1.9.1, not 1.9.0.
30+
''
31+
security: ~
32+
fixes:
33+
- Fixed broken password hash upgrade destroying existing stored passwords on update.
34+
- Fixed Linux service scripts to use `-cp` parameter instead of `-jar`.
35+
changes: ~
36+
additions: ~
37+
dependencyChanges: ~
38+
contributors: ~
39+
}
40+
41+
#
42+
# 1.9.0 release
43+
#
44+
r30: {
45+
title: Gitblit 1.9.0 released
46+
id: 1.9.0
47+
date: 2020-02-01
848
note: ''
949
Gitblit uses Servlet 3.0 and thus drops support for Tomcat 6. Run on Tomcat 6 at your own risk.
1050

@@ -18,7 +58,8 @@ r30: {
1858

1959
When the `realm.ldap.bindpattern` property is set, GitBlit will only bind as the user to LDAP, not to a manager account or anonymously.
2060

21-
Older password storage mechanisms are deprecated, PBKDF2 is the new default. When you switch from plaintext to a hashed scheme, or from the older hashed to the new PBKDF2 scheme, the stored password of a user will be rehashed with the more secure mechanism when the user logs in.
61+
Older password storage mechanisms are deprecated, PBKDF2 is the new default. When you switch from plaintext to a hashed scheme, or from the older hashed to the new PBKDF2 scheme, the stored password of a user will be rehashed with the more secure mechanism when the user logs in.
62+
!! THIS IS BROKEN IN 1.9.0. DO NOT UPDATE TO 1.9.0. USE 1.9.1 INSTEAD !!
2263
''
2364
html: ~
2465
text: ''
@@ -1949,6 +1990,6 @@ r1: {
19491990
- James Moger
19501991
}
19511992

1952-
snapshot: &r30
1953-
release: &r29
1954-
releases: &r[1..29]
1993+
snapshot: &r31
1994+
release: &r30
1995+
releases: &r[1..30]
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#!/bin/bash
2-
java -cp gitblit.jar:ext/* com.gitblit.authority.GitblitAuthority --baseFolder data
2+
java -cp "gitblit.jar:ext/*" com.gitblit.authority.GitblitAuthority --baseFolder data
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ After=network.target
1818
[Service]
1919
User=gitblit
2020
Group=gitblit
21-
Environment="ARGS=-server -Xmx1024M -Djava.awt.headless=true -jar"
21+
Environment="ARGS=-server -Xmx1024M -Djava.awt.headless=true -cp"
2222
EnvironmentFile=-/etc/sysconfig/gitblit
2323
WorkingDirectory=/opt/gitblit
24-
ExecStart=/usr/bin/java \$ARGS gitblit.jar --httpsPort \$GITBLIT_HTTPS_PORT --httpPort \$GITBLIT_HTTP_PORT --baseFolder \$GITBLIT_BASE_FOLDER --dailyLogFile
25-
ExecStop=/usr/bin/java \$ARGS gitblit.jar --baseFolder \$GITBLIT_BASE_FOLDER --stop
24+
ExecStart=/usr/bin/java \$ARGS gitblit.jar:ext/* com.gitblit.GitBlitServer --httpsPort \$GITBLIT_HTTPS_PORT --httpPort \$GITBLIT_HTTP_PORT --baseFolder \$GITBLIT_BASE_FOLDER --dailyLogFile
25+
ExecStop=/usr/bin/java \$ARGS gitblit.jar:ext/* com.gitblit.GitBlitServer --baseFolder \$GITBLIT_BASE_FOLDER --stop
2626
2727
[Install]
2828
WantedBy=multi-user.target
2929
EOF
3030

3131
# Finally copy the files to the destination and register the systemd unit.
32-
sudo su -c "cp /tmp/gitblit.defaults /etc/sysconfig/gitblit && cp /tmp/gitblit.service /etc/systemd/system/"
33-
sudo su -c "systemctl daemon-reload && systemctl enable gitblit.service && systemctl start gitblit.service"
32+
sudo sh -c "cp /tmp/gitblit.defaults /etc/sysconfig/gitblit && cp /tmp/gitblit.service /etc/systemd/system/"
33+
sudo sh -c "systemctl daemon-reload && systemctl enable gitblit.service && systemctl start gitblit.service"
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#
99
# --------------------------------------------------------------------------
1010

11-
if [[ -z $1 || -z $2 ]]; then
11+
if [ -z $1 ] || [ -z $2 ]; then
1212
echo "Please specify the output ticket service and your baseFolder!";
1313
echo "";
1414
echo "usage:";
@@ -17,5 +17,5 @@ if [[ -z $1 || -z $2 ]]; then
1717
exit 1;
1818
fi
1919

20-
java -cp gitblit.jar:./ext/* com.gitblit.MigrateTickets $1 --baseFolder $2
20+
java -cp "gitblit.jar:ext/*" com.gitblit.MigrateTickets $1 --baseFolder $2
2121

Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
# --------------------------------------------------------------------------
1313

14-
if [[ -z $1 ]]; then
14+
if [ -z $1 ] ; then
1515
echo "Please specify your baseFolder!";
1616
echo "";
1717
echo "usage:";
@@ -20,5 +20,5 @@ if [[ -z $1 ]]; then
2020
exit 1;
2121
fi
2222

23-
java -cp gitblit.jar:./ext/* com.gitblit.ReindexTickets --baseFolder $1
23+
java -cp "gitblit.jar:ext/*" com.gitblit.ReindexTickets --baseFolder $1
2424

Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ GITBLIT_HTTP_PORT=0
1111
GITBLIT_HTTPS_PORT=8443
1212
GITBLIT_LOG=/var/log/gitblit.log
1313
source ${GITBLIT_PATH}/java-proxy-config.sh
14-
JAVA="java -server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar"
14+
JAVA="java -server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -cp"
1515

1616
RETVAL=0
1717

@@ -21,7 +21,7 @@ case "$1" in
2121
then
2222
echo $"Starting gitblit server"
2323
cd $GITBLIT_PATH
24-
$JAVA $GITBLIT_PATH/gitblit.jar --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER --dailyLogFile &
24+
$JAVA "$GITBLIT_PATH/gitblit.jar:$GITBLIT_PATH/ext/*" com.gitblit.GitBlitServer --httpsPort $GITBLIT_HTTPS_PORT --httpPort $GITBLIT_HTTP_PORT --baseFolder $GITBLIT_BASE_FOLDER --dailyLogFile &
2525
echo "."
2626
exit $RETVAL
2727
fi
@@ -32,7 +32,7 @@ case "$1" in
3232
then
3333
echo $"Stopping gitblit server"
3434
cd $GITBLIT_PATH
35-
$JAVA $GITBLIT_PATH/gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
35+
$JAVA "$GITBLIT_PATH/gitblit.jar:$GITBLIT_PATH/ext/*" com.gitblit.GitBlitServer --baseFolder $GITBLIT_BASE_FOLDER --stop > /dev/null &
3636
echo "."
3737
exit $RETVAL
3838
fi
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ GITBLIT_PATH=/opt/gitblit
1919
GITBLIT_BASE_FOLDER=/opt/gitblit/data
2020
GITBLIT_USER="gitblit"
2121
source ${GITBLIT_PATH}/java-proxy-config.sh
22-
ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -jar gitblit.jar --baseFolder $GITBLIT_BASE_FOLDER --dailyLogFile"
22+
ARGS="-server -Xmx1024M ${JAVA_PROXY_CONFIG} -Djava.awt.headless=true -cp gitblit.jar:ext/* com.gitblit.GitBlitServer --baseFolder $GITBLIT_BASE_FOLDER --dailyLogFile"
2323

2424
RETVAL=0
2525

Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
import java.nio.charset.Charset;
1919
import java.security.Principal;
2020
import java.text.MessageFormat;
21-
import java.util.ArrayList;
22-
import java.util.HashMap;
23-
import java.util.List;
24-
import java.util.Map;
21+
import java.util.*;
2522
import java.util.concurrent.TimeUnit;
2623

2724
import javax.servlet.http.Cookie;
@@ -455,7 +452,6 @@ protected void flagRequest(HttpServletRequest httpRequest, AuthenticationType au
455452
/**
456453
* Authenticate a user based on a username and password.
457454
*
458-
* @see IUserService.authenticate(String, char[])
459455
* @param username
460456
* @param password
461457
* @return a user object or null
@@ -474,34 +470,39 @@ public UserModel authenticate(String username, char[] password, String remoteIP)
474470
}
475471

476472
String usernameDecoded = StringUtils.decodeUsername(username);
477-
String pw = new String(password);
478-
if (StringUtils.isEmpty(pw)) {
473+
if (StringUtils.isEmpty(password)) {
479474
// can not authenticate empty password
480475
return null;
481476
}
482477

483478
UserModel user = userManager.getUserModel(usernameDecoded);
484479

485-
// try local authentication
486-
if (user != null && user.isLocalAccount()) {
487-
UserModel returnedUser = authenticateLocal(user, password);
488-
if (returnedUser != null) {
489-
// user authenticated
490-
return returnedUser;
491-
}
492-
} else {
493-
// try registered external authentication providers
494-
for (AuthenticationProvider provider : authenticationProviders) {
495-
if (provider instanceof UsernamePasswordAuthenticationProvider) {
496-
UserModel returnedUser = provider.authenticate(usernameDecoded, password);
497-
if (returnedUser != null) {
498-
// user authenticated
499-
returnedUser.accountType = provider.getAccountType();
500-
return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS);
480+
try {
481+
// try local authentication
482+
if (user != null && user.isLocalAccount()) {
483+
UserModel returnedUser = authenticateLocal(user, password);
484+
if (returnedUser != null) {
485+
// user authenticated
486+
return returnedUser;
487+
}
488+
} else {
489+
// try registered external authentication providers
490+
for (AuthenticationProvider provider : authenticationProviders) {
491+
if (provider instanceof UsernamePasswordAuthenticationProvider) {
492+
UserModel returnedUser = provider.authenticate(usernameDecoded, password);
493+
if (returnedUser != null) {
494+
// user authenticated
495+
returnedUser.accountType = provider.getAccountType();
496+
return validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS);
497+
}
501498
}
502499
}
503500
}
504501
}
502+
finally {
503+
// Zero out password array to delete password from memory
504+
Arrays.fill(password, Character.MIN_VALUE);
505+
}
505506

506507
// could not authenticate locally or with a provider
507508
logger.warn(MessageFormat.format("Failed login attempt for {0}, invalid credentials from {1}", username,
@@ -520,21 +521,33 @@ public UserModel authenticate(String username, char[] password, String remoteIP)
520521
protected UserModel authenticateLocal(UserModel user, char [] password) {
521522
UserModel returnedUser = null;
522523

523-
PasswordHash pwdHash = PasswordHash.instanceFor(user.password);
524-
if (pwdHash != null) {
525-
if (pwdHash.matches(user.password, password, user.username)) {
524+
// Create a copy of the password that we can use to rehash to upgrade to a more secure hashing method.
525+
// This is done to be independent from the implementation of the PasswordHash, which might already clear out
526+
// the password it gets passed in. This looks a bit stupid, as we could simply clean up the mess, but this
527+
// falls under "better safe than sorry".
528+
char[] pwdToUpgrade = Arrays.copyOf(password, password.length);
529+
try {
530+
PasswordHash pwdHash = PasswordHash.instanceFor(user.password);
531+
if (pwdHash != null) {
532+
if (pwdHash.matches(user.password, password, user.username)) {
533+
returnedUser = user;
534+
}
535+
} else if (user.password.equals(new String(password))) {
536+
// plain-text password
526537
returnedUser = user;
527538
}
528-
} else if (user.password.equals(new String(password))) {
529-
// plain-text password
530-
returnedUser = user;
531-
}
532-
533-
// validate user
534-
returnedUser = validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS);
535-
536-
// try to upgrade the stored password hash to a stronger hash, if necessary
537-
upgradeStoredPassword(returnedUser, password, pwdHash);
539+
540+
// validate user
541+
returnedUser = validateAuthentication(returnedUser, AuthenticationType.CREDENTIALS);
542+
543+
// try to upgrade the stored password hash to a stronger hash, if necessary
544+
upgradeStoredPassword(returnedUser, pwdToUpgrade, pwdHash);
545+
}
546+
finally {
547+
// Now we make sure that the password is zeroed out in any case.
548+
Arrays.fill(password, Character.MIN_VALUE);
549+
Arrays.fill(pwdToUpgrade, Character.MIN_VALUE);
550+
}
538551

539552
return returnedUser;
540553
}
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ public static boolean isEmpty(String value) {
5656
return value == null || value.trim().length() == 0;
5757
}
5858

59+
/**
60+
* Returns true if the character array represents an empty String.
61+
* An empty character sequence is defined as a sequence that
62+
* either has no characters at all, or no characters above
63+
* '\u0020' (space).
64+
*
65+
* @param value
66+
* @return true if value is null or represents an empty String
67+
*/
68+
public static boolean isEmpty(char[] value) {
69+
if (value == null || value.length == 0) return true;
70+
for ( char c : value) if (c > '\u0020') return false;
71+
return true;
72+
}
73+
5974
/**
6075
* Replaces carriage returns and line feeds with html line breaks.
6176
*
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,6 @@ Instead of using `federation.properties` you may directly specify a Gitblit inst
335335
java -cp fedclient.jar;"%CD%/ext/*" com.gitblit.FederationClient --url https://go.gitblit.com --mirror --bare --token 123456789
336336
--repositoriesFolder c:/mymirror
337337

338-
java -cp fedclient.jar:ext/* com.gitblit.FederationClient --url https://go.gitblit.com --mirror --bare --token 123456789
338+
java -cp "fedclient.jar:ext/*" com.gitblit.FederationClient --url https://go.gitblit.com --mirror --bare --token 123456789
339339
--repositoriesFolder /srv/mymirror --daemon --frequency "24 hours"
340340

Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Gitblit optionally allows a remote client to administer the Gitblit server. Thi
88
web.enableRpcManagement=false
99
web.enableRpcAdministration=false
1010

11-
**https** is strongly recommended because passwords are insecurely transmitted form your browser/rpc client using Basic authentication!
11+
**https** is strongly recommended because passwords are insecurely transmitted from your browser/rpc client using Basic authentication!
1212

1313
The Gitblit JSON RPC mechanism, like the Gitblit JGit servlet, syndication/feed servlet, etc, supports request-based authentication. Making an *admin* request will trigger Gitblit's basic authentication mechanism. Listing of repositories, generally, will not trigger this authentication mechanism unless *web.authenticateViewPages=true*. That means its possible to allow anonymous enumeration of repositories that are not *view restricted* or *clone restricted*. Of course, if credentials are provided then all private repositories that are available to the user account will be enumerated in the JSON response.
1414

Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Open `data/gitblit.properties` in your favorite text editor and make sure to rev
1717
**NOTE:** You can only have **one** SSL certificate specified for a port.
1818
4. exit the authority app
1919
4. Windows: Execute `gitblit.cmd` or `java -cp gitblit.jar;"%CD%\ext\*" com.gitblit.GitBlitServer --baseFolder data` from a command-line
20-
Linux/OSX: Execute `gitblit.sh` or `java -cp gitblit.jar;ext/* com.gitblit.GitBlitServer --baseFolder data` from a command-line
20+
Linux/OSX: Execute `gitblit.sh` or `java -cp "gitblit.jar:ext/*"" com.gitblit.GitBlitServer --baseFolder data` from a command-line
2121
5. Open your browser to <http://localhost:8080> or <https://localhost:8443> depending on your chosen configuration.
2222
6. Enter the default administrator credentials: **admin / admin** and click the *Login* button
2323
**NOTE:** Make sure to change the administrator username and/or password!!

0 commit comments

Comments
 (0)