Skip to content

Instantly share code, notes, and snippets.

@jamshid
Created June 8, 2017 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamshid/d03bb69f6a9076b178d73e69ee5446c4 to your computer and use it in GitHub Desktop.
Save jamshid/d03bb69f6a9076b178d73e69ee5446c4 to your computer and use it in GitHub Desktop.
/**
* Can download libpam4j and JNA jars from:
* http://mvnrepository.com/artifact/org.kohsuke/libpam4j
* https://github.com/twall/jna
* https://github.com/matthiasblaesing/libpam4j/commits/gc_and_threadsave
*
* SETUP: useradd zuser1 ; echo zuser1:password | chpasswd ; useradd zuser2 ; echo zuser2:password | chpasswd
* BUILD 1.8: javac -classpath ./jna-4.0.0.jar:./libpam4j-1.8.jar:. PAMTest.java
* BUILD 1.9X: javac -classpath ./jna-4.1.0.jar:./libpam4j-1.9X.jar:. PAMTest.java
* FAILS: sudo java -classpath ./jna-4.0.0.jar:./libpam4j-1.8.jar:. PAMTest zuser1:password zuser2:password
* SUCCEEDS: sudo java -classpath ./jna-4.1.0.jar:./libpam4j-1.9X.jar:. PAMTest zuser1:password zuser2:password
*/
import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.*;
import org.jvnet.libpam.PAM;
import org.jvnet.libpam.UnixUser;
public class PAMTest {
public static String getRandom (Set<String> e) {
return e.stream()
.skip((int) (e.size() * Math.random()))
.findFirst().get();
}
public static void main(String[] argv) {
if (argv.length == 0) {
System.err.println("Time PAM authentication with: PAMTest user1:password1 user2:password2");
System.exit(1);
}
String rando = null;
try {
Map<String,String> users = new HashMap<String,String>(argv.length);
for (int i = 0; i < argv.length; ++i) {
String[] parts = argv[i].split(":");
if (parts.length != 2) {
System.err.println("Expected arguments with username:password, not " + argv[i]);
System.exit(1);
}
users.put(parts[0], parts[1]);
}
Set<String> userNames = users.keySet();
Set<UnixUser> allUsers = new HashSet<UnixUser>();
PAM pam = null;
int counter = 0;
while (true) {
rando = getRandom(userNames);
try {
long fullstart = System.currentTimeMillis();
if (pam == null) {
pam = new PAM("login");
}
long start = System.currentTimeMillis();
UnixUser u = pam.authenticate(rando, users.get(rando));
System.out.println("DEBUG: pam.authenticate=" + (System.currentTimeMillis() - start) + "ms / " + (System.currentTimeMillis() - fullstart) + "ms, User " + u.getUserName() + " " + u.getUID() + " " + u.getGID() + " " + u.getDir() + " " + u.getGecos() + " " + u.getShell() + " in " + u.getGroups());
allUsers.add(u);
} catch (Exception e) {
System.out.println("Exception for user '" + rando + "', wrong password? " + e);
e.printStackTrace();
throw e;
} finally {
if (pam != null && ++counter % 10 == 0) {
long start = System.currentTimeMillis();
pam.dispose();
pam = null;
System.out.println("DISPOSE: " + (System.currentTimeMillis() - start));
}
}
/*
int count = 0;
for (UnixUser u : allUsers) {
System.out.println("DEBUG: " + ++count + ". user: " + u);
System.out.println("DEBUG: " + u.getUserName() + " " + u.getUID() + " " + u.getGID() + " " + u.getDir() + " " + u.getGecos() + " " + u.getShell() + " in " + u.getGroups());
}
*/
}
} catch (Exception e) {
System.out.println("Exception for user '" + rando + "', wrong password? " + e);
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment