1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package net.sf.jguard.ext.authentication.loginmodules;
29
30 import java.io.IOException;
31 import java.lang.reflect.Array;
32 import java.security.cert.CertificateParsingException;
33 import java.security.cert.X509Certificate;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Set;
39
40 import java.util.logging.Level;
41 import javax.security.auth.Subject;
42 import javax.security.auth.callback.Callback;
43 import javax.security.auth.callback.CallbackHandler;
44 import javax.security.auth.callback.UnsupportedCallbackException;
45 import javax.security.auth.login.LoginException;
46 import javax.security.auth.spi.LoginModule;
47
48 import net.sf.jguard.core.authentication.credentials.JGuardCredential;
49 import net.sf.jguard.ext.SecurityConstants;
50 import net.sf.jguard.ext.authentication.callbacks.CertificatesCallback;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54
55
56
57
58
59
60
61 public abstract class CertificateLoginModule implements LoginModule {
62
63
64 private static final Logger logger = LoggerFactory.getLogger(CertificateLoginModule.class.getName());
65 protected Subject subject;
66 protected boolean loginOK = true;
67 protected X509Certificate[] certChainToCheck;
68 protected CallbackHandler callbackHandler;
69
70
71
72
73 public boolean abort() throws LoginException {
74 if(subject!= null){
75 subject.getPrincipals().clear();
76 subject.getPrivateCredentials().clear();
77 subject.getPublicCredentials().clear();
78 }
79 return true;
80 }
81 public boolean commit() throws LoginException {
82 if(loginOK){
83 return certificateCommit();
84 }else{
85 return false;
86 }
87 }
88
89
90
91
92
93
94
95 public boolean logout() throws LoginException {
96 subject.getPrincipals().clear();
97 subject.getPublicCredentials().clear();
98 subject.getPrivateCredentials().clear();
99 return true;
100 }
101
102
103
104 protected boolean certificateCommit() throws LoginException {
105 Set publicCredentials = this.subject.getPublicCredentials();
106 List certs = Arrays.asList(this.certChainToCheck);
107
108 X509Certificate cert = (X509Certificate)certs.get(0);
109 subject.getPrincipals().add(cert.getSubjectX500Principal());
110
111
112 if(cert.getSubjectUniqueID()!=null){
113 JGuardCredential credential1 = new JGuardCredential();
114 credential1.setName(SecurityConstants.UNIQUE_ID);
115 credential1.setValue(cert.getSubjectUniqueID());
116 publicCredentials.add(credential1);
117 }
118
119 Collection altNames=null;
120 try {
121 altNames = cert.getSubjectAlternativeNames();
122 } catch (CertificateParsingException e) {
123 logger.error(" certificate cannot be parsed ");
124
125 throw new LoginException(e.getMessage());
126 }
127 if(altNames==null){
128 return true;
129 }
130 int count = 0;
131
132 Iterator itAltNames = altNames.iterator();
133 while(itAltNames.hasNext()){
134 List extensionEntry = (List)itAltNames.next();
135 Integer nameType = (Integer) extensionEntry.get(0);
136 Object name = extensionEntry.get(1);
137 byte[] nameAsBytes = null;
138 JGuardCredential credential = new JGuardCredential();
139 credential.setName(SecurityConstants.ALTERNATIVE_NAME+"#"+count);
140 if(name instanceof Array){
141 nameAsBytes = (byte[]) name;
142 }
143 if(nameAsBytes!= null){
144 credential.setValue(nameType+"#"+new String(nameAsBytes));
145 }else{
146 credential.setValue(nameType+"#"+(String)name);
147 }
148 publicCredentials.add(credential);
149 count++;
150 }
151
152 return true;
153 }
154
155
156 public boolean login()throws LoginException{
157 if (callbackHandler == null) {
158 loginOK = false;
159 throw new LoginException("there is no CallbackHandler to authenticate the user");
160 }
161 Callback[] callbacks = new Callback[1];
162 callbacks[0] = new CertificatesCallback();
163 try {
164 callbackHandler.handle(callbacks);
165 } catch (IOException e1) {
166 logger.error( " IOException when we handle callbacks with callback " + callbackHandler.getClass().getName(), e1);
167 } catch (UnsupportedCallbackException e1) {
168 logger.error( " one callback type is not supported ", e1);
169 }
170 certChainToCheck = ((CertificatesCallback) callbacks[0]).getCertificates();
171 if (certChainToCheck == null ||certChainToCheck.length==0) {
172 loginOK = false;
173
174 return false;
175 }
176 return true;
177 }
178 }