Skip to content

Commit

Permalink
Merge pull request #10 from erwannT/master
Browse files Browse the repository at this point in the history
Proxy for credentials
  • Loading branch information
slide committed Dec 15, 2015
2 parents 906b3de + 3b968f1 commit 6411884
Show file tree
Hide file tree
Showing 14 changed files with 458 additions and 52 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.532.1</version>
<version>1.554.3</version>
</parent>

<groupId>org.jenkins-ci.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,56 @@

package jenkins.plugins.publish_over_ssh;

import com.jcraft.jsch.*;
import hudson.Util;
import hudson.model.Describable;
import hudson.model.Hudson;

import java.io.IOException;
import java.util.Properties;
import jenkins.plugins.publish_over.BPBuildInfo;
import jenkins.plugins.publish_over.BPHostConfiguration;
import jenkins.plugins.publish_over.BapPublisher;
import jenkins.plugins.publish_over.BapPublisherException;

import jenkins.plugins.publish_over.*;
import jenkins.plugins.publish_over_ssh.descriptor.BapSshHostConfigurationDescriptor;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kohsuke.stapler.DataBoundConstructor;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import org.kohsuke.stapler.DataBoundSetter;

@SuppressWarnings("PMD.TooManyMethods")
public class BapSshHostConfiguration extends BPHostConfiguration<BapSshClient, BapSshCommonConfiguration>
implements Describable<BapSshHostConfiguration> {
implements Describable<BapSshHostConfiguration> {

private static final long serialVersionUID = 1L;
public static final int DEFAULT_PORT = 22;
public static final int DEFAULT_TIMEOUT = 300000;
public static final String CONFIG_KEY_PREFERRED_AUTHENTICATIONS = "PreferredAuthentications";
private static final Log LOG = LogFactory.getLog(BapSshHostConfiguration.class);
public static final String HTTP_PROXY_TYPE = "http";
public static final String SOCKS_4_PROXY_TYPE = "socks4";
public static final String SOCKS_5_PROXY_TYPE = "socks5";

private int timeout;
private boolean overrideKey;
private boolean disableExec;
private final BapSshKeyInfo keyInfo;
private BapSshKeyInfo keyInfo;

private String proxyType;
private String proxyHost;
private int proxyPort;
private String proxyUser;
private String proxyPassword;

public BapSshHostConfiguration() {
// use this constructor instead of the default w/o parameters because there is some
// business logic in there...
super(null, null, null, null, null, 0);
this.keyInfo = new BapSshKeyInfo(null, null, null);
}

// CSOFF: ParameterNumberCheck
@SuppressWarnings("PMD.ExcessiveParameterList") // DBC for you!
Expand All @@ -73,20 +85,63 @@ public BapSshHostConfiguration(final String name, final String hostname, final S
super(name, hostname, username, null, remoteRootDir, port);
this.timeout = timeout;
this.overrideKey = overrideKey;
keyInfo = new BapSshKeyInfo(encryptedPassword, key, keyPath);
this.keyInfo = new BapSshKeyInfo(encryptedPassword, key, keyPath);
this.disableExec = disableExec;
}

public int getTimeout() { return timeout; }
public void setTimeout(final int timeout) { this.timeout = timeout; }
@DataBoundSetter
@Override
public void setName(String name) {
super.setName(name);
}

@DataBoundSetter
@Override
protected final String getPassword() { return keyInfo.getPassphrase(); }
public void setHostname(String hostname) {
super.setHostname(hostname);
}

@DataBoundSetter
@Override
public final void setPassword(final String password) { keyInfo.setPassphrase(password); }
public void setRemoteRootDir(String remoteRootDir) {
super.setRemoteRootDir(remoteRootDir);
}

@DataBoundSetter
@Override
public final String getEncryptedPassword() { return keyInfo.getEncryptedPassphrase(); }
public void setPort(int port) {
super.setPort(port);
}

public int getTimeout() {
return timeout;
}

@DataBoundSetter
public void setTimeout(final int timeout) {
this.timeout = timeout;
}

@Override
protected final String getPassword() {
return keyInfo.getPassphrase();
}

@Override
public final void setPassword(final String password) {
keyInfo.setPassphrase(password);
}

@DataBoundSetter
@Override
public final String getEncryptedPassword() {
return keyInfo.getEncryptedPassphrase();
}

@DataBoundSetter
public void setEncryptedPassword(final String encryptedPassword) {
this.keyInfo.setPassphrase(encryptedPassword);
}

public String getKeyPath() { return keyInfo.getKeyPath(); }
public void setKeyPath(final String keyPath) { keyInfo.setKeyPath(keyPath); }
Expand All @@ -95,11 +150,50 @@ public BapSshHostConfiguration(final String name, final String hostname, final S
public void setKey(final String key) { keyInfo.setKey(key); }

public boolean isOverrideKey() { return overrideKey; }

@DataBoundSetter
public void setOverrideKey(final boolean overrideKey) { this.overrideKey = overrideKey; }

public boolean isDisableExec() { return disableExec; }

@DataBoundSetter
public void setDisableExec(final boolean disableExec) { this.disableExec = disableExec; }

public String getProxyType() { return proxyType; }

public String getProxyHost() {return proxyHost; }

public int getProxyPort() { return proxyPort; }

public String getProxyUser() { return proxyUser; }

public String getProxyPassword() {return proxyPassword; }

@DataBoundSetter
public void setProxyType(String proxyType) {
this.proxyType = proxyType;
}

@DataBoundSetter
public void setProxyHost(String proxyHost) {
this.proxyHost = proxyHost;
}

@DataBoundSetter
public void setProxyPort(int proxyPort) {
this.proxyPort = proxyPort;
}

@DataBoundSetter
public void setProxyUser(String proxyUser) {
this.proxyUser = proxyUser;
}

@DataBoundSetter
public void setProxyPassword(String proxyPassword) {
this.proxyPassword = proxyPassword;
}

public boolean isEffectiveDisableExec() {
return getCommonConfig().isDisableAllExec() || disableExec;
}
Expand Down Expand Up @@ -235,7 +329,36 @@ private Session createSession(final BPBuildInfo buildInfo, final JSch ssh) {
final String username = overrideCreds == null ? getUsername() : overrideCreds.getUsername();
try {
buildInfo.printIfVerbose(Messages.console_session_creating(username, getHostnameTrimmed(), getPort()));
return ssh.getSession(username, getHostnameTrimmed(), getPort());
Session session = ssh.getSession(username, getHostnameTrimmed(), getPort());

if (StringUtils.isNotEmpty(proxyType) && StringUtils.isNotEmpty(proxyHost)) {
if (StringUtils.equals(HTTP_PROXY_TYPE, proxyType)) {
ProxyHTTP proxyHTTP = new ProxyHTTP(proxyHost, proxyPort);
if (StringUtils.isNotEmpty(proxyUser) && StringUtils.isNotEmpty(proxyPassword)) {
proxyHTTP.setUserPasswd(proxyUser, proxyPassword);
} else {
proxyHTTP.setUserPasswd(null, null);
}
session.setProxy(proxyHTTP);
} else if (StringUtils.equals(SOCKS_4_PROXY_TYPE, proxyType)) {
ProxySOCKS4 proxySocks4 = new ProxySOCKS4(proxyHost, proxyPort);
if (StringUtils.isNotEmpty(proxyUser) && StringUtils.isNotEmpty(proxyPassword)) {
proxySocks4.setUserPasswd(proxyUser, proxyPassword);
} else {
proxySocks4.setUserPasswd(null, null);
}
session.setProxy(proxySocks4);
} else if (StringUtils.equals(SOCKS_5_PROXY_TYPE, proxyType)) {
ProxySOCKS5 proxySocks5 = new ProxySOCKS5(proxyHost, proxyPort);
if (StringUtils.isNotEmpty(proxyUser) && StringUtils.isNotEmpty(proxyPassword)) {
proxySocks5.setUserPasswd(proxyUser, proxyPassword);
} else {
proxySocks5.setUserPasswd(null, null);
}
session.setProxy(proxySocks5);
}
}
return session;
} catch (JSchException jse) {
throw new BapPublisherException(Messages.exception_session_create(
username, getHostnameTrimmed(), getPort(), jse.getLocalizedMessage()), jse);
Expand All @@ -256,28 +379,44 @@ public BapSshHostConfigurationDescriptor getDescriptor() {

protected EqualsBuilder addToEquals(final EqualsBuilder builder, final BapSshHostConfiguration that) {
return super.addToEquals(builder, that)
.append(keyInfo, that.keyInfo)
.append(timeout, that.timeout)
.append(overrideKey, that.overrideKey)
.append(disableExec, that.disableExec);
.append(keyInfo, that.keyInfo)
.append(timeout, that.timeout)
.append(overrideKey, that.overrideKey)
.append(disableExec, that.disableExec)
.append(proxyType, that.proxyType)
.append(proxyHost, that.proxyHost)
.append(proxyPort, that.proxyPort)
.append(proxyUser, that.proxyUser)
.append(proxyPassword, that.proxyPassword);
}

@Override
protected HashCodeBuilder addToHashCode(final HashCodeBuilder builder) {
return super.addToHashCode(builder)
.append(keyInfo)
.append(timeout)
.append(overrideKey)
.append(disableExec);
.append(keyInfo)
.append(timeout)
.append(overrideKey)
.append(disableExec)
.append(proxyType)
.append(proxyHost)
.append(proxyPort)
.append(proxyUser)
.append(proxyPassword);
}

@Override
protected ToStringBuilder addToToString(final ToStringBuilder builder) {
return super.addToToString(builder)
.append("keyInfo", keyInfo)
.append("timeout", timeout)
.append("overrideKey", overrideKey)
.append("disableExec", disableExec);
.append("keyInfo", keyInfo)
.append("timeout", timeout)
.append("overrideKey", overrideKey)
.append("disableExec", disableExec)
.append("proxyType", proxyType)
.append("proxyHost", proxyHost)
.append("proxyPort", proxyPort)
.append("proxyUser", proxyUser)
.append("proxyPassword", proxyPassword);

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,31 @@
<f:entry title="${%disableExec}" field="disableExec">
<f:checkbox/>
</f:entry>

<f:entry name="proxyType" title="${%proxyType}" field="proxyType">
<select name="proxyType">
<f:option value=""></f:option>
<f:option selected="${instance.proxyType == 'http'}" value="http">${%proxyHTTP}</f:option>
<f:option selected="${instance.proxyType == 'socks4'}" value="socks4">${%proxySocks4}</f:option>
<f:option selected="${instance.proxyType == 'socks5'}" value="socks5">${%proxySocks5}</f:option>
</select>
</f:entry>
<f:entry title="${%proxyHost}" field="proxyHost">
<f:textbox/>
</f:entry>
<f:entry title="${%proxyPort}" field="proxyPort">
<f:textbox clazz="number" />
</f:entry>
<f:entry title="${%proxyUser}" field="proxyUser">
<f:textbox/>
</f:entry>
<f:entry title="${%proxyPassword}" field="proxyPassword">
<f:password/>
</f:entry>

</f:advanced>

<f:validateButton title="${m.test_title()}" progress="${m.test_progress()}" method="testConnection"
with="name,hostname,username,encryptedPassword,remoteRootDir,port,timeout,keyPath,key,overrideKey,common.encryptedPassphrase,common.key,common.keyPath"/>
with="name,hostname,username,encryptedPassword,remoteRootDir,port,timeout,keyPath,key,overrideKey,common.encryptedPassphrase,common.key,common.keyPath,proxyType,proxyHost,proxyPort,proxyUser,proxyPassword"/>

</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ password=Passphrase / Password
keyPath=Path to key
key=Key
disableExec=Disable exec
proxyType=Proxy type
proxyHTTP=HTTP
proxySocks4=SOCKS4
proxySocks5=SOCKS5
proxyHost=Proxy host
proxyPort=Proxy port
proxyUser=Proxy user
proxyPassword=Proxy password
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ password=P*s*p*r*s* / P*s*w*r*
keyPath=P*t* t* k*y
key=K*y
disableExec=D*s*b*e e*e*
proxyType=P*o*y t*p*
proxyHTTP=H*T*
proxySocks4=S*c*s4
proxySocks5=S*c*s5
proxyHost=P*o*y h*s*
proxyPort=P*o*y p*r*
proxyUser=P*o*y u*e*
proxyPassword=P*o*y p*s*w*r*
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!--
~ The MIT License
~
~ Copyright (C) 2010-2011 by Anthony Robinson
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->

<div>Proxy hostname or IP address to connect to</div>
Loading

0 comments on commit 6411884

Please sign in to comment.