Problem using git token with jgit sshFactory (JschConfigSessionFactory) - ssh

I have the following code running with JGIT and when I set the repo to the origin to HTTPS protocol I'm able to fetch using JGIT with no issues. However, when I change the repo's origin to an SSH protocol I get an AUTH failed error. I've looked through stack overflow and the JGIT documentation and am wondering if someone can take a look at this code and advise on how to use a git token to auth through SSH. is this even possible? Thanks
FetchResult result = git.fetch().setTransportConfigCallback(transport -> {
if (transport instanceof SshTransport) {
SshTransport sshTransport = (SshTransport) transport;
SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
#Override
protected void configure(OpenSshConfig.Host host, Session session) {
session.setPassword("<TOKEN>");
session.setConfig("StrictHostKeyChecking", "no");
}
#Override
protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jsch = super.getJSch(hc, fs);
jsch.removeAllIdentity();
return jsch;
}
};
sshTransport.setSshSessionFactory(sshSessionFactory);
} else if (transport instanceof HttpTransport) {
HttpTransport httpTransport = (HttpTransport) transport;
httpTransport.setCredentialsProvider(new UsernamePasswordCredentialsProvider("<SERVICE_NAME", "<TOKEN>"));
}
}).setCheckFetchedObjects(true).call();
}

Related

Intercept SSL/TLS requests in HTTPS Grizzly server

I have set up an HTTPS server using grizzly 2.3.30 and jersey 2.25.1, which can be found here.
The server works well and I can curl to it with certificate-authority, certificate and key:
curl -v --cacert $CERTS/myCA.pem --key $CERTS/grizzly.key --cert $CERTS/grizzly.crt https://localhost:9999/hello
I want to intercept TLS/SSL requests, so I can log which ones fail like for example:
curl -v https://localhost:9999/hello
I am using Grizzly Http Server Framework with Jersey in this fashion:
public class MyGrizzlyServer {
public static void main(String[] args) throws Exception {
System.out.println("Hello main!");
String uriStr = "https://0.0.0.0:9999/";
URI uri = URI.create(uriStr);
final ResourceConfig rc = new ResourceConfig().packages("org");
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(uri, rc, false);
SSLEngineConfigurator engineConfig = getSslEngineConfig();
for (NetworkListener listener : server.getListeners()) {
listener.setSecure(true);
listener.setSSLEngineConfig(engineConfig);
}
HttpHandler handler = server.getHttpHandler();
System.out.println("Http server start...");
server.start();
System.out.println("Hit enter to stop it...");
System.in.read();
server.shutdownNow();
}
private static SSLEngineConfigurator getSslEngineConfig() {
SSLContextConfigurator sslConfigurator = new SSLContextConfigurator();
sslConfigurator.setKeyStoreFile("./mycerts/grizzly.jks");
sslConfigurator.setKeyStorePass("awesome");
sslConfigurator.setTrustStoreFile("./mycerts/myCA.jks");
sslConfigurator.setTrustStorePass("mycapass");
sslConfigurator.setSecurityProtocol("TLS");
SSLContext context = sslConfigurator.createSSLContext(true);
SSLEngineConfigurator sslEngineConfigurator = new SSLEngineConfigurator(context);
sslEngineConfigurator.setNeedClientAuth(true);
sslEngineConfigurator.setClientMode(false);
return sslEngineConfigurator;
}
}
I have been reading Grizzly documentation to get familiarized with its internals.
Grizzly seems to pile filter chains for transport, ssl, http, etc.
I am experimenting with this, but haven't figured out how to achieve it yet.
Any hint will be appreciated.
After playing a bit with filter chains, I was able to remove default SSLBaseFilter and add a custom SSL Filter inherited from SSLBaseFilter.
That way I could captured exceptions thrown by failed TLS/SSL requests.
In MyGrizzlyServer server:
server.start();
NetworkListener listener = server.getListener("grizzly");
FilterChain filterChain = listener.getFilterChain();
int sslBaseFilterIndex = filterChain.indexOfType(SSLBaseFilter.class);
filterChain.remove(sslBaseFilterIndex);
MySslFilter sslFilter = new MySslFilter(sslEngineConfig);
filterChain.add(sslBaseFilterIndex, sslFilter);
With custom SSL filter:
public class MySslFilter extends SSLBaseFilter {
MySslFilter(SSLEngineConfigurator configurator) {
super(configurator);
}
#Override
public NextAction handleRead(FilterChainContext ctx) throws IOException {
NextAction nextAction = null;
try {
System.out.println(" *** MySslFilter handleRead ***" );
nextAction = super.handleRead(ctx);
} catch (IOException e) {
System.out.println(" *** MySslFilter Exception ***" );
e.printStackTrace();
}
return nextAction;
}
}

using oPort option in Apache commons SFTP

I have a sftp server which i can connect manually using the command below
sftp -oport=4022 user#xxxxxx.com
but I am finding difficulty in doing the same with apache commons vfs.
Below is the method I am using to establish connection to the sftp server. But it not working and fails with the error "org.apache.commons.vfs2.FileSystemException: Could not connect to SFTP server at xxxxxx.com"
public boolean connect(String host, String login, String password,
int port) throws Exception {
//If the client is already connected, disconnect
if (command != null) {
disconnect();
}
FileSystemOptions fso = new FileSystemOptions();
try {
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(fso,
"no");
session =
SftpClientFactory.createConnection(host, port, login.toCharArray(),
password.toCharArray(),
fso);
System.out.println("pass");
Channel channel = session.openChannel("ssh");
channel.connect();
command = (ChannelSftp)channel;
} catch (FileSystemException e) {
throw e;
// return false;
}
return command.isConnected();
}
Please help me with this

Solr 4 with basic authentication

I am trying to connect to solr using solrj. My solr instance runs in jetty and is protected with basic authentication. I found these links that contain relevant information.
http://grokbase.com/t/lucene/solr-user/1288xjjbwx/http-basic-authentication-with-httpsolrserver
Preemptive Basic authentication with Apache HttpClient 4
However, I still get the following exception:
Caused by: org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:352)
... 5 more
Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.
at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:625)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
... 8 more
I have also attached a snippet of the code I am using.
public static void main(String[] args) throws SolrServerException, IOException {
HttpSolrServer server = new HttpSolrServer("http://localhost:8983/solr/");
DefaultHttpClient m_client =(DefaultHttpClient)server.getHttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(USERNAME, PASSWORD);
m_client.addRequestInterceptor(new PreemptiveAuthInterceptor(),0);
(((DefaultHttpClient)m_client).getCredentialsProvider()).setCredentials(new AuthScope("localhost",8983), credentials);
SolrInputDocument document = new SolrInputDocument();
document.addField("id",123213);
server.add(document);
server.commit();
}
}
class PreemptiveAuthInterceptor implements HttpRequestInterceptor {
public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
// If no auth scheme avaialble yet, try to initialize it
// preemptively
if (authState.getAuthScheme() == null) {
AuthScheme authScheme = (AuthScheme) context.getAttribute("preemptive-auth");
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
if (authScheme != null) {
Credentials creds = credsProvider.getCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()));
if (creds == null) {
throw new HttpException("No credentials for preemptive authentication");
}
authState.setAuthScheme(authScheme);
authState.setCredentials(creds);
}
}
}
Can anyone point me in the right direction? Thanks !!
i had the same problem when implementing partial documents update. i solved the problem by implementing PreemptiveAuthInterceptor. see below code
PoolingClientConnectionManager cxMgr = new PoolingClientConnectionManager(
SchemeRegistryFactory.createDefault());
cxMgr.setMaxTotal(100);
cxMgr.setDefaultMaxPerRoute(20);
DefaultHttpClient httpclient = new DefaultHttpClient(cxMgr);
httpclient.addRequestInterceptor(
new PreemptiveAuthInterceptor(), 0);
httpclient.getCredentialsProvider().setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(solrDto.getUsername(),
solrDto.getPassword()));
HttpSolrServer solrServerInstance = new HttpSolrServer(solrDto.getUrl(),
httpclient);
solrServerInstance.setRequestWriter(new BinaryRequestWriter());
solrServerInstance.setAllowCompression(true);
You also need:
private class PreemptiveAuthInterceptor implements HttpRequestInterceptor {
public void process(final HttpRequest request, final HttpContext context)
throws HttpException, IOException {
AuthState authState = (AuthState) context
.getAttribute(ClientContext.TARGET_AUTH_STATE);
// If no auth scheme avaialble yet, try to initialize it
// preemptively
if (authState.getAuthScheme() == null) {
CredentialsProvider credsProvider = (CredentialsProvider) context
.getAttribute(ClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context
.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
Credentials creds = credsProvider.getCredentials(new AuthScope(
targetHost.getHostName(), targetHost.getPort()));
if (creds == null)
throw new HttpException(
"No credentials for preemptive authentication");
authState.setAuthScheme(new BasicScheme());
authState.setCredentials(creds);
}
}
}
According to the Solr Security - SolrJ section on Solr Wiki you should be able to do the following:
public static void main(String[] args) throws SolrServerException, IOException {
HttpSolrServer server = new HttpSolrServer("http://localhost:8983/solr/");
HttpClientUtil.setBasicAuth(server.getHttpClient(), USERNAME, PASSWORD);
SolrInputDocument document = new SolrInputDocument();
document.addField("id",123213);
server.add(document);
server.commit();
}
You need to add the JAR solr-solrj-4.0.0.jar for HttpClientUtil.
Then use the below code:
HttpSolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/"+url);
HttpClientUtil.setBasicAuth((DefaultHttpClient) solrServer.getHttpClient(), "USERNAME", "PASSWORD");
That worked for me on Jdk 1.6 and tomcat 6

Unable to tunnel through proxy. Proxy returns "HTTP/1.1 407" via https

I try to connect to a server via https that requires authentication.Moreover, I have an http proxy in the middle that also requires authentication. I use ProxyAuthSecurityHandler to authenticate with the proxy and BasicAuthSecurityHandler to authenticate with the server.
Receiving java.io.IOException: Unable to tunnel through proxy.
Proxy returns "HTTP/1.1 407 Proxy Auth Required"
at sun.net.www.protocol.http.HttpURLConnection.doTunneling(HttpURLConnection.java:1525)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect (AbstractDelegateHttpsURLConnection.java:164)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
at org.apache.wink.client.internal.handlers.HttpURLConnectionHandler.processRequest(HttpURLConnectionHandler.java:97)
I noticed that the implementation of ProxyAuthSecurityHandler is expecting response code 407 however, during debug we never get to the second part due to the IOException thrown.
Code snap:
ClientConfig configuration = new ClientConfig();
configuration.connectTimeout(timeout);
MyBasicAuthenticationSecurityHandler basicAuthProps = new MyBasicAuthenticationSecurityHandler();
basicAuthProps.setUserName(user);
basicAuthProps.setPassword(password);
configuration.handlers(basicAuthProps);
if ("true".equals(System.getProperty("setProxy"))) {
configuration.proxyHost(proxyHost);
if ((proxyPort != null) && !proxyPort.equals("")) {
configuration.proxyPort(Integer.parseInt(proxyPort));
}
MyProxyAuthSecurityHandler proxyAuthSecHandler =
new MyProxyAuthSecurityHandler();
proxyAuthSecHandler.setUserName(proxyUser);
proxyAuthSecHandler.setPassword(proxyPass);
configuration.handlers(proxyAuthSecHandler);
}
restClient = new RestClient(configuration);
// create the createResourceWithSessionCookies instance to interact with
Resource resource = getResource(loginUrl);
// Request body is empty
ClientResponse response = resource.post(null);
Tried using wink client versions 1.1.2 and also 1.2.1. the issue repeats in both.
What I found out is that when trying to pass through a proxy using https url we first send CONNECT and only then try to send the request. The proxy server cannot read any headrs we attach to the request, cause it doesn't have the key to decrypt the traffic.
This means that the CONNECT should already have the user/pass to the proxy to pass this stage.
here is a code snap I used - that works for me:
import sun.misc.BASE64Encoder;
import java.io.*;
import java.net.*;
public class ProxyPass {
public ProxyPass(String proxyHost, int proxyPort, final String userid, final String password, String url) {
try {
/* Create a HttpURLConnection Object and set the properties */
URL u = new URL(url);
Proxy proxy =
new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
HttpURLConnection uc = (HttpURLConnection)u.openConnection(proxy);
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType().equals(RequestorType.PROXY)) {
return new PasswordAuthentication(userid, password.toCharArray());
}
return super.getPasswordAuthentication();
}
});
uc.connect();
/* Print the content of the url to the console. */
showContent(uc);
} catch (IOException e) {
e.printStackTrace();
}
}
private void showContent(HttpURLConnection uc) throws IOException {
InputStream i = uc.getInputStream();
char c;
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
public static void main(String[] args) {
String proxyhost = "proxy host";
int proxyport = port;
String proxylogin = "proxy username";
String proxypass = "proxy password";
String url = "https://....";
new ProxyPass(proxyhost, proxyport, proxylogin, proxypass, url);
}
}
if you are using wink - like I do, you need to set the proxy in the ClientConfig and before passing it to the RestClient set the default authenticator.
ClientConfig configuration = new ClientConfig();
configuration.connectTimeout(timeout);
BasicAuthenticationSecurityHandler basicAuthProps = new BasicAuthenticationSecurityHandler();
basicAuthProps.setUserName(user);
basicAuthProps.setPassword(password);
configuration.handlers(basicAuthProps);
if (proxySet()) {
configuration.proxyHost(proxyHost);
if ((proxyPort != null) && !proxyPort.equals("")) {
configuration.proxyPort(Integer.parseInt(proxyPort));
}
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType().equals(RequestorType.PROXY)) {
return new PasswordAuthentication(proxyUser), proxyPass.toCharArray());
}
return super.getPasswordAuthentication();
}
});
}
restClient = new RestClient(configuration);
Resource resource = getResource(loginUrl);
// Request body is empty
ClientResponse response = resource.post(null);
if (response.getStatusCode() != Response.Status.OK.getStatusCode()) {
throw new RestClientException("Authentication failed for user " + user);
}
If Ilana Platonov's answer doesn't work, try editing the variables :
jdk.http.auth.tunneling.disabledSchemes
jdk.http.auth.proxying.disabledSchemes

JGit clone repository

I'm trying to clone Git repository with JGit and I have problem with UnsupportedCredentialItem.
My code:
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.setGitDir(PATH).readEnvironment().findGitDir().build();
Git git = new Git(repository);
CloneCommand clone = git.cloneRepository();
clone.setBare(false);
clone.setCloneAllBranches(true);
clone.setDirectory(PATH).setURI(url);
UsernamePasswordCredentialsProvider user = new UsernamePasswordCredentialsProvider(login, password);
clone.setCredentialsProvider(user);
clone.call();
It will occur Exception:
org.eclipse.jgit.errors.UnsupportedCredentialItem: ssh://git#github.com:22: Passphrase for C:\Users\Marek\.ssh\id_rsa at
org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider.get(UsernamePasswordCredentialsProvider.java:110)....
But if I delete file known_hosts in .ssh\ It will occur different Exception
org.eclipse.jgit.errors.UnsupportedCredentialItem: ssh://git#github.com:22: The authenticity of host 'github.com' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting?
at org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider.get(UsernamePasswordCredentialsProvider.java:110)....
Is there any possibility to type "yes" to that question or just skip it?
Thank you!
I think if you login with username and password, you need https. For ssh you will need a public key that matches the one on record with github.
This will do it (like #michals, only less code) if using username / password with ssh
public void gitClone() throws GitAPIException {
final File localPath = new File("./TestRepo");
Git.cloneRepository()
.setURI(REMOTE_URL)
.setDirectory(localPath)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("***", "***"))
.call();
}
I suppose you would want to check the github help:
http://help.github.com/win-set-up-git/
Especially the part about generating ssh keys (ssh-keygen -t rsa -C "your_email#youremail.com"). Read the article for your environment, and you'll understand how to get a better configuration.
I had the same problem. The reason was passphrase set for rsa private key. When I remove passphrase for this key it started work without any CredentialsProvider.
UsernamePasswordCredentialsProvider probably don't support passphrase. If you would like to have passphrase set, you could define you own CredentialProvider, which will support it, for example:
CloneCommand clone = Git.cloneRepository()
.setURI("...")
.setCredentialsProvider(new CredentialsProvider() {
#Override
public boolean supports(CredentialItem... items) {
return true;
}
#Override
public boolean isInteractive() {
return true;
}
#Override
public boolean get(URIish uri, CredentialItem... items)
throws UnsupportedCredentialItem {
for (CredentialItem item : items) {
if (item instanceof CredentialItem.StringType) {
((CredentialItem.StringType) item).
setValue(new String("YOUR_PASSPHRASE"));
continue;
}
}
return true;
}
});
clone.call();
It works for me ;)
I had a similar issue, though my setup was a bit different. Leaving this here in case anyone else encounters something similar. I had overridden my configure method and createDefaultJSch method according to this tutorial: https://www.codeaffine.com/2014/12/09/jgit-authentication/
I had something like:
#Override
public void configure( Transport transport ) {
SshTransport sshTransport = ( SshTransport )transport;
sshTransport.setSshSessionFactory( sshSessionFactory );
}
#Override
protected JSch createDefaultJSch( FS fs ) throws JSchException {
JSch defaultJSch = super.createDefaultJSch( fs );
defaultJSch.addIdentity( "/path/to/private_key" );
return defaultJSch;
}
I ended up changing my createdDefaultJSch method to getSch (adding the appropriate parameters) and adding removeAllIdentity():
#Override
public JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
JSch jSch = super.getJSch(hc, fs)
jSch.removeAllIdentity()
jSch.addIdentity( "/path/to/private_key" )
return jSch
}
No idea why this worked, but I found the getSch thing from this answer (coincidentally by the same guy who wrote the tutorial): Using Keys with JGit to Access a Git Repository Securely
It is not clear to me whether you want to do username/password authentication or public/private key authentication. Either way, CredentialsProvider will not be used, according to this. You need to configure the transport. First, create a transport configuration callback:
SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
#Override
protected void configure( Host host, Session session ) {
// If you are using username/password authentication, add the following line
session.setPassword( "password" );
}
} );
TransportConfigCallback transportConfigCallback = new TransportConfigCallback() {
#Override
public void configure( Transport transport ) {
SshTransport sshTransport = ( SshTransport )transport;
sshTransport.setSshSessionFactory( sshSessionFactory );
}
};
Then configure the command with it:
clone.setTransportConfigCallback( transportConfigCallback );
If the repository is private and needs authentication, you(#Scruger) will do it using username/password with ssh for clone repository.
private UsernamePasswordCredentialsProvider configAuthentication(String user, String password) {
return new UsernamePasswordCredentialsProvider(user, password );
}
public void clonneRepositoryWithAuthentication(String link, String directory,String branch,String user, String password){
System.out.println("cloning repository private from bitcketebuk");
try {
Git.cloneRepository()//function responsible to clone repository
.setURI(link)// set link to repository git
.setDirectory(new File(Constants.PATH_DEFAULT + directory))//Defined the path local the cloning
.setCredentialsProvider(configAuthentication(user, password))
.setCloneAllBranches(true)//Defined clone all branch exists on repository
.call();//execute call the clone repository git
System.out.println("Cloning sucess.....");
} catch (GitAPIException e) {
System.err.println("Error Cloning repository " + link + " : "+ e.getMessage());
}
}