From c87d8ea4fa59bb8d130fa1695012934859c0f760 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 1 Jan 2011 21:30:18 +0100 Subject: [PATCH] added scm-pam-plugin --- plugins/pom.xml | 1 + plugins/scm-pam-plugin/pom.xml | 37 +++ .../scm/pam/PAMAuthenticationHandler.java | 237 ++++++++++++++++++ .../main/java/sonia/scm/pam/PAMConfig.java | 81 ++++++ .../java/sonia/scm/pam/PAMConfigResource.java | 119 +++++++++ .../main/resources/META-INF/scm/plugin.xml | 51 ++++ .../main/resources/sonia/scm/pam/sonia.pam.js | 80 ++++++ scm-webapp/pom.xml | 6 + 8 files changed, 612 insertions(+) create mode 100644 plugins/scm-pam-plugin/pom.xml create mode 100644 plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMAuthenticationHandler.java create mode 100644 plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfig.java create mode 100644 plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfigResource.java create mode 100644 plugins/scm-pam-plugin/src/main/resources/META-INF/scm/plugin.xml create mode 100644 plugins/scm-pam-plugin/src/main/resources/sonia/scm/pam/sonia.pam.js diff --git a/plugins/pom.xml b/plugins/pom.xml index 66d54fee19..415e85032e 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -21,6 +21,7 @@ scm-git-plugin scm-graph-plugin scm-activedirectory-auth-plugin + scm-pam-plugin diff --git a/plugins/scm-pam-plugin/pom.xml b/plugins/scm-pam-plugin/pom.xml new file mode 100644 index 0000000000..73825fdca2 --- /dev/null +++ b/plugins/scm-pam-plugin/pom.xml @@ -0,0 +1,37 @@ + + + + 4.0.0 + + + scm-plugins + sonia.scm.plugins + 1.0-M6-SNAPSHOT + + + sonia.scm.plugins + scm-pam-plugin + 1.0-M6-SNAPSHOT + scm-pam-plugin + https://bitbucket.org/sdorra/scm-manager + Using pam as an authentication handler. + + + + + javax.servlet + servlet-api + ${servlet.version} + provided + + + + org.jvnet.libpam4j + libpam4j + 1.3 + + + + + diff --git a/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMAuthenticationHandler.java b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMAuthenticationHandler.java new file mode 100644 index 0000000000..f024db4849 --- /dev/null +++ b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMAuthenticationHandler.java @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.pam; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import org.jvnet.libpam.PAM; +import org.jvnet.libpam.PAMException; +import org.jvnet.libpam.UnixUser; +import org.jvnet.libpam.impl.CLibrary; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.SCMContextProvider; +import sonia.scm.plugin.ext.Extension; +import sonia.scm.store.Store; +import sonia.scm.store.StoreFactory; +import sonia.scm.user.User; +import sonia.scm.util.AssertUtil; +import sonia.scm.web.security.AuthenticationHandler; +import sonia.scm.web.security.AuthenticationResult; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +@Extension +public class PAMAuthenticationHandler implements AuthenticationHandler +{ + + /** Field description */ + public static final String TYPE = "pam"; + + /** the logger for PAMAuthenticationHandler */ + private static final Logger logger = + LoggerFactory.getLogger(PAMAuthenticationHandler.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param factory + */ + @Inject + public PAMAuthenticationHandler(StoreFactory factory) + { + store = factory.getStore(PAMConfig.class, TYPE); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param response + * @param username + * @param password + * + * @return + */ + @Override + public AuthenticationResult authenticate(HttpServletRequest request, + HttpServletResponse response, String username, String password) + { + AssertUtil.assertIsNotEmpty(username); + AssertUtil.assertIsNotEmpty(password); + + PAM pam = null; + + try + { + pam = new PAM(config.getServiceName()); + } + catch (PAMException ex) + { + logger.warn("could not load pam module", ex); + } + + AuthenticationResult result = AuthenticationResult.NOT_FOUND; + + if (pam != null) + { + if (CLibrary.libc.getpwnam(username) != null) + { + try + { + UnixUser user = pam.authenticate(username, password); + + if (user != null) + { + result = new AuthenticationResult(new User(username, username, + null)); + } + } + catch (PAMException ex) + { + result = AuthenticationResult.FAILED; + } + } + } + + return result; + } + + /** + * Method description + * + * + * @throws IOException + */ + @Override + public void close() throws IOException + { + + // do nothing + } + + /** + * Method description + * + * + * @param context + */ + @Override + public void init(SCMContextProvider context) + { + config = store.get(); + + if (config == null) + { + config = new PAMConfig(); + store.set(config); + } + } + + /** + * Method description + * + */ + public void storeConfig() + { + store.set(config); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public PAMConfig getConfig() + { + return config; + } + + /** + * Method description + * + * + * @return + */ + @Override + public String getType() + { + return TYPE; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param config + */ + public void setConfig(PAMConfig config) + { + this.config = config; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private PAMConfig config; + + /** Field description */ + private Store store; +} diff --git a/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfig.java b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfig.java new file mode 100644 index 0000000000..ccc59cd22f --- /dev/null +++ b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfig.java @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.pam; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "pam-config") +@XmlAccessorType(XmlAccessType.FIELD) +public class PAMConfig +{ + + /** + * Method description + * + * + * @return + */ + public String getServiceName() + { + return serviceName; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param serviceName + */ + public void setServiceName(String serviceName) + { + this.serviceName = serviceName; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlElement(name = "service-name") + private String serviceName = "sshd"; +} diff --git a/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfigResource.java b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfigResource.java new file mode 100644 index 0000000000..1a1d2c024d --- /dev/null +++ b/plugins/scm-pam-plugin/src/main/java/sonia/scm/pam/PAMConfigResource.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.pam; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +@Path("config/auth/pam") +public class PAMConfigResource +{ + + /** + * Constructs ... + * + * + * @param authenticationHandler + */ + @Inject + public PAMConfigResource(PAMAuthenticationHandler authenticationHandler) + { + this.authenticationHandler = authenticationHandler; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @GET + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public PAMConfig getConfig() + { + return authenticationHandler.getConfig(); + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param uriInfo + * @param config + * + * @return + * + * @throws IOException + */ + @POST + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public Response setConfig(@Context UriInfo uriInfo, PAMConfig config) + throws IOException + { + authenticationHandler.setConfig(config); + authenticationHandler.storeConfig(); + + return Response.created(uriInfo.getRequestUri()).build(); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private PAMAuthenticationHandler authenticationHandler; +} diff --git a/plugins/scm-pam-plugin/src/main/resources/META-INF/scm/plugin.xml b/plugins/scm-pam-plugin/src/main/resources/META-INF/scm/plugin.xml new file mode 100644 index 0000000000..3654a09708 --- /dev/null +++ b/plugins/scm-pam-plugin/src/main/resources/META-INF/scm/plugin.xml @@ -0,0 +1,51 @@ + + + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + ${project.name} + ${project.description} + Sebastian Sdorra + ${project.url} + + + + + + + diff --git a/plugins/scm-pam-plugin/src/main/resources/sonia/scm/pam/sonia.pam.js b/plugins/scm-pam-plugin/src/main/resources/sonia/scm/pam/sonia.pam.js new file mode 100644 index 0000000000..e0551e3dca --- /dev/null +++ b/plugins/scm-pam-plugin/src/main/resources/sonia/scm/pam/sonia.pam.js @@ -0,0 +1,80 @@ +/* * + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + +registerGeneralConfigPanel({ + xtype : 'configForm', + title : 'PAM Authentication', + items : [{ + xtype : 'textfield', + fieldLabel : 'Service name', + name : 'service-name', + allowBlank : false + }], + + onSubmit: function(values){ + this.el.mask('Submit ...'); + Ext.Ajax.request({ + url: restUrl + 'config/auth/pam.json', + method: 'POST', + jsonData: values, + scope: this, + disableCaching: true, + success: function(response){ + this.el.unmask(); + }, + failure: function(){ + this.el.unmask(); + } + }); + }, + + onLoad: function(el){ + var tid = setTimeout( function(){ el.mask('Loading ...'); }, 100); + Ext.Ajax.request({ + url: restUrl + 'config/auth/pam.json', + method: 'GET', + scope: this, + disableCaching: true, + success: function(response){ + var obj = Ext.decode(response.responseText); + this.load(obj); + clearTimeout(tid); + el.unmask(); + }, + failure: function(){ + el.unmask(); + clearTimeout(tid); + alert('failure'); + } + }); + } +}); diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 1d21313113..d8df5e192a 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -260,6 +260,12 @@ 1.0-M6-SNAPSHOT + + sonia.scm.plugins + scm-pam-plugin + 1.0-M6-SNAPSHOT + +