Browse Source

Added PAMUserService for local Linux/Unix/MacOSX account authentication

tags/v1.3.1
James Moger 10 years ago
parent
commit
2659e7430f

+ 1
- 0
.classpath View File

@@ -45,6 +45,7 @@
<classpathentry kind="lib" path="ext/platform-3.5.0.jar" sourcepath="ext/src/platform-3.5.0.jar" />
<classpathentry kind="lib" path="ext/jna-3.5.0.jar" sourcepath="ext/src/jna-3.5.0.jar" />
<classpathentry kind="lib" path="ext/guava-13.0.1.jar" sourcepath="ext/src/guava-13.0.1.jar" />
<classpathentry kind="lib" path="ext/libpam4j-1.7.jar" sourcepath="ext/src/libpam4j-1.7.jar" />
<classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" />
<classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" />
<classpathentry kind="lib" path="ext/selenium-java-2.28.0.jar" sourcepath="ext/src/selenium-java-2.28.0.jar" />

+ 1
- 0
build.moxie View File

@@ -150,6 +150,7 @@ dependencies:
- compile 'com.force.api:force-partner-api:24.0.0' :war
- compile 'org.freemarker:freemarker:2.3.19' :war
- compile 'com.github.dblock.waffle:waffle-jna:1.5' :war
- compile 'org.kohsuke:libpam4j:1.7' :war
- test 'junit'
# Dependencies for Selenium web page testing
- test 'org.seleniumhq.selenium:selenium-java:${selenium.version}' @jar

+ 2
- 0
build.xml View File

@@ -302,6 +302,7 @@
<class name="com.gitblit.RedmineUserService" />
<class name="com.gitblit.SalesforceUserService" />
<class name="com.gitblit.WindowsUserService" />
<class name="com.gitblit.PAMUserService" />
</mx:genjar>
<!-- Build the WAR file -->
@@ -421,6 +422,7 @@
<class name="com.gitblit.RedmineUserService" />
<class name="com.gitblit.SalesforceUserService" />
<class name="com.gitblit.WindowsUserService" />
<class name="com.gitblit.PAMUserService" />
</mx:genjar>
<!-- Build Express Zip file -->

+ 11
- 0
gitblit.iml View File

@@ -468,6 +468,17 @@
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library">
<library name="libpam4j-1.7.jar">
<CLASSES>
<root url="jar://$MODULE_DIR$/ext/libpam4j-1.7.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MODULE_DIR$/ext/src/libpam4j-1.7.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="module-library" scope="TEST">
<library name="junit-4.11.jar">
<CLASSES>

+ 3
- 0
releases.moxie View File

@@ -32,9 +32,12 @@ r18: {
additions:
- Added optional browser-side page caching using Last-Modified and Cache-Control for the dashboard, activity, project, and several repository pages
- Added a GET_USER request type for the RPC mechanism (issue-275)
- Added PAMUserService to authenticate against a local Linux/Unix/MacOSX server
dependencyChanges: ~
settings:
- { name: 'web.pageCacheExpires', defaultValue: 0 }
- { name: 'realm.pam.backingUserService', defaultValue: 'users.conf' }
- { name: 'realm.pam.serviceName', defaultValue: 'system-auth' }
contributors:
- Rainer Alföldi
- Liyu Wang

+ 16
- 0
src/main/distrib/data/gitblit.properties View File

@@ -501,6 +501,7 @@ web.projectsFile = ${baseFolder}/projects.conf
# com.gitblit.RedmineUserService
# com.gitblit.SalesforceUserService
# com.gitblit.WindowsUserService
# com.gitblit.PAMUserService
#
# Any custom user service implementation must have a public default constructor.
#
@@ -1212,6 +1213,21 @@ realm.windows.allowGuests = false
# SINCE 1.3.0
realm.windows.defaultDomain =
# The PAMUserService must be backed by another user service for standard user
# and team management.
# default: users.conf
#
# RESTART REQUIRED
# BASEFOLDER
# SINCE 1.3.1
realm.pam.backingUserService = ${baseFolder}/users.conf
# The PAM service name for authentication.
# default: system-auth
#
# SINCE 1.3.1
realm.pam.serviceName = system-auth
# The SalesforceUserService must be backed by another user service for standard user
# and team management.
# default: users.conf

+ 1
- 1
src/main/java/com/gitblit/Constants.java View File

@@ -480,7 +480,7 @@ public class Constants {
}
public static enum AccountType {
LOCAL, EXTERNAL, LDAP, REDMINE, SALESFORCE, WINDOWS;
LOCAL, EXTERNAL, LDAP, REDMINE, SALESFORCE, WINDOWS, PAM;
public boolean isLocal() {
return this == LOCAL;

+ 142
- 0
src/main/java/com/gitblit/PAMUserService.java View File

@@ -0,0 +1,142 @@
/*
* Copyright 2013 gitblit.com.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gitblit;
import java.io.File;
import org.jvnet.libpam.PAM;
import org.jvnet.libpam.PAMException;
import org.jvnet.libpam.impl.CLibrary;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.Constants.AccountType;
import com.gitblit.models.UserModel;
import com.gitblit.utils.ArrayUtils;
import com.gitblit.utils.StringUtils;
/**
* Implementation of a PAM user service for Linux/Unix/MacOSX.
*
* @author James Moger
*/
public class PAMUserService extends GitblitUserService {
private final Logger logger = LoggerFactory.getLogger(PAMUserService.class);
private IStoredSettings settings;
public PAMUserService() {
super();
}
@Override
public void setup(IStoredSettings settings) {
this.settings = settings;
String file = settings.getString(Keys.realm.pam.backingUserService, "${baseFolder}/users.conf");
File realmFile = GitBlit.getFileOrFolder(file);
serviceImpl = createUserService(realmFile);
logger.info("PAM User Service backed by " + serviceImpl.toString());
// Try to identify the passwd database
String [] files = { "/etc/shadow", "/etc/master.passwd" };
File passwdFile = null;
for (String name : files) {
File f = new File(name);
if (f.exists()) {
passwdFile = f;
break;
}
}
if (passwdFile == null) {
logger.error("PAM User Service could not find a passwd database!");
} else if (!passwdFile.canRead()) {
logger.error("PAM User Service can not read passwd database {}! PAM authentications may fail!", passwdFile);
}
}
@Override
public boolean supportsCredentialChanges() {
return false;
}
@Override
public boolean supportsDisplayNameChanges() {
return true;
}
@Override
public boolean supportsEmailAddressChanges() {
return true;
}
@Override
public boolean supportsTeamMembershipChanges() {
return true;
}
@Override
protected AccountType getAccountType() {
return AccountType.PAM;
}
@Override
public UserModel authenticate(String username, char[] password) {
if (isLocalAccount(username)) {
// local account, bypass PAM authentication
return super.authenticate(username, password);
}
if (CLibrary.libc.getpwnam(username) == null) {
logger.warn("Can not get PAM passwd for " + username);
return null;
}
PAM pam = null;
try {
String serviceName = settings.getString(Keys.realm.pam.serviceName, "system-auth");
pam = new PAM(serviceName);
pam.authenticate(username, new String(password));
} catch (PAMException e) {
logger.error(e.getMessage());
return null;
} finally {
pam.dispose();
}
UserModel user = getUserModel(username);
if (user == null) // create user object for new authenticated user
user = new UserModel(username.toLowerCase());
// create a user cookie
if (StringUtils.isEmpty(user.cookie) && !ArrayUtils.isEmpty(password)) {
user.cookie = StringUtils.getSHA1(user.username + new String(password));
}
// update user attributes from UnixUser
user.accountType = getAccountType();
user.password = Constants.EXTERNAL_ACCOUNT;
// TODO consider mapping PAM groups to teams
// push the changes to the backing user service
super.updateUserModel(user);
return user;
}
}

+ 1
- 0
src/site/features.mkd View File

@@ -37,6 +37,7 @@
- Redmine authentication
- Salesforce.com authentication
- Windows authentication
- PAM authentication
- Gravatar integration
- Git-notes display support
- Submodule support

+ 8
- 0
src/site/setup_authentication.mkd View File

@@ -6,6 +6,7 @@ Gitblit supports additional authentication mechanisms aside from it's internal o
* LDAP authentication
* Windows authentication
* PAM authentication
* Redmine auhentication
* Salesforce.com authentication
* Servlet container authentication
@@ -83,6 +84,13 @@ Windows authentication is based on the use of Waffle and JNA. It is known to wo
realm.userService = com.gitblit.WindowsUserService
realm.windows.defaultDomain =
### PAM Authentication
PAM authentication is based on the use of libpam4j and JNA. To use this service, your Gitblit server must be installed on a Linux/Unix/MacOSX machine and the user that Gitblit runs-as must have root permissions.
realm.userService = com.gitblit.PAMUserService
realm.pam.serviceName = system-auth
### Redmine Authentication
You may authenticate your users against a Redmine installation as long as your Redmine install has properly enabled [API authentication](http://www.redmine.org/projects/redmine/wiki/Rest_Api#Authentication). This user service only supports user authentication; it does not support team creation based on Redmine groups. Redmine administrators will also be Gitblit administrators.

+ 4
- 3
src/site/siteindex.mkd View File

@@ -68,9 +68,10 @@ Administrators can create and manage all repositories, user accounts, and teams
- Groovy push hook scripts
- Pluggable user service mechanism
- LDAP authentication with optional LDAP-controlled Team memberships
- Redmine authentication
- SalesForce.com authentication
- Windows authentication
- Redmine authentication
- SalesForce.com authentication
- Windows authentication
- PAM authentication
- Custom authentication, authorization, and user management
- Rich RSS feeds
- JSON-based RPC mechanism

Loading…
Cancel
Save