Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
9ba18f5d
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
9ba18f5d
编写于
2月 15, 2020
作者:
T
Tim Jacomb
提交者:
GitHub
2月 15, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into jep-223
上级
58a3f01c
7ff5f097
变更
42
显示空白变更内容
内联
并排
Showing
42 changed file
with
300 addition
and
93 deletion
+300
-93
cli/src/main/java/hudson/cli/CLI.java
cli/src/main/java/hudson/cli/CLI.java
+14
-2
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
+11
-4
cli/src/main/java/hudson/cli/NoCheckTrustManager.java
cli/src/main/java/hudson/cli/NoCheckTrustManager.java
+5
-0
cli/src/main/java/hudson/cli/SSHCLI.java
cli/src/main/java/hudson/cli/SSHCLI.java
+6
-2
core/src/main/java/hudson/ClassicPluginStrategy.java
core/src/main/java/hudson/ClassicPluginStrategy.java
+1
-0
core/src/main/java/hudson/Proc.java
core/src/main/java/hudson/Proc.java
+2
-0
core/src/main/java/hudson/Util.java
core/src/main/java/hudson/Util.java
+11
-1
core/src/main/java/hudson/cli/Connection.java
core/src/main/java/hudson/cli/Connection.java
+9
-2
core/src/main/java/hudson/console/AnnotatedLargeText.java
core/src/main/java/hudson/console/AnnotatedLargeText.java
+7
-1
core/src/main/java/hudson/console/ConsoleNote.java
core/src/main/java/hudson/console/ConsoleNote.java
+7
-1
core/src/main/java/hudson/scheduler/Hash.java
core/src/main/java/hudson/scheduler/Hash.java
+10
-2
core/src/main/java/hudson/security/BasicAuthenticationFilter.java
.../main/java/hudson/security/BasicAuthenticationFilter.java
+8
-2
core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java
.../java/hudson/security/HudsonAuthenticationEntryPoint.java
+15
-9
core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java
...main/java/hudson/security/HudsonPrivateSecurityRealm.java
+1
-1
core/src/main/java/hudson/util/ConsistentHash.java
core/src/main/java/hudson/util/ConsistentHash.java
+9
-1
core/src/main/java/hudson/util/DOSToUnixPathHelper.java
core/src/main/java/hudson/util/DOSToUnixPathHelper.java
+7
-2
core/src/main/java/hudson/util/FormFieldValidator.java
core/src/main/java/hudson/util/FormFieldValidator.java
+8
-1
core/src/main/java/jenkins/InitReactorRunner.java
core/src/main/java/jenkins/InitReactorRunner.java
+3
-1
core/src/main/java/jenkins/model/RunIdMigrator.java
core/src/main/java/jenkins/model/RunIdMigrator.java
+8
-1
core/src/main/java/jenkins/model/identity/IdentityRootAction.java
.../main/java/jenkins/model/identity/IdentityRootAction.java
+9
-1
core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java
...src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java
+6
-2
core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly
...main/resources/hudson/model/View/AsynchPeople/index.jelly
+1
-1
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
...dson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
+28
-10
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage.jelly
.../security/HudsonPrivateSecurityRealm/_entryFormPage.jelly
+23
-15
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css
...y/HudsonPrivateSecurityRealm/_entryFormPage/resources.css
+12
-0
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly
.../hudson/security/HudsonPrivateSecurityRealm/addUser.jelly
+3
-3
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config.jelly
...s/hudson/security/HudsonPrivateSecurityRealm/config.jelly
+1
-2
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly
...udson/security/HudsonPrivateSecurityRealm/firstUser.jelly
+3
-3
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly
...es/hudson/security/HudsonPrivateSecurityRealm/index.jelly
+6
-6
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink.jelly
...udson/security/HudsonPrivateSecurityRealm/loginLink.jelly
+2
-2
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly
...udson/security/HudsonPrivateSecurityRealm/sidepanel.jelly
+5
-5
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
...sonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
+3
-3
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success.jelly
.../hudson/security/HudsonPrivateSecurityRealm/success.jelly
+1
-1
core/src/main/resources/hudson/security/SecurityRealm/signup.jelly
...main/resources/hudson/security/SecurityRealm/signup.jelly
+1
-1
core/src/main/resources/lib/layout/hasPermission.jelly
core/src/main/resources/lib/layout/hasPermission.jelly
+8
-2
core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java
core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java
+7
-2
pom.xml
pom.xml
+14
-0
src/findbugs/findbugs-excludes.xml
src/findbugs/findbugs-excludes.xml
+8
-0
test/src/test/java/hudson/PluginManagerTest.java
test/src/test/java/hudson/PluginManagerTest.java
+12
-0
test/src/test/resources/plugins/require-system-in-initializer.jpi
.../test/resources/plugins/require-system-in-initializer.jpi
+0
-0
war/pom.xml
war/pom.xml
+1
-1
war/src/main/webapp/css/style.css
war/src/main/webapp/css/style.css
+4
-0
未找到文件。
cli/src/main/java/hudson/cli/CLI.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.cli
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.cli.client.Messages
;
import
java.io.DataInputStream
;
import
javax.net.ssl.HostnameVerifier
;
...
...
@@ -175,6 +176,7 @@ public class CLI {
HttpsURLConnection
.
setDefaultSSLSocketFactory
(
context
.
getSocketFactory
());
// bypass host name check, too.
HttpsURLConnection
.
setDefaultHostnameVerifier
(
new
HostnameVerifier
()
{
@SuppressFBWarnings
(
value
=
"WEAK_HOSTNAME_VERIFIER"
,
justification
=
"User set parameter to skip verifier."
)
public
boolean
verify
(
String
s
,
SSLSession
sslSession
)
{
return
true
;
}
...
...
@@ -188,7 +190,7 @@ public class CLI {
continue
;
}
if
(
head
.
equals
(
"-i"
)
&&
args
.
size
()>=
2
)
{
File
f
=
new
File
(
args
.
get
(
1
)
);
File
f
=
getFileFromArguments
(
args
);
if
(!
f
.
exists
())
{
printUsage
(
Messages
.
CLI_NoSuchFileExists
(
f
));
return
-
1
;
...
...
@@ -290,7 +292,7 @@ public class CLI {
if
(
userInfo
!=
null
)
{
factory
=
factory
.
basicAuth
(
userInfo
);
}
else
if
(
auth
!=
null
)
{
factory
=
factory
.
basicAuth
(
auth
.
startsWith
(
"@"
)
?
FileUtils
.
readFileToString
(
new
File
(
auth
.
substring
(
1
)),
Charset
.
defaultCharset
()
).
trim
()
:
auth
);
factory
=
factory
.
basicAuth
(
auth
.
startsWith
(
"@"
)
?
readAuthFromFile
(
auth
).
trim
()
:
auth
);
}
if
(
mode
==
Mode
.
HTTP
)
{
...
...
@@ -304,6 +306,16 @@ public class CLI {
throw
new
AssertionError
();
}
@SuppressFBWarnings
(
value
=
{
"PATH_TRAVERSAL_IN"
,
"URLCONNECTION_SSRF_FD"
},
justification
=
"User provided values for running the program."
)
private
static
String
readAuthFromFile
(
String
auth
)
throws
IOException
{
return
FileUtils
.
readFileToString
(
new
File
(
auth
.
substring
(
1
)),
Charset
.
defaultCharset
());
}
@SuppressFBWarnings
(
value
=
{
"PATH_TRAVERSAL_IN"
,
"URLCONNECTION_SSRF_FD"
},
justification
=
"User provided values for running the program."
)
private
static
File
getFileFromArguments
(
List
<
String
>
args
)
{
return
new
File
(
args
.
get
(
1
));
}
private
static
int
webSocketConnection
(
String
url
,
List
<
String
>
args
,
CLIConnectionFactory
factory
)
throws
Exception
{
LOGGER
.
fine
(()
->
"Trying to connect to "
+
url
+
" via plain protocol over WebSocket"
);
class
CLIEndpoint
extends
Endpoint
{
...
...
cli/src/main/java/hudson/cli/FullDuplexHttpStream.java
浏览文件 @
9ba18f5d
package
hudson.cli
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
...
...
@@ -60,7 +62,7 @@ public class FullDuplexHttpStream {
// server->client
LOGGER
.
fine
(
"establishing download side"
);
HttpURLConnection
con
=
(
HttpURLConnection
)
target
.
openConnection
(
);
HttpURLConnection
con
=
openHttpConnection
(
target
);
con
.
setDoOutput
(
true
);
// request POST to avoid caching
con
.
setRequestMethod
(
"POST"
);
con
.
addRequestProperty
(
"Session"
,
uuid
.
toString
());
...
...
@@ -78,7 +80,7 @@ public class FullDuplexHttpStream {
// client->server uses chunked encoded POST for unlimited capacity.
LOGGER
.
fine
(
"establishing upload side"
);
con
=
(
HttpURLConnection
)
target
.
openConnection
(
);
con
=
openHttpConnection
(
target
);
con
.
setDoOutput
(
true
);
// request POST
con
.
setRequestMethod
(
"POST"
);
con
.
setChunkedStreamingMode
(
0
);
...
...
@@ -92,10 +94,15 @@ public class FullDuplexHttpStream {
LOGGER
.
fine
(
"established upload side"
);
}
// As this transport mode is using POST, it is necessary to resolve possible redirections using GET first.
@SuppressFBWarnings
(
value
=
"URLCONNECTION_SSRF_FD"
,
justification
=
"Client-side code doesn't involve SSRF."
)
private
HttpURLConnection
openHttpConnection
(
URL
target
)
throws
IOException
{
return
(
HttpURLConnection
)
target
.
openConnection
();
}
// As this transport mode is using POST, it is necessary to resolve possible redirections using GET first. @SuppressFBWarnings(value = "URLCONNECTION_SSRF_FD", justification = "Client-side code doesn't involve SSRF.")
private
URL
tryToResolveRedirects
(
URL
base
,
String
authorization
)
{
try
{
HttpURLConnection
con
=
(
HttpURLConnection
)
base
.
openConnection
(
);
HttpURLConnection
con
=
openHttpConnection
(
base
);
if
(
authorization
!=
null
)
{
con
.
addRequestProperty
(
"Authorization"
,
authorization
);
}
...
...
cli/src/main/java/hudson/cli/NoCheckTrustManager.java
浏览文件 @
9ba18f5d
package
hudson.cli
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
javax.net.ssl.X509TrustManager
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
...
...
@@ -8,12 +10,15 @@ import java.security.cert.X509Certificate;
* @author Kohsuke Kawaguchi
*/
public
class
NoCheckTrustManager
implements
X509TrustManager
{
@SuppressFBWarnings
(
value
=
"WEAK_TRUST_MANAGER"
,
justification
=
"User set parameter to skip verifier."
)
public
void
checkClientTrusted
(
X509Certificate
[]
x509Certificates
,
String
s
)
throws
CertificateException
{
}
@SuppressFBWarnings
(
value
=
"WEAK_TRUST_MANAGER"
,
justification
=
"User set parameter to skip verifier."
)
public
void
checkServerTrusted
(
X509Certificate
[]
x509Certificates
,
String
s
)
throws
CertificateException
{
}
@SuppressFBWarnings
(
value
=
"WEAK_TRUST_MANAGER"
,
justification
=
"User set parameter to skip verifier."
)
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
new
X509Certificate
[
0
];
}
...
...
cli/src/main/java/hudson/cli/SSHCLI.java
浏览文件 @
9ba18f5d
...
...
@@ -61,11 +61,10 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
*/
class
SSHCLI
{
@SuppressFBWarnings
(
value
=
"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"
,
justification
=
"Due to whatever reason FindBugs reports it fot try-with-resources"
)
static
int
sshConnection
(
String
jenkinsUrl
,
String
user
,
List
<
String
>
args
,
PrivateKeyProvider
provider
,
final
boolean
strictHostKey
)
throws
IOException
{
Logger
.
getLogger
(
SecurityUtils
.
class
.
getName
()).
setLevel
(
Level
.
WARNING
);
// suppress: BouncyCastle not registered, using the default JCE provider
URL
url
=
new
URL
(
jenkinsUrl
+
"login"
);
URLConnection
conn
=
url
.
openConnection
(
);
URLConnection
conn
=
openConnection
(
url
);
CLI
.
verifyJenkinsConnection
(
conn
);
String
endpointDescription
=
conn
.
getHeaderField
(
"X-SSH-Endpoint"
);
...
...
@@ -131,6 +130,11 @@ class SSHCLI {
}
}
@SuppressFBWarnings
(
value
=
"URLCONNECTION_SSRF_FD"
,
justification
=
"Client-side code doesn't involve SSRF."
)
private
static
URLConnection
openConnection
(
URL
url
)
throws
IOException
{
return
url
.
openConnection
();
}
private
SSHCLI
()
{}
}
core/src/main/java/hudson/ClassicPluginStrategy.java
浏览文件 @
9ba18f5d
...
...
@@ -431,6 +431,7 @@ public class ClassicPluginStrategy implements PluginStrategy {
return
null
;
}
@SuppressFBWarnings
(
value
=
"PATH_TRAVERSAL_IN"
,
justification
=
"Administrator action installing a plugin, which could do far worse."
)
private
static
File
resolve
(
File
base
,
String
relative
)
{
File
rel
=
new
File
(
relative
);
if
(
rel
.
isAbsolute
())
...
...
core/src/main/java/hudson/Proc.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.Launcher.ProcStarter
;
import
hudson.model.TaskListener
;
import
hudson.remoting.Channel
;
...
...
@@ -215,6 +216,7 @@ public abstract class Proc {
* @param err
* null to redirect stderr to stdout.
*/
@SuppressFBWarnings
(
value
=
"COMMAND_INJECTION"
,
justification
=
"Command injection is the point of this old, barely used class."
)
public
LocalProc
(
String
[]
cmd
,
String
[]
env
,
InputStream
in
,
OutputStream
out
,
OutputStream
err
,
File
workDir
)
throws
IOException
{
this
(
calcName
(
cmd
),
stderr
(
environment
(
new
ProcessBuilder
(
cmd
),
env
).
directory
(
workDir
),
err
==
null
||
err
==
SELFPUMP_OUTPUT
),
...
...
core/src/main/java/hudson/Util.java
浏览文件 @
9ba18f5d
...
...
@@ -589,6 +589,8 @@ public class Util {
/**
* Computes MD5 digest of the given input stream.
*
* This method should only be used for non-security applications where the MD5 weakness is not a problem.
*
* @param source
* The stream will be closed by this method at the end of this method.
* @return
...
...
@@ -598,7 +600,7 @@ public class Util {
@Nonnull
public
static
String
getDigestOf
(
@Nonnull
InputStream
source
)
throws
IOException
{
try
{
MessageDigest
md5
=
MessageDigest
.
getInstance
(
"MD5"
);
MessageDigest
md5
=
getMd5
(
);
DigestInputStream
in
=
new
DigestInputStream
(
source
,
md5
);
// Note: IOUtils.copy() buffers the input internally, so there is no
// need to use a BufferedInputStream.
...
...
@@ -618,6 +620,14 @@ public class Util {
*/
}
// TODO JENKINS-60563 remove MD5 from all usages in Jenkins
@SuppressFBWarnings
(
value
=
"WEAK_MESSAGE_DIGEST_MD5"
,
justification
=
"This method should only be used for non-security applications where the MD5 weakness is not a problem."
)
@Deprecated
private
static
MessageDigest
getMd5
()
throws
NoSuchAlgorithmException
{
return
MessageDigest
.
getInstance
(
"MD5"
);
}
@Nonnull
public
static
String
getDigestOf
(
@Nonnull
String
text
)
{
try
{
...
...
core/src/main/java/hudson/cli/Connection.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.cli
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.remoting.ClassFilter
;
import
hudson.remoting.ObjectInputStreamEx
;
import
hudson.remoting.SocketChannelStream
;
...
...
@@ -113,6 +114,8 @@ public class Connection {
/**
* Receives an object sent by {@link #writeObject(Object)}
*/
// TODO JENKINS-60562 remove this class
@SuppressFBWarnings
(
value
=
"OBJECT_DESERIALIZATION"
,
justification
=
"Not used. We should just remove it. Class is deprecated."
)
public
<
T
>
T
readObject
()
throws
IOException
,
ClassNotFoundException
{
ObjectInputStream
ois
=
new
ObjectInputStreamEx
(
in
,
getClass
().
getClassLoader
(),
ClassFilter
.
DEFAULT
);
...
...
@@ -194,16 +197,20 @@ public class Connection {
*/
public
Connection
encryptConnection
(
SecretKey
sessionKey
,
String
algorithm
)
throws
IOException
,
GeneralSecurityException
{
Cipher
cout
=
Cipher
.
getInstance
(
algorithm
);
cout
.
init
(
Cipher
.
ENCRYPT_MODE
,
sessionKey
,
new
IvParameterSpec
(
sessionKey
.
getEncoded
()
));
cout
.
init
(
Cipher
.
ENCRYPT_MODE
,
sessionKey
,
createIv
(
sessionKey
));
CipherOutputStream
o
=
new
CipherOutputStream
(
out
,
cout
);
Cipher
cin
=
Cipher
.
getInstance
(
algorithm
);
cin
.
init
(
Cipher
.
DECRYPT_MODE
,
sessionKey
,
new
IvParameterSpec
(
sessionKey
.
getEncoded
()
));
cin
.
init
(
Cipher
.
DECRYPT_MODE
,
sessionKey
,
createIv
(
sessionKey
));
CipherInputStream
i
=
new
CipherInputStream
(
in
,
cin
);
return
new
Connection
(
i
,
o
);
}
private
IvParameterSpec
createIv
(
SecretKey
sessionKey
)
{
return
new
IvParameterSpec
(
sessionKey
.
getEncoded
());
}
/**
* Given a byte array that contains arbitrary number of bytes, digests or expands those bits into the specified
* number of bytes without loss of entropy.
...
...
core/src/main/java/hudson/console/AnnotatedLargeText.java
浏览文件 @
9ba18f5d
...
...
@@ -25,6 +25,7 @@
*/
package
hudson.console
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
jenkins.model.Jenkins
;
import
hudson.remoting.ObjectInputStreamEx
;
import
java.util.concurrent.TimeUnit
;
...
...
@@ -128,7 +129,7 @@ public class AnnotatedLargeText<T> extends LargeText {
long
timestamp
=
ois
.
readLong
();
if
(
TimeUnit
.
HOURS
.
toMillis
(
1
)
>
abs
(
System
.
currentTimeMillis
()-
timestamp
))
// don't deserialize something too old to prevent a replay attack
return
(
ConsoleAnnotator
)
ois
.
readObject
(
);
return
getConsoleAnnotator
(
ois
);
}
catch
(
RuntimeException
ex
)
{
throw
new
IOException
(
"Could not decode input"
,
ex
);
}
...
...
@@ -140,6 +141,11 @@ public class AnnotatedLargeText<T> extends LargeText {
return
ConsoleAnnotator
.
initial
(
context
);
}
@SuppressFBWarnings
(
value
=
"OBJECT_DESERIALIZATION"
,
justification
=
"Deserialization is protected by logic."
)
private
ConsoleAnnotator
getConsoleAnnotator
(
ObjectInputStream
ois
)
throws
IOException
,
ClassNotFoundException
{
return
(
ConsoleAnnotator
)
ois
.
readObject
();
}
@CheckReturnValue
@Override
public
long
writeLogTo
(
long
start
,
Writer
w
)
throws
IOException
{
...
...
core/src/main/java/hudson/console/ConsoleNote.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.console
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.ExtensionPoint
;
import
hudson.Functions
;
import
hudson.MarkupText
;
...
...
@@ -275,7 +276,7 @@ public abstract class ConsoleNote<T> implements Serializable, Describable<Consol
try
(
ObjectInputStream
ois
=
new
ObjectInputStreamEx
(
new
GZIPInputStream
(
new
ByteArrayInputStream
(
buf
)),
jenkins
!=
null
?
jenkins
.
pluginManager
.
uberClassLoader
:
ConsoleNote
.
class
.
getClassLoader
(),
ClassFilter
.
DEFAULT
))
{
return
(
ConsoleNote
)
ois
.
readObject
(
);
return
getConsoleNote
(
ois
);
}
}
catch
(
Error
e
)
{
// for example, bogus 'sz' can result in OutOfMemoryError.
...
...
@@ -284,6 +285,11 @@ public abstract class ConsoleNote<T> implements Serializable, Describable<Consol
}
}
@SuppressFBWarnings
(
value
=
"OBJECT_DESERIALIZATION"
,
justification
=
"Deserialization is protected by logic."
)
private
static
ConsoleNote
getConsoleNote
(
ObjectInputStream
ois
)
throws
IOException
,
ClassNotFoundException
{
return
(
ConsoleNote
)
ois
.
readObject
();
}
/**
* Skips the encoded console note.
*/
...
...
core/src/main/java/hudson/scheduler/Hash.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,8 @@
*/
package
hudson.scheduler
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
java.nio.charset.StandardCharsets
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
...
...
@@ -54,7 +56,7 @@ public abstract class Hash {
public
static
Hash
from
(
String
seed
)
{
try
{
MessageDigest
md5
=
MessageDigest
.
getInstance
(
"MD5"
);
MessageDigest
md5
=
getMd5
(
);
md5
.
update
(
seed
.
getBytes
(
StandardCharsets
.
UTF_8
));
byte
[]
digest
=
md5
.
digest
();
...
...
@@ -77,6 +79,12 @@ public abstract class Hash {
}
}
// TODO JENKINS-60563 remove MD5 from all usages in Jenkins
@SuppressFBWarnings
(
value
=
"WEAK_MESSAGE_DIGEST_MD5"
,
justification
=
"Should not be used for security."
)
private
static
MessageDigest
getMd5
()
throws
NoSuchAlgorithmException
{
return
MessageDigest
.
getInstance
(
"MD5"
);
}
/**
* Creates a hash that always return 0.
*/
...
...
core/src/main/java/hudson/security/BasicAuthenticationFilter.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.security
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.model.User
;
import
jenkins.model.Jenkins
;
import
hudson.util.Scrambler
;
...
...
@@ -162,8 +163,7 @@ public class BasicAuthenticationFilter implements Filter {
path
+=
'?'
+
q
;
// prepare a redirect
rsp
.
setStatus
(
HttpServletResponse
.
SC_MOVED_TEMPORARILY
);
rsp
.
setHeader
(
"Location"
,
path
);
prepareRedirect
(
rsp
,
path
);
// ... but first let the container authenticate this request
RequestDispatcher
d
=
servletContext
.
getRequestDispatcher
(
"/j_security_check?j_username="
+
...
...
@@ -171,6 +171,12 @@ public class BasicAuthenticationFilter implements Filter {
d
.
include
(
req
,
rsp
);
}
@SuppressFBWarnings
(
value
=
"UNVALIDATED_REDIRECT"
,
justification
=
"Redirect is validated as processed."
)
private
void
prepareRedirect
(
HttpServletResponse
rsp
,
String
path
)
{
rsp
.
setStatus
(
HttpServletResponse
.
SC_MOVED_TEMPORARILY
);
rsp
.
setHeader
(
"Location"
,
path
);
}
//public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// HttpServletRequest req = (HttpServletRequest) request;
// String authorization = req.getHeader("Authorization");
...
...
core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.security
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.Functions
;
import
com.google.common.base.Strings
;
...
...
@@ -100,15 +101,7 @@ public class HudsonAuthenticationEntryPoint extends AuthenticationProcessingFilt
}
catch
(
IllegalStateException
e
)
{
out
=
rsp
.
getWriter
();
}
out
.
printf
(
"<html><head>"
+
"<meta http-equiv='refresh' content='1;url=%1$s'/>"
+
"<script>window.location.replace('%1$s');</script>"
+
"</head>"
+
"<body style='background-color:white; color:white;'>%n"
+
"%n%n"
+
"Authentication required%n"
+
"<!--%n"
,
loginForm
);
printResponse
(
loginForm
,
out
);
if
(
cause
!=
null
)
cause
.
report
(
out
);
...
...
@@ -123,4 +116,17 @@ public class HudsonAuthenticationEntryPoint extends AuthenticationProcessingFilt
out
.
close
();
}
}
@SuppressFBWarnings
(
value
=
"XSS_SERVLET"
,
justification
=
"Intermediate step for redirecting users to login page."
)
private
void
printResponse
(
String
loginForm
,
PrintWriter
out
)
{
out
.
printf
(
"<html><head>"
+
"<meta http-equiv='refresh' content='1;url=%1$s'/>"
+
"<script>window.location.replace('%1$s');</script>"
+
"</head>"
+
"<body style='background-color:white; color:white;'>%n"
+
"%n%n"
+
"Authentication required%n"
+
"<!--%n"
,
loginForm
);
}
}
core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java
浏览文件 @
9ba18f5d
...
...
@@ -490,7 +490,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea
}
}
@Restricted
(
NoExternalUse
.
class
)
@Restricted
(
NoExternalUse
.
class
)
// _entryForm.jelly and signup.jelly
public
boolean
isMailerPluginPresent
()
{
try
{
// mail support has moved to a separate plugin
...
...
core/src/main/java/hudson/util/ConsistentHash.java
浏览文件 @
9ba18f5d
...
...
@@ -26,6 +26,7 @@ package hudson.util;
import
java.lang.RuntimeException
;
import
java.security.GeneralSecurityException
;
import
java.security.MessageDigest
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
...
...
@@ -33,6 +34,7 @@ import java.util.Collection;
import
java.util.Iterator
;
import
java.util.NoSuchElementException
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.util.Iterators.DuplicateFilterIterator
;
/**
...
...
@@ -290,7 +292,7 @@ public class ConsistentHash<T> {
*/
private
int
md5
(
String
s
)
{
try
{
MessageDigest
md5
=
MessageDigest
.
getInstance
(
"MD5"
);
MessageDigest
md5
=
getMd5
(
);
md5
.
update
(
s
.
getBytes
());
byte
[]
digest
=
md5
.
digest
();
...
...
@@ -303,6 +305,12 @@ public class ConsistentHash<T> {
}
}
// TODO JENKINS-60563 remove MD5 from all usages in Jenkins
@SuppressFBWarnings
(
value
=
"WEAK_MESSAGE_DIGEST_MD5"
,
justification
=
"Not used for security."
)
private
MessageDigest
getMd5
()
throws
NoSuchAlgorithmException
{
return
MessageDigest
.
getInstance
(
"MD5"
);
}
/**
* unsigned byte->int.
*/
...
...
core/src/main/java/hudson/util/DOSToUnixPathHelper.java
浏览文件 @
9ba18f5d
package
hudson.util
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.EnvVars
;
import
hudson.Util
;
import
org.kohsuke.accmod.Restricted
;
...
...
@@ -17,19 +18,23 @@ class DOSToUnixPathHelper {
void
validate
(
File
fexe
);
}
static
private
boolean
checkPrefix
(
String
prefix
,
Helper
helper
)
{
File
f
=
new
File
(
prefix
);
File
f
=
construct
File
(
prefix
);
if
(
f
.
exists
())
{
helper
.
checkExecutable
(
f
);
return
true
;
}
File
fexe
=
new
File
(
prefix
+
".exe"
);
File
fexe
=
construct
File
(
prefix
+
".exe"
);
if
(
fexe
.
exists
())
{
helper
.
checkExecutable
(
fexe
);
return
true
;
}
return
false
;
}
@SuppressFBWarnings
(
value
=
"PATH_TRAVERSAL_IN"
,
justification
=
"Limited use for locating shell executable by administrator."
)
private
static
File
constructFile
(
String
prefix
)
{
return
new
File
(
prefix
);
}
static
void
iteratePath
(
String
exe
,
Helper
helper
)
{
exe
=
fixEmpty
(
exe
);
if
(
exe
==
null
)
{
...
...
core/src/main/java/hudson/util/FormFieldValidator.java
浏览文件 @
9ba18f5d
...
...
@@ -23,6 +23,7 @@
*/
package
hudson.util
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.FilePath
;
import
hudson.ProxyConfiguration
;
import
hudson.Util
;
...
...
@@ -145,6 +146,7 @@ public abstract class FormFieldValidator {
/**
* Gets the parameter as a file.
*/
@SuppressFBWarnings
(
value
=
"PATH_TRAVERSAL_IN"
,
justification
=
"Not used."
)
protected
final
File
getFileParameter
(
String
paramName
)
{
return
new
File
(
Util
.
fixNull
(
request
.
getParameter
(
paramName
)));
}
...
...
@@ -329,7 +331,7 @@ public abstract class FormFieldValidator {
try
{
URL
url
=
new
URL
(
value
);
HttpURLConnection
con
=
(
HttpURLConnection
)
url
.
openConnection
(
);
HttpURLConnection
con
=
openConnection
(
url
);
con
.
connect
();
if
(
con
.
getResponseCode
()!=
200
||
con
.
getHeaderField
(
"X-Hudson"
)==
null
)
{
...
...
@@ -342,6 +344,11 @@ public abstract class FormFieldValidator {
handleIOException
(
value
,
e
);
}
}
@SuppressFBWarnings
(
value
=
"URLCONNECTION_SSRF_FD"
,
justification
=
"Not used."
)
private
HttpURLConnection
openConnection
(
URL
url
)
throws
IOException
{
return
(
HttpURLConnection
)
url
.
openConnection
();
}
}
/**
...
...
core/src/main/java/jenkins/InitReactorRunner.java
浏览文件 @
9ba18f5d
...
...
@@ -4,10 +4,12 @@ import com.google.common.collect.Lists;
import
jenkins.util.SystemProperties
;
import
hudson.init.InitMilestone
;
import
hudson.init.InitReactorListener
;
import
hudson.security.ACL
;
import
hudson.util.DaemonThreadFactory
;
import
hudson.util.NamingThreadFactory
;
import
jenkins.model.Configuration
;
import
jenkins.model.Jenkins
;
import
jenkins.security.ImpersonatingExecutorService
;
import
org.jvnet.hudson.reactor.Milestone
;
import
org.jvnet.hudson.reactor.Reactor
;
import
org.jvnet.hudson.reactor.ReactorException
;
...
...
@@ -45,7 +47,7 @@ public class InitReactorRunner {
else
es
=
Executors
.
newSingleThreadExecutor
(
new
NamingThreadFactory
(
new
DaemonThreadFactory
(),
"InitReactorRunner"
));
try
{
reactor
.
execute
(
es
,
buildReactorListener
());
reactor
.
execute
(
new
ImpersonatingExecutorService
(
es
,
ACL
.
SYSTEM
),
buildReactorListener
());
}
finally
{
es
.
shutdownNow
();
// upon a successful return the executor queue should be empty. Upon an exception, we want to cancel all pending tasks
}
...
...
core/src/main/java/jenkins/model/RunIdMigrator.java
浏览文件 @
9ba18f5d
...
...
@@ -24,6 +24,7 @@
package
jenkins.model
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.Extension
;
import
hudson.Util
;
import
hudson.model.Job
;
...
...
@@ -313,13 +314,19 @@ public final class RunIdMigrator {
if
(
args
.
length
!=
1
)
{
throw
new
Exception
(
"pass one parameter, $JENKINS_HOME"
);
}
File
root
=
new
File
(
args
[
0
]);
File
root
=
construct
File
(
args
[
0
]);
File
jobs
=
new
File
(
root
,
"jobs"
);
if
(!
jobs
.
isDirectory
())
{
throw
new
FileNotFoundException
(
"no such $JENKINS_HOME "
+
root
);
}
new
RunIdMigrator
().
unmigrateJobsDir
(
jobs
);
}
@SuppressFBWarnings
(
value
=
"PATH_TRAVERSAL_IN"
,
justification
=
"Only invoked from the command line as a standalone utility"
)
private
static
File
constructFile
(
String
arg
)
{
return
new
File
(
arg
);
}
private
void
unmigrateJobsDir
(
File
jobs
)
throws
Exception
{
File
[]
jobDirs
=
jobs
.
listFiles
();
if
(
jobDirs
==
null
)
{
...
...
core/src/main/java/jenkins/model/identity/IdentityRootAction.java
浏览文件 @
9ba18f5d
package
jenkins.model.identity
;
import
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
;
import
hudson.Extension
;
import
hudson.model.UnprotectedRootAction
;
import
java.security.MessageDigest
;
...
...
@@ -61,6 +62,7 @@ public class IdentityRootAction implements UnprotectedRootAction {
*
* @return the fingerprint of the public key.
*/
@SuppressFBWarnings
(
value
=
"WEAK_MESSAGE_DIGEST_MD5"
,
justification
=
"Not used for security. "
)
public
String
getFingerprint
()
{
RSAPublicKey
key
=
InstanceIdentityProvider
.
RSA
.
getPublicKey
();
if
(
key
==
null
)
{
...
...
@@ -68,7 +70,7 @@ public class IdentityRootAction implements UnprotectedRootAction {
}
// TODO replace with org.jenkinsci.remoting.util.KeyUtils once JENKINS-36871 changes are merged
try
{
MessageDigest
digest
=
MessageDigest
.
getInstance
(
"MD5"
);
MessageDigest
digest
=
getMd5
(
);
digest
.
reset
();
byte
[]
bytes
=
digest
.
digest
(
key
.
getEncoded
());
StringBuilder
result
=
new
StringBuilder
(
Math
.
max
(
0
,
bytes
.
length
*
3
-
1
));
...
...
@@ -84,4 +86,10 @@ public class IdentityRootAction implements UnprotectedRootAction {
throw
new
IllegalStateException
(
"JLS mandates MD5 support"
);
}
}
// TODO JENKINS-60563 remove MD5 from all usages in Jenkins
@SuppressFBWarnings
(
value
=
"WEAK_MESSAGE_DIGEST_MD5"
,
justification
=
"Not used for security. "
)
private
MessageDigest
getMd5
()
throws
NoSuchAlgorithmException
{
return
MessageDigest
.
getInstance
(
"MD5"
);
}
}
core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java
浏览文件 @
9ba18f5d
...
...
@@ -111,7 +111,7 @@ public class JnlpSlaveAgentProtocol4 extends AgentProtocol {
// prepare our keyStore so we can provide our authentication
keyStore
=
KeyStore
.
getInstance
(
"JKS"
);
char
[]
password
=
"password"
.
toCharArray
();
char
[]
password
=
constructPassword
();
try
{
keyStore
.
load
(
null
,
password
);
}
catch
(
IOException
e
)
{
...
...
@@ -146,6 +146,10 @@ public class JnlpSlaveAgentProtocol4 extends AgentProtocol {
sslContext
.
init
(
kmf
.
getKeyManagers
(),
trustManagers
,
null
);
}
private
char
[]
constructPassword
()
{
return
"password"
.
toCharArray
();
}
/**
* Inject the {@link IOHubProvider}
*
...
...
@@ -182,7 +186,7 @@ public class JnlpSlaveAgentProtocol4 extends AgentProtocol {
LOGGER
.
log
(
Level
.
INFO
,
"Updating {0} TLS certificate to retain validity"
,
getName
());
X509Certificate
identityCertificate
=
InstanceIdentityProvider
.
RSA
.
getCertificate
();
RSAPrivateKey
privateKey
=
InstanceIdentityProvider
.
RSA
.
getPrivateKey
();
char
[]
password
=
"password"
.
toCharArray
();
char
[]
password
=
constructPassword
();
keyStore
.
setKeyEntry
(
"jenkins"
,
privateKey
,
password
,
new
X509Certificate
[]{
identityCertificate
});
}
}
catch
(
KeyStoreException
e
)
{
...
...
core/src/main/resources/hudson/model/View/AsynchPeople/index.jelly
浏览文件 @
9ba18f5d
...
...
@@ -100,7 +100,7 @@ THE SOFTWARE.
<l:progressiveRendering handler="${it}" callback="display"/>
<table class="sortable pane bigtable" id="people">
<tr>
<th />
<th
class="minimum-width"
/>
<th>${%User ID}</th>
<th>${%Name}</th>
<th initialSortDir="up">${%Last Commit Activity}</th>
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly
浏览文件 @
9ba18f5d
...
...
@@ -24,23 +24,41 @@ THE SOFTWARE.
<!-- tag file used by both signup.jelly and addUser.jelly -->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
<st:documentation>
<st:attribute name="it" use="required" type="hudson.security.HudsonPrivateSecurityRealm">
Context where the page is loaded.
</st:attribute>
<st:attribute name="title" use="required">
Title of the HTML page. Rendered in the page content inside a <h1>.
</st:attribute>
<st:attribute name="action" use="required">
The method to call from within the HudsonPrivateSecurityRealm.
</st:attribute>
<st:attribute name="captcha" use="optional">
Determines if the tag will include the captcha.
</st:attribute>
<st:attribute name="data" use="optional" type="hudson.security.HudsonPrivateSecurityRealm.SignupInfo">
The wrapper for the data provided by the user and the error message(s) if any. Is null on first form display.
</st:attribute>
</st:documentation>
<h1>${title}</h1>
<div
style="margin: 2em;
">
<div
class="form-content
">
<j:if test="${data.errorMessage!=null}">
<div class="error"
style="margin-bottom:1em"
>
<div class="error">
${data.errorMessage}
</div>
</j:if>
<j:forEach var="error" items="${data.errors}">
<div class="error"
style="margin-bottom:1em"
>
<div class="error">
${error.value}
</div>
</j:forEach>
<table>
<tr>
<td>${%Username}:</td>
<td><input type="text" name="username" id="username" value="${data.username}" /></td>
<td><input type="text" name="username" id="username" value="${data.username}"
autofocus="autofocus"
/></td>
</tr>
<tr>
<td>${%Password}:</td>
...
...
@@ -65,7 +83,7 @@ THE SOFTWARE.
<td>${%Enter text as shown}:</td>
<td>
<input type="text" name="captcha" autocomplete="off" /><br />
<img src="${rootURL}/securityRealm/captcha" alt="[${%captcha}]"/>
<img src="${rootURL}/securityRealm/captcha" alt="[${%captcha}]"
/>
</td>
</tr>
</j:if>
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage.jelly
浏览文件 @
9ba18f5d
...
...
@@ -22,28 +22,36 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<!-- tag file used by
both signup.jelly and add
User.jelly -->
<!-- tag file used by
signupWithFederatedIdentity.jelly, addUser.jelly and first
User.jelly -->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form" xmlns:local="/hudson/security/HudsonPrivateSecurityRealm">
<st:documentation>
<st:attribute name="host" use="required" type="hudson.security.HudsonPrivateSecurityRealm">
Corresponds to the "it" of Jelly, meaning the context where the page is loaded.
</st:attribute>
<st:attribute name="title" use="required">
Title of the HTML page.
Rendered into <title> tag, in the page content inside a <h1> and as the label of the submit button.
</st:attribute>
<st:attribute name="action" use="required">
The method to call from within the HudsonPrivateSecurityRealm.
</st:attribute>
<st:attribute name="captcha" use="optional" type="boolean">
Determines if the tag will include the captcha.
</st:attribute>
<st:attribute name="data" use="optional" type="hudson.security.HudsonPrivateSecurityRealm.SignupInfo">
The wrapper for the data provided by the user and the error message(s) if any. Is null on first form display.
</st:attribute>
</st:documentation>
<l:layout norefresh="true" title="${title}">
<l:header>
<style>
<!-- match width with captcha image -->
INPUT {
width:200px;
}
</style>
</l:header>
<st:adjunct includes="hudson.security.HudsonPrivateSecurityRealm._entryFormPage.resources" />
<l:hasPermission permission="${app.READ}" it="${host}">
<st:include page="sidepanel.jelly" it="${host}" />
</l:hasPermission>
<l:main-panel>
<form action="${rootURL}/securityRealm/${action}" method="post"
style="text-size:smaller"
>
<local:_entryForm title="${title}" action="${action}" captcha="${captcha}"
xmlns:local="/hudson/security/HudsonPrivateSecurityRealm
" />
<form action="${rootURL}/securityRealm/${action}" method="post">
<local:_entryForm title="${title}" action="${action}" captcha="${captcha}"
it="${host}" data="${data}
" />
<f:submit value="${title}" />
<script>
$('username').focus();
</script>
</form>
</l:main-panel>
</l:layout>
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage/resources.css
0 → 100644
浏览文件 @
9ba18f5d
input
{
/* match width with captcha image */
width
:
200px
;
}
.form-content
{
margin
:
2em
;
}
.form-content
.error
{
margin-bottom
:
1em
;
}
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly
浏览文件 @
9ba18f5d
...
...
@@ -26,6 +26,6 @@ THE SOFTWARE.
Page for admin to create a new user
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:
st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/for
m">
<local:_entryFormPage host="${it}" title="${%Create User}" action="createAccountByAdmin" captcha="${false}"
xmlns:local="/hudson/security/HudsonPrivateSecurityRealm
" />
<j:jelly xmlns:j="jelly:core" xmlns:
local="/hudson/security/HudsonPrivateSecurityReal
m">
<local:_entryFormPage host="${it}" title="${%Create User}" action="createAccountByAdmin" captcha="${false}"
data="${data}
" />
</j:jelly>
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config.jelly
浏览文件 @
9ba18f5d
...
...
@@ -23,8 +23,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson"
xmlns:f="/lib/form">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:f="/lib/form">
<f:entry field="allowsSignup">
<f:checkbox default="false" title="${%Allow users to sign up}" />
</f:entry>
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly
浏览文件 @
9ba18f5d
...
...
@@ -26,6 +26,6 @@ THE SOFTWARE.
This is used to create the first user.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:
st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/for
m">
<local:_entryFormPage host="${it}" title="${%Create First Admin User}" action="createFirstAccount" captcha="${false}"
xmlns:local="/hudson/security/HudsonPrivateSecurityRealm"
/>
<j:jelly xmlns:j="jelly:core" xmlns:
local="/hudson/security/HudsonPrivateSecurityReal
m">
<local:_entryFormPage host="${it}" title="${%Create First Admin User}" action="createFirstAccount" captcha="${false}"
data="${data}"
/>
</j:jelly>
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly
浏览文件 @
9ba18f5d
...
...
@@ -23,7 +23,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form
">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
l="/lib/layout
">
<l:layout permission="${app.ADMINISTER}" title="${%Users}">
<st:include page="sidepanel.jelly" />
<l:main-panel>
...
...
@@ -32,20 +32,20 @@ THE SOFTWARE.
<table class="sortable pane bigtable" id="people">
<tr>
<th
style="width:32px"
/>
<th
class="minimum-width"
/>
<th>${%User ID}</th>
<th>${%Name}</th>
<th
style="width:32px"
/>
<th
class="minimum-width"
/>
</tr>
<j:forEach var="user" items="${it.allUsers}">
<tr>
<td><a href="${user.url}/" class="model-link inside"><img src="${h.getUserAvatar(user,'32x32')}" alt="" height="32" width="32"/></a></td>
<td><a href="${user.url}/" class="model-link inside"><img src="${h.getUserAvatar(user,'32x32')}" alt="" height="32" width="32"
/></a></td>
<td><a href="${user.url}/">${user.id}</a></td>
<td><a href="${user.url}/">${user}</a></td>
<td>
<a href="${user.url}/configure"><l:icon class="icon-gear2 icon-lg"/></a>
<a href="${user.url}/configure"><l:icon class="icon-gear2 icon-lg"
/></a>
<j:if test="${user.canDelete()}">
<a href="${user.url}/delete"><l:icon class="icon-edit-delete icon-md"/></a>
<a href="${user.url}/delete"><l:icon class="icon-edit-delete icon-md"
/></a>
</j:if>
</td>
</tr>
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink.jelly
浏览文件 @
9ba18f5d
...
...
@@ -23,7 +23,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler"
xmlns:d="jelly:define" xmlns:l="/lib/layout"
>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
<st:include page="/hudson/security/SecurityRealm/loginLink.jelly" />
<j:if test="${it.allowsSignup()}">
|
...
...
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly
浏览文件 @
9ba18f5d
...
...
@@ -23,13 +23,13 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:
st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:s="/lib/form
">
<j:jelly xmlns:j="jelly:core" xmlns:
l="/lib/layout
">
<l:header />
<l:side-panel>
<l:tasks>
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"/>
<l:task href="${rootURL}/manage" icon="icon-gear2 icon-md" permission="${app.MANAGE}" title="${%Manage Jenkins}"/>
<l:task href="addUser" icon="icon-new-user icon-md" permission="${app.ADMINISTER}" title="${%Create User}"/>
<l:task href="${rootURL}/" icon="icon-up icon-md" title="${%Back to Dashboard}"
/>
<l:task href="${rootURL}/manage" icon="icon-gear2 icon-md" permission="${app.MANAGE}" title="${%Manage Jenkins}"
/>
<l:task href="addUser" icon="icon-new-user icon-md" permission="${app.ADMINISTER}" title="${%Create User}"
/>
</l:tasks>
</l:side-panel>
</j:jelly>
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly
浏览文件 @
9ba18f5d
...
...
@@ -26,6 +26,6 @@ THE SOFTWARE.
User self sign up page.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:
st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/for
m">
<local:_entryFormPage host="${app}" title="${%Sign up}" action="createAccountWithFederatedIdentity" captcha="${true}"
xmlns:local="/hudson/security/HudsonPrivateSecurityRealm
" />
<j:jelly xmlns:j="jelly:core" xmlns:
local="/hudson/security/HudsonPrivateSecurityReal
m">
<local:_entryFormPage host="${app}" title="${%Sign up}" action="createAccountWithFederatedIdentity" captcha="${true}"
data="${data}
" />
</j:jelly>
core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success.jelly
浏览文件 @
9ba18f5d
...
...
@@ -23,7 +23,7 @@ THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form
">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
l="/lib/layout
">
<l:layout norefresh="true">
<l:hasPermission permission="${app.READ}" it="${app}">
<st:include page="sidepanel.jelly" it="${app}" />
...
...
core/src/main/resources/hudson/security/SecurityRealm/signup.jelly
浏览文件 @
9ba18f5d
...
...
@@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fm
t">
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:
l="/lib/layou
t">
<st:statusCode value="404" />
<st:include page="sidepanel.jelly" from="${app}" it="${app}" />
<l:layout title="${%Signup not supported}">
...
...
core/src/main/resources/lib/layout/hasPermission.jelly
浏览文件 @
9ba18f5d
...
...
@@ -26,7 +26,13 @@ THE SOFTWARE.
<j:jelly xmlns:j="jelly:core" xmlns:d="jelly:define" xmlns:st="jelly:stapler">
<st:documentation>
Renders the body only if the current user has the specified permission
<st:attribute name="permission" use="required" type="Permission">
<st:attribute name="it" use="optional">
By default it will reuse the current context.
If the provided value does not inherit from hudson.security.AccessControlled,
the tag will look for the first ancestor satisfying the condition.
The hasPermission will be performed against that value.
</st:attribute>
<st:attribute name="permission" use="required" type="hudson.security.Permission">
permission object to check. If this is null, the body will be also rendered.
</st:attribute>
</st:documentation>
...
...
core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java
浏览文件 @
9ba18f5d
...
...
@@ -27,8 +27,11 @@ import hudson.util.XStream2;
import
org.apache.commons.io.IOUtils
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.xmlunit.diff.DefaultNodeMatcher
;
import
org.xmlunit.diff.ElementSelectors
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
xmlunit
.
matchers
.
CompareMatcher
.
isSimilarTo
;
import
java.io.IOException
;
import
java.io.InputStream
;
...
...
@@ -62,7 +65,8 @@ public class XStreamDOMTest {
Foo
foo
=
createSomeFoo
();
String
xml
=
xs
.
toXML
(
foo
);
System
.
out
.
println
(
xml
);
assertEquals
(
getTestData1
().
trim
(),
xml
.
trim
());
assertThat
(
getTestData1
().
trim
(),
isSimilarTo
(
xml
.
trim
()).
ignoreWhitespace
()
.
withNodeMatcher
(
new
DefaultNodeMatcher
(
ElementSelectors
.
byNameAndText
)));
}
private
String
getTestData1
()
throws
IOException
{
...
...
@@ -100,7 +104,8 @@ public class XStreamDOMTest {
String
xml
=
xs
.
toXML
(
foo
);
System
.
out
.
println
(
xml
);
assertEquals
(
getTestData1
().
trim
(),
xml
.
trim
());
assertThat
(
getTestData1
().
trim
(),
isSimilarTo
(
xml
.
trim
()).
ignoreWhitespace
()
.
withNodeMatcher
(
new
DefaultNodeMatcher
(
ElementSelectors
.
byNameAndText
)));
}
@Test
...
...
pom.xml
浏览文件 @
9ba18f5d
...
...
@@ -407,6 +407,20 @@ THE SOFTWARE.
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
animal-sniffer-maven-plugin
</artifactId>
</plugin>
<plugin>
<groupId>
com.github.spotbugs
</groupId>
<artifactId>
spotbugs-maven-plugin
</artifactId>
<configuration>
<plugins>
<plugin>
<groupId>
com.h3xstream.findsecbugs
</groupId>
<artifactId>
findsecbugs-plugin
</artifactId>
<version>
1.10.1
</version>
</plugin>
</plugins>
<maxHeap>
768
</maxHeap>
</configuration>
</plugin>
</plugins>
</pluginManagement>
...
...
src/findbugs/findbugs-excludes.xml
浏览文件 @
9ba18f5d
...
...
@@ -13,4 +13,12 @@
<Bug
pattern=
"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"
/>
</Or>
</Match>
<Match>
<!--We don't care about this behavior.-->
<Bug
pattern=
"CRLF_INJECTION_LOGS"
/>
</Match>
<Match>
<!--Jenkins handles this issue differently or doesn't care about it.-->
<Bug
pattern=
"INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE"
/>
</Match>
</FindBugsFilter>
test/src/test/java/hudson/PluginManagerTest.java
浏览文件 @
9ba18f5d
...
...
@@ -503,6 +503,18 @@ public class PluginManagerTest {
}
}
@Issue
(
"JENKINS-61071"
)
@Test
public
void
requireSystemInInitializer
()
throws
Exception
{
r
.
jenkins
.
setSecurityRealm
(
r
.
createDummySecurityRealm
());
r
.
jenkins
.
setAuthorizationStrategy
(
new
MockAuthorizationStrategy
());
String
pluginShortName
=
"require-system-in-initializer"
;
dynamicLoad
(
pluginShortName
+
".jpi"
);
try
(
ACLContext
context
=
ACL
.
as
(
User
.
getById
(
"underprivileged"
,
true
).
impersonate
()))
{
r
.
jenkins
.
pluginManager
.
start
(
Collections
.
singletonList
(
r
.
jenkins
.
pluginManager
.
getPlugin
(
pluginShortName
)));
}
}
private
void
dynamicLoad
(
String
plugin
)
throws
IOException
,
InterruptedException
,
RestartRequiredException
{
PluginManagerUtil
.
dynamicLoad
(
plugin
,
r
.
jenkins
);
}
...
...
test/src/test/resources/plugins/require-system-in-initializer.jpi
0 → 100644
浏览文件 @
9ba18f5d
文件已添加
war/pom.xml
浏览文件 @
9ba18f5d
...
...
@@ -360,7 +360,7 @@ THE SOFTWARE.
<artifactItem>
<groupId>
org.jenkins-ci.plugins
</groupId>
<artifactId>
script-security
</artifactId>
<version>
1.
68
</version>
<version>
1.
70
</version>
<type>
hpi
</type>
</artifactItem>
<artifactItem>
...
...
war/src/main/webapp/css/style.css
浏览文件 @
9ba18f5d
...
...
@@ -522,6 +522,10 @@ table.bigtable.pane > tbody > tr > td:last-child {
white-space
:
nowrap
;
}
.bigtable
th
.minimum-width
{
width
:
1px
;
}
.bigtable
td
{
vertical-align
:
middle
;
padding
:
3px
4px
3px
4px
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录