question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NB-14: Cloning/fetching/pushing remote repositories with Git over SSH disregards cnd.tmpbase

See original GitHub issue

Apache NetBeans version

Apache NetBeans 14

What happened

In Apache NetBeans 14, Git-related support for cloning, fetching from, or pushing to remote repositories is broken, as outlined below, whenever the temporary-file directory (/tmp) is mounted with the noexec option set.

In prior releases, having cnd.tmpbase system property defined, allowed to select a temporary-file directory where necessary execution would have taken place. It may, as well, work still, but its coverage seems to slip (junixsocket).

How to reproduce

[P R E L I M I N A R Y    S T E P]

Set up the ssh transport protocol for a target repository (locally generate public-private key pair, upload the public key). Create a new directory that can be read, written, searched by an Apache NetBeans process and which can be used by it for the management of its own temporary files. Enable keyring-related logging in netbeans/etc/netbeans.conf: netbeans_default_options="... -J-Dorg.netbeans.modules.keyring.level=0"

Proceed with the following steps (FAILURE and SUCCESS) in any order.


[F A I L U R E]

Manually forbid execution of binaries and other executable files from the /tmp directory: sudo mount --options remount,noexec /tmp mount | grep /tmp

Launch Apache NetBeans 14 with -J-Dcnd.tmpbase=/path/to/new/dir. (Substitute the actual path to the newly-created directory for /path/to/new/dir.)

Try either cloning or fetching from or pushing to some Git repository for which the ssh transport protocol was set.

When CLONING…

Go Team -> Git -> Clone

[Repository URL: git@…]

Check “Private/Public Key”, type in the passphrase, and press the “Next” button. Expect a message written just above the “Next” button:

Cannot connect to repository at git@… .

Press “Cancel” and exit Apache NetBeans.

In /tmp (and not in /path/to/new/dir), verify the presence of libtmp*libjunixsocket*.so files (apparently, extracted from netbeans/ide/modules/ext/junixsocket-native-common-2.4.0.jar).

View ~/.netbeans/14/var/log/messages.log.

Look for the keyring provider being used:

FINE [org.netbeans.modules.keyring]: Using provider: org.netbeans.modules.keyring.gnome.libsecret.GnomeLibSecretProvider@xxxxxxxx

Look for the “remote hung up unexpectedly” entries:

INFO [org.netbeans.modules.git]: git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly

And right below it:

java.lang.NoClassDefFoundError: Could not initialize class org.newsclub.net.unix.AFUNIXSocketAddress     at com.jcraft.jsch.JUnixSocketFactory.connect(JUnixSocketFactory.java:58)     at com.jcraft.jsch.SSHAgentConnector.open(SSHAgentConnector.java:78)     at com.jcraft.jsch.SSHAgentConnector.isAvailable(SSHAgentConnector.java:69)     at com.jcraft.jsch.AgentIdentityRepository.getStatus(AgentIdentityRepository.java:68)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.setupJSchIdentityRepository(JGitSshSessionFactory.java:182)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.setupJSch(JGitSshSessionFactory.java:206)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.getSession(JGitSshSessionFactory.java:103)     at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:107)     at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:247) Caused: org.eclipse.jgit.errors.TransportException: git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly     at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:263)     at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:137)     at org.netbeans.libs.git.jgit.commands.ListRemoteObjectsCommand.runTransportCommand(ListRemoteObjectsCommand.java:51) Caused: org.netbeans.libs.git.GitException: git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly     at org.netbeans.libs.git.jgit.commands.TransportCommand.handleException(TransportCommand.java:238)     at org.netbeans.libs.git.jgit.commands.ListRemoteObjectsCommand.runTransportCommand(ListRemoteObjectsCommand.java:64)     at org.netbeans.libs.git.jgit.commands.TransportCommand.run(TransportCommand.java:168)     at org.netbeans.libs.git.jgit.commands.GitCommand$1.run(GitCommand.java:57)     at org.netbeans.libs.git.jgit.commands.GitCommand$1.run(GitCommand.java:54)     at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)     at org.netbeans.libs.git.jgit.commands.GitCommand.execute(GitCommand.java:54)     at org.netbeans.libs.git.GitClient.listRemoteBranches(GitClient.java:893)     at org.netbeans.modules.git.client.GitClient$36.call(GitClient.java:582)     at org.netbeans.modules.git.client.GitClient$36.call(GitClient.java:578)     at org.openide.util.NetworkSettings.suppressAuthenticationDialog(NetworkSettings.java:138)     at org.netbeans.modules.git.client.GitClient$CommandInvoker$1$1.call(GitClient.java:931)     at org.netbeans.modules.git.client.GitClient$CommandInvoker$1.call(GitClient.java:956)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethodIntern(GitClient.java:968)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethod(GitClient.java:897)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethod(GitClient.java:875)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.access$400(GitClient.java:869)     at org.netbeans.modules.git.client.GitClient.listRemoteBranches(GitClient.java:578) [catch] at org.netbeans.modules.git.ui.clone.RepositoryStep$RepositoryStepProgressSupport.perform(RepositoryStep.java:302)     at org.netbeans.modules.git.client.GitProgressSupport.performIntern(GitProgressSupport.java:92)     at org.netbeans.modules.git.client.GitProgressSupport.run(GitProgressSupport.java:85)     at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1418)     at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)     at org.openide.util.lookup.Lookups.executeWith(Lookups.java:278)     at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)


Affirm the availability of that not-found class: cd /path/to/netbeans/14/ jar tf netbeans/ide/modules/ext/junixsocket-common-2.4.0.jar | grep AFUNIXSocketAddress

(Clone the repository with git-clone(1): eval "$(ssh-agent -s)" ssh-add ~/.ssh/PRIVATE_KEY git clone --verbose git@...

Open the (supported) project.)

When FETCHING (or PUSHING)…

(When the project is newly opened, expect a pop-up window, entitled “Specify Git repository location”, to appear. Check “Private/Public Key”, type in the passphrase, and press the “OK” button. And now…) Expect a pop-up window, entitled “Git Command Failed”, to appear with an error message (also saved in messages.log):

git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly

Again, as with CLONING, libtmp*libjunixsocket*.so files should be abandoned in /tmp (and not in /path/to/new/dir).

And a similar (fetching) stack trace shall be written to ~/.netbeans/14/var/log/messages.log:

java.lang.NoClassDefFoundError: Could not initialize class org.newsclub.net.unix.AFUNIXSocketAddress     at com.jcraft.jsch.JUnixSocketFactory.connect(JUnixSocketFactory.java:58)     at com.jcraft.jsch.SSHAgentConnector.open(SSHAgentConnector.java:78)     at com.jcraft.jsch.SSHAgentConnector.isAvailable(SSHAgentConnector.java:69)     at com.jcraft.jsch.AgentIdentityRepository.getStatus(AgentIdentityRepository.java:68)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.setupJSchIdentityRepository(JGitSshSessionFactory.java:182)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.setupJSch(JGitSshSessionFactory.java:206)     at org.netbeans.libs.git.jgit.JGitSshSessionFactory.getSession(JGitSshSessionFactory.java:103)     at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:107)     at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:247) Caused: org.eclipse.jgit.errors.TransportException: git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly     at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:263)     at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:137)     at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:105)     at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:91)     at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1260)     at org.netbeans.libs.git.jgit.commands.FetchCommand.runTransportCommand(FetchCommand.java:80) Caused: org.netbeans.libs.git.GitException: git@xxxxxxxxxxxxxxxx.git: remote hung up unexpectedly     at org.netbeans.libs.git.jgit.commands.TransportCommand.handleException(TransportCommand.java:238)     at org.netbeans.libs.git.jgit.commands.FetchCommand.runTransportCommand(FetchCommand.java:98)     at org.netbeans.libs.git.jgit.commands.TransportCommand.run(TransportCommand.java:168)     at org.netbeans.libs.git.jgit.commands.GitCommand$1.run(GitCommand.java:57)     at org.netbeans.libs.git.jgit.commands.GitCommand$1.run(GitCommand.java:54)     at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)     at org.netbeans.libs.git.jgit.commands.GitCommand.execute(GitCommand.java:54)     at org.netbeans.libs.git.GitClient.fetch(GitClient.java:640)     at org.netbeans.modules.git.client.GitClient$19.call(GitClient.java:403)     at org.netbeans.modules.git.client.GitClient$19.call(GitClient.java:399)     at org.openide.util.NetworkSettings.suppressAuthenticationDialog(NetworkSettings.java:138)     at org.netbeans.modules.git.client.GitClient$CommandInvoker$1$1.call(GitClient.java:931)     at org.netbeans.modules.git.client.GitClient$CommandInvoker$1$1.call(GitClient.java:937)     at org.netbeans.modules.git.client.GitClient$CommandInvoker$1.call(GitClient.java:956)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethodIntern(GitClient.java:968)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethod(GitClient.java:893)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.runMethod(GitClient.java:875)     at org.netbeans.modules.git.client.GitClient$CommandInvoker.access$400(GitClient.java:869)     at org.netbeans.modules.git.client.GitClient.fetch(GitClient.java:399)     at org.netbeans.modules.git.ui.fetch.FetchAction.fetchRepeatedly(FetchAction.java:170) [catch] at org.netbeans.modules.git.ui.fetch.FetchAction$3.perform(FetchAction.java:146)     at org.netbeans.modules.git.client.GitProgressSupport.performIntern(GitProgressSupport.java:92)     at org.netbeans.modules.git.client.GitProgressSupport.run(GitProgressSupport.java:85)     at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1418)     at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)     at org.openide.util.lookup.Lookups.executeWith(Lookups.java:278)     at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)



[S U C C E S S    # 1]

Manually permit execution of binaries and other executable files from the /tmp directory: sudo mount --options remount,exec /tmp mount | grep /tmp

(If present, manually remove stale libtmp*libjunixsocket*.so files from /tmp.)

Launch Apache NetBeans 14.

Try fetching from (or pushing to) some Git repository for which the ssh transport protocol was set. Expect a pop-up window, entitled “Specify Git repository location”, to appear. Check “Private/Public Key”, type in the passphrase, and press the “OK” button.

(There should be neither a new NoClassDefFoundError logged entry nor new libtmp*libjunixsocket*.so files left over in /tmp.)


[S U C C E S S    # 2]

Manually forbid execution of binaries and other executable files from the /tmp directory: sudo mount --options remount,noexec /tmp mount | grep /tmp

Launch Apache NetBeans 14 with JUnixSocket’s property set -J-Dorg.newsclub.net.unix.library.tmpdir=/path/to/new/dir, as the temporary-file directory path. (Substitute the actual path to the newly-created directory for /path/to/new/dir.)

Try fetching from (or pushing to) some Git repository for which the ssh transport protocol was set. Expect a pop-up window, entitled “Specify Git repository location”, to appear. Check “Private/Public Key”, type in the passphrase, and press the “OK” button.

(There should be neither a new NoClassDefFoundError logged entry nor new libtmp*libjunixsocket*.so files left over in /tmp.)

Did this work correctly in an earlier version?

Apache NetBeans 13

Operating System

GNU/Linux Debian (testing/bookworm)

JDK

OpenJDK (17.0.3+7-Debian-1)

Apache NetBeans packaging

Apache NetBeans binary zip

Anything else

It may be speculated that all that is needed to resolve this issue lies in extending cnd.tmpbase’s coverage by re-using its value, if any, as the value of the property parsed by the JUnixSocket dependency of Apache NetBeans: org.newsclub.net.unix.library.tmpdir.

For example,

class UnifiedBespokeTmpDirTests
{
	private static final String PROP_J_UNIX_SOCKET_TMP_DIR =
					"org.newsclub.net.unix.library.tmpdir";
	private static final String PROP_NET_BEANS_TMP_DIR = "cnd.tmpbase";

	// Call it some time before org.newsclub.net.unix.NativeLibraryLoader
	// from "junixsocket-common" can be loaded.
	static void unifyBespokeTmpDir(boolean dependsOnJUnixSocket)
	{
		if (!dependsOnJUnixSocket)
			return;

		final String netBeansTmpDir = System.getProperty(
						PROP_NET_BEANS_TMP_DIR);

		if (netBeansTmpDir != null)
			System.setProperty(PROP_J_UNIX_SOCKET_TMP_DIR,
						netBeansTmpDir);
	}


	public static void main(String[] args)
	{
		System.setProperty(PROP_NET_BEANS_TMP_DIR, "/foo");
		unifyBespokeTmpDir(true);
		assert System.getProperty(PROP_J_UNIX_SOCKET_TMP_DIR, "")
			.equals(System.getProperty(PROP_NET_BEANS_TMP_DIR));
	}
}

Are you willing to submit a pull request?

Yes

Code of Conduct

Yes

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
matthiasblaesingcommented, Jul 22, 2022

@neilcsmith-net - I looked at 13 and the difference is, that the old git integration used a unix domain socket implementation based on JNA and this is already covered by the same mechanism that is now used to load the junixsocket library after the referenced PR. As we never advertised, that you could run with a noexec temp, this is IMHO not a regression.

1reaction
matthiasblaesingcommented, Jul 21, 2022

So I have a PR ready, that should fix this. PR is referenced, a binary build is available here:

https://doppel-helix.eu/NetBeans-dev-dev-a27179c197747f3f5a3e5031135d856374385bf5-release.zip

I tested with a readonly tmpfs on linux and was able to reproduce the problem (retargetting java.io.tmpdir there) and also could verify, that pull works after this change.

HOWEVER this needs to be tested on mac OS and of course if there are more linux users willing to test, it would also be appreciated. On windows I assume the putty agent is more common, so it is less interesting there.

The test scenario is this: With this build you should still be able to do a git pull using an SSH based connection, that is authenticated using an SSH agent. This is basicly the whole use-case the unixdomain socket library has in NetBeans (communication with the SSH agent).ssh based git pull, that is authenticated using an ssh agent (that is the whole use case of the existence of the library)

@geertjanw if I remember correctly you are a mac OS user, so it would be great if you could give it a spin.

Read more comments on GitHub >

github_iconTop Results From Across the Web

2.5 Git Basics - Working with Remotes
Managing remote repositories includes knowing how to add remote repositories, remove remotes that are no longer valid, manage various remote branches and define ......
Read more >
Setting up and testing a Git connection | Looker - Google Cloud
With SSH, Looker accesses your Git repository using a deploy key that you generate through your Git provider's website, as described in Connecting...
Read more >
Remotes in GitHub – Version Control with Git - Our Lessons
Explain what remote repositories are and why they are useful. Push to or pull from a remote repository. Version control really comes into...
Read more >
Git - Hosting and Accessing Remote Repository over SSH
To host a Git repository via SSH, we need to run a SSH server on the Linux machine and of course we also...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found