{"action":"created","comment":{"url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments/139002192","pull_request_review_id":62876198,"id":139002192,"diff_hunk":"@@ -596,12 +596,6 @@ THE SOFTWARE.\n       <version>1.3.1-jenkins-1</version>\n     </dependency>\n \n-    <dependency>","path":"core/pom.xml","position":4,"original_position":4,"commit_id":"1784f90806c1c1f39e307c722a3dd4f63850877e","original_commit_id":"1784f90806c1c1f39e307c722a3dd4f63850877e","user":{"login":"jglick","id":154109,"avatar_url":"https://avatars1.githubusercontent.com/u/154109?v=4","gravatar_id":"","url":"https://api.github.com/users/jglick","html_url":"https://github.com/jglick","followers_url":"https://api.github.com/users/jglick/followers","following_url":"https://api.github.com/users/jglick/following{/other_user}","gists_url":"https://api.github.com/users/jglick/gists{/gist_id}","starred_url":"https://api.github.com/users/jglick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jglick/subscriptions","organizations_url":"https://api.github.com/users/jglick/orgs","repos_url":"https://api.github.com/users/jglick/repos","events_url":"https://api.github.com/users/jglick/events{/privacy}","received_events_url":"https://api.github.com/users/jglick/received_events","type":"User","site_admin":false},"body":"There _are_ usages of JBCrypt in core. They now use the transitive dependency as far as the Maven compiler plugin is concerned. From the perspective of runtime class loading, it means there is just one `jenkins.war!/WEB-INF/lib/jbcrypt-*.jar` rather than two.","created_at":"2017-09-14T20:25:53Z","updated_at":"2017-09-14T20:25:53Z","html_url":"https://github.com/jenkinsci/jenkins/pull/3026#discussion_r139002192","pull_request_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments/139002192"},"html":{"href":"https://github.com/jenkinsci/jenkins/pull/3026#discussion_r139002192"},"pull_request":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026"}},"in_reply_to_id":139001500},"pull_request":{"url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026","id":141145704,"html_url":"https://github.com/jenkinsci/jenkins/pull/3026","diff_url":"https://github.com/jenkinsci/jenkins/pull/3026.diff","patch_url":"https://github.com/jenkinsci/jenkins/pull/3026.patch","issue_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/3026","number":3026,"state":"open","locked":false,"title":"[JENKINS-46754] Remove org.mindrot:jbcrypt:0.4 since we already bundle org.connectbot.jbcrypt:jbcrypt:1.0.0","user":{"login":"jglick","id":154109,"avatar_url":"https://avatars1.githubusercontent.com/u/154109?v=4","gravatar_id":"","url":"https://api.github.com/users/jglick","html_url":"https://github.com/jglick","followers_url":"https://api.github.com/users/jglick/followers","following_url":"https://api.github.com/users/jglick/following{/other_user}","gists_url":"https://api.github.com/users/jglick/gists{/gist_id}","starred_url":"https://api.github.com/users/jglick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jglick/subscriptions","organizations_url":"https://api.github.com/users/jglick/orgs","repos_url":"https://api.github.com/users/jglick/repos","events_url":"https://api.github.com/users/jglick/events{/privacy}","received_events_url":"https://api.github.com/users/jglick/received_events","type":"User","site_admin":false},"body":"See [JENKINS-46754](https://issues.jenkins-ci.org/browse/JENKINS-46754).\r\n\r\nIn a nutshell, `jenkins.war` was accidentally bundling two distinct versions of the same library, under different GAs (so, invisibly to Maven). There are three GAs packaging the [JBCrypt library](http://www.mindrot.org/projects/jBCrypt/) that I know of:\r\n\r\n* `org.mindrot:jbcrypt`, apparently an unauthorized upload from https://github.com/djmdjm/jBCrypt/pull/1.\r\n* `de.svenkubiak:jBCrypt`, considered during SECURITY-354 but rejected since it required Java 8 to run, inappropriate for a security advisory.\r\n* `org.connectbot.jbcrypt:jbcrypt`, which seems to have forked the library and done some additional development.\r\n\r\nWhile I knew of the existence of the ConnectBot packaging when filing #2964, I did not realize that\r\n\r\n* 1.0.0 is actually different from 0.4; https://github.com/kruton/jbcrypt/commit/37a5a774565b7eaf9e58f0fadba1291a3a06649f adds some new APIs.\r\n* We were already bundling the ConnectBot fork! Since https://github.com/jenkinsci/trilead-ssh2/commit/dac7b1bdc80a845337a2a692a8e4f4cee8d19a1f and https://github.com/jenkinsci/trilead-ssh2/commit/30dbd420e6125a5d11fbc1426ece43949c34fb22 our “fork” of Trilead (at this point I guess the authoritative version) depends on those new APIs to decrypt certain kinds of keys. And Maven in its infinite wisdom was pulling that in as a transitive dependency.\r\n\r\nNow when the WAR bundles two JAR files containing classes with the same FQN, the servlet container has to decide which one to load. As far as I can tell, Jetty does so essentially randomly, on the basis of the order of `File.list`, basically the directory iterator from the OS kernel. So if you were lucky, it would pick the ConnectBot version, which Trilead could link against, and all is well. If you were in the unlucky 50%, it would pick the older Mindrot version, which Trilead would fail to link against. I am adding a test here which detects this kind of mistake, but there are too many other failures to enable it yet. I plan to attempt to patch Jetty to make its load order deterministic.\r\n\r\nThanks @MarkEWaite for discovering. His test cases are run semi-manually; I plan to attempt to reproduce the issue (at least 50% of the time!) in `acceptance-test-harness`. (`JenkinsRule` would not suffice since then a version of JBCrypt would be loaded from `${java.class.path}`, deterministic according to Maven POMs: [JENKINS-41827](https://issues.jenkins-ci.org/browse/JENKINS-41827).)\r\n\r\nI also note that in the case of the SSH launcher at least, the error is reported to the system log rather than the agent launch log where you might expect it. I plan to fix this in `ssh-credentials` too.\r\n\r\nTimeline:\r\n* [SECURITY-354](https://jenkins.io/security/advisory/2017-02-01/) in Jenkins 2.32.2 / 2.44 replaces Mindrot JBCrypt 0.3 with a repackaged private version of 0.4 for use from `HudsonPrivateSecurityRealm`.\r\n* #2848 in 2.58 updates Trilead to a version relying on the ConnectBot JBCrypt, I suppose causing core to bundle it. Since these use distinct package names there is no conflict.\r\n* #2964 in 2.73 switches to Mindrot 0.4, producing the clash.\r\n\r\nThis fix simply removes the older Mindrot library in favor of the newer ConnectBot fork already in use by Trilead, letting `HudsonPrivateSecurityRealm` share it also. To the objection that we should not be bundling a forked copy of a library where it could be used as an API, I would say\r\n* Yes, though this is hardly the first time Jenkins has done so.\r\n* I can find no direct usages of `BCrypt` from plugins, only Trilead and `HudsonPrivateSecurityRealm`. [This search](https://github.com/search?utf8=%E2%9C%93&q=user%3Ajenkinsci+%22import+org.mindrot.jbcrypt%22&type=Code) turns up just a false positive: https://github.com/jenkinsci/credentials-plugin/pull/91\r\n* We have already been doing so since 2.58. Trying to hide it now, or revert to an older version, would be technically incompatible.\r\n* It is unclear whether there even _is_ an authoritative version of the library. The Mindrot version seems to be moribund, as I asked in https://github.com/kruton/jbcrypt/issues/1. (Ironically, the author @djmdjm of JBCrypt seems to be active in the C version of the exact same thing: https://github.com/openssh/openssh-portable/commit/1ff130dac9b7aea0628f4ad30683431fe35e0020)\r\n\r\nAs an aside: https://github.com/jenkinsci/ssh-credentials-plugin/pull/27\r\n\r\n### Proposed changelog entries\r\n\r\n* Since 2.73, certain uses of passphrase-protected ed25519 private keys would sometimes fail.\r\n\r\n@jenkinsci/code-reviewers @reviewbybees","created_at":"2017-09-14T18:28:57Z","updated_at":"2017-09-14T20:25:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4c15beb645ef9119e62eae6898e0675129488d28","assignee":null,"assignees":[],"requested_reviewers":[{"login":"mc1arke","id":1250331,"avatar_url":"https://avatars2.githubusercontent.com/u/1250331?v=4","gravatar_id":"","url":"https://api.github.com/users/mc1arke","html_url":"https://github.com/mc1arke","followers_url":"https://api.github.com/users/mc1arke/followers","following_url":"https://api.github.com/users/mc1arke/following{/other_user}","gists_url":"https://api.github.com/users/mc1arke/gists{/gist_id}","starred_url":"https://api.github.com/users/mc1arke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mc1arke/subscriptions","organizations_url":"https://api.github.com/users/mc1arke/orgs","repos_url":"https://api.github.com/users/mc1arke/repos","events_url":"https://api.github.com/users/mc1arke/events{/privacy}","received_events_url":"https://api.github.com/users/mc1arke/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026/commits","review_comments_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026/comments","review_comment_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments{/number}","comments_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/3026/comments","statuses_url":"https://api.github.com/repos/jenkinsci/jenkins/statuses/1784f90806c1c1f39e307c722a3dd4f63850877e","head":{"label":"jglick:jbcrypt-JENKINS-46754","ref":"jbcrypt-JENKINS-46754","sha":"1784f90806c1c1f39e307c722a3dd4f63850877e","user":{"login":"jglick","id":154109,"avatar_url":"https://avatars1.githubusercontent.com/u/154109?v=4","gravatar_id":"","url":"https://api.github.com/users/jglick","html_url":"https://github.com/jglick","followers_url":"https://api.github.com/users/jglick/followers","following_url":"https://api.github.com/users/jglick/following{/other_user}","gists_url":"https://api.github.com/users/jglick/gists{/gist_id}","starred_url":"https://api.github.com/users/jglick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jglick/subscriptions","organizations_url":"https://api.github.com/users/jglick/orgs","repos_url":"https://api.github.com/users/jglick/repos","events_url":"https://api.github.com/users/jglick/events{/privacy}","received_events_url":"https://api.github.com/users/jglick/received_events","type":"User","site_admin":false},"repo":{"id":4914128,"name":"jenkins","full_name":"jglick/jenkins","owner":{"login":"jglick","id":154109,"avatar_url":"https://avatars1.githubusercontent.com/u/154109?v=4","gravatar_id":"","url":"https://api.github.com/users/jglick","html_url":"https://github.com/jglick","followers_url":"https://api.github.com/users/jglick/followers","following_url":"https://api.github.com/users/jglick/following{/other_user}","gists_url":"https://api.github.com/users/jglick/gists{/gist_id}","starred_url":"https://api.github.com/users/jglick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jglick/subscriptions","organizations_url":"https://api.github.com/users/jglick/orgs","repos_url":"https://api.github.com/users/jglick/repos","events_url":"https://api.github.com/users/jglick/events{/privacy}","received_events_url":"https://api.github.com/users/jglick/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jglick/jenkins","description":"Jenkins Continuous Integration Server","fork":true,"url":"https://api.github.com/repos/jglick/jenkins","forks_url":"https://api.github.com/repos/jglick/jenkins/forks","keys_url":"https://api.github.com/repos/jglick/jenkins/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jglick/jenkins/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jglick/jenkins/teams","hooks_url":"https://api.github.com/repos/jglick/jenkins/hooks","issue_events_url":"https://api.github.com/repos/jglick/jenkins/issues/events{/number}","events_url":"https://api.github.com/repos/jglick/jenkins/events","assignees_url":"https://api.github.com/repos/jglick/jenkins/assignees{/user}","branches_url":"https://api.github.com/repos/jglick/jenkins/branches{/branch}","tags_url":"https://api.github.com/repos/jglick/jenkins/tags","blobs_url":"https://api.github.com/repos/jglick/jenkins/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jglick/jenkins/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jglick/jenkins/git/refs{/sha}","trees_url":"https://api.github.com/repos/jglick/jenkins/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jglick/jenkins/statuses/{sha}","languages_url":"https://api.github.com/repos/jglick/jenkins/languages","stargazers_url":"https://api.github.com/repos/jglick/jenkins/stargazers","contributors_url":"https://api.github.com/repos/jglick/jenkins/contributors","subscribers_url":"https://api.github.com/repos/jglick/jenkins/subscribers","subscription_url":"https://api.github.com/repos/jglick/jenkins/subscription","commits_url":"https://api.github.com/repos/jglick/jenkins/commits{/sha}","git_commits_url":"https://api.github.com/repos/jglick/jenkins/git/commits{/sha}","comments_url":"https://api.github.com/repos/jglick/jenkins/comments{/number}","issue_comment_url":"https://api.github.com/repos/jglick/jenkins/issues/comments{/number}","contents_url":"https://api.github.com/repos/jglick/jenkins/contents/{+path}","compare_url":"https://api.github.com/repos/jglick/jenkins/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jglick/jenkins/merges","archive_url":"https://api.github.com/repos/jglick/jenkins/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jglick/jenkins/downloads","issues_url":"https://api.github.com/repos/jglick/jenkins/issues{/number}","pulls_url":"https://api.github.com/repos/jglick/jenkins/pulls{/number}","milestones_url":"https://api.github.com/repos/jglick/jenkins/milestones{/number}","notifications_url":"https://api.github.com/repos/jglick/jenkins/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jglick/jenkins/labels{/name}","releases_url":"https://api.github.com/repos/jglick/jenkins/releases{/id}","deployments_url":"https://api.github.com/repos/jglick/jenkins/deployments","created_at":"2012-07-05T19:53:26Z","updated_at":"2017-03-13T23:19:16Z","pushed_at":"2017-09-14T18:47:42Z","git_url":"git://github.com/jglick/jenkins.git","ssh_url":"git@github.com:jglick/jenkins.git","clone_url":"https://github.com/jglick/jenkins.git","svn_url":"https://github.com/jglick/jenkins","homepage":"http://jenkins-ci.org/","size":101119,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"jenkinsci:master","ref":"master","sha":"a2cbd5752eada09fd6eff283742ca8aa97dd6e3b","user":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars0.githubusercontent.com/u/107424?v=4","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"repo":{"id":1103607,"name":"jenkins","full_name":"jenkinsci/jenkins","owner":{"login":"jenkinsci","id":107424,"avatar_url":"https://avatars0.githubusercontent.com/u/107424?v=4","gravatar_id":"","url":"https://api.github.com/users/jenkinsci","html_url":"https://github.com/jenkinsci","followers_url":"https://api.github.com/users/jenkinsci/followers","following_url":"https://api.github.com/users/jenkinsci/following{/other_user}","gists_url":"https://api.github.com/users/jenkinsci/gists{/gist_id}","starred_url":"https://api.github.com/users/jenkinsci/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jenkinsci/subscriptions","organizations_url":"https://api.github.com/users/jenkinsci/orgs","repos_url":"https://api.github.com/users/jenkinsci/repos","events_url":"https://api.github.com/users/jenkinsci/events{/privacy}","received_events_url":"https://api.github.com/users/jenkinsci/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/jenkinsci/jenkins","description":"Jenkins automation server","fork":true,"url":"https://api.github.com/repos/jenkinsci/jenkins","forks_url":"https://api.github.com/repos/jenkinsci/jenkins/forks","keys_url":"https://api.github.com/repos/jenkinsci/jenkins/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jenkinsci/jenkins/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jenkinsci/jenkins/teams","hooks_url":"https://api.github.com/repos/jenkinsci/jenkins/hooks","issue_events_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/events{/number}","events_url":"https://api.github.com/repos/jenkinsci/jenkins/events","assignees_url":"https://api.github.com/repos/jenkinsci/jenkins/assignees{/user}","branches_url":"https://api.github.com/repos/jenkinsci/jenkins/branches{/branch}","tags_url":"https://api.github.com/repos/jenkinsci/jenkins/tags","blobs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jenkinsci/jenkins/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jenkinsci/jenkins/git/refs{/sha}","trees_url":"https://api.github.com/repos/jenkinsci/jenkins/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jenkinsci/jenkins/statuses/{sha}","languages_url":"https://api.github.com/repos/jenkinsci/jenkins/languages","stargazers_url":"https://api.github.com/repos/jenkinsci/jenkins/stargazers","contributors_url":"https://api.github.com/repos/jenkinsci/jenkins/contributors","subscribers_url":"https://api.github.com/repos/jenkinsci/jenkins/subscribers","subscription_url":"https://api.github.com/repos/jenkinsci/jenkins/subscription","commits_url":"https://api.github.com/repos/jenkinsci/jenkins/commits{/sha}","git_commits_url":"https://api.github.com/repos/jenkinsci/jenkins/git/commits{/sha}","comments_url":"https://api.github.com/repos/jenkinsci/jenkins/comments{/number}","issue_comment_url":"https://api.github.com/repos/jenkinsci/jenkins/issues/comments{/number}","contents_url":"https://api.github.com/repos/jenkinsci/jenkins/contents/{+path}","compare_url":"https://api.github.com/repos/jenkinsci/jenkins/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jenkinsci/jenkins/merges","archive_url":"https://api.github.com/repos/jenkinsci/jenkins/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jenkinsci/jenkins/downloads","issues_url":"https://api.github.com/repos/jenkinsci/jenkins/issues{/number}","pulls_url":"https://api.github.com/repos/jenkinsci/jenkins/pulls{/number}","milestones_url":"https://api.github.com/repos/jenkinsci/jenkins/milestones{/number}","notifications_url":"https://api.github.com/repos/jenkinsci/jenkins/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jenkinsci/jenkins/labels{/name}","releases_url":"https://api.github.com/repos/jenkinsci/jenkins/releases{/id}","deployments_url":"https://api.github.com/repos/jenkinsci/jenkins/deployments","created_at":"2010-11-22T21:21:23Z","updated_at":"2017-09-14T08:45:25Z","pushed_at":"2017-09-14T18:49:39Z","git_url":"git://github.com/jenkinsci/jenkins.git","ssh_url":"git@github.com:jenkinsci/jenkins.git","clone_url":"https://github.com/jenkinsci/jenkins.git","svn_url":"https://github.com/jenkinsci/jenkins","homepage":"https://jenkins.io/","size":103034,"stargazers_count":9020,"watchers_count":9020,"language":"Java","has_issues":false,"has_projects":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":3592,"mirror_url":null,"open_issues_count":137,"forks":3592,"open_issues":137,"watchers":9020,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026"},"html":{"href":"https://github.com/jenkinsci/jenkins/pull/3026"},"issue":{"href":"https://api.github.com/repos/jenkinsci/jenkins/issues/3026"},"comments":{"href":"https://api.github.com/repos/jenkinsci/jenkins/issues/3026/comments"},"review_comments":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026/comments"},"review_comment":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/jenkinsci/jenkins/pulls/3026/commits"},"statuses":{"href":"https://api.github.com/repos/jenkinsci/jenkins/statuses/1784f90806c1c1f39e307c722a3dd4f63850877e"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"jglick"}}