1 package fr.in2p3.jsaga.adaptor.security;
2
3 import fr.in2p3.jsaga.adaptor.base.defaults.Default;
4 import fr.in2p3.jsaga.adaptor.base.usage.*;
5 import fr.in2p3.jsaga.adaptor.security.impl.UserPassSecurityCredential;
6 import org.ogf.saga.context.Context;
7 import org.ogf.saga.error.IncorrectStateException;
8 import org.ogf.saga.error.NoSuccessException;
9
10 import java.io.*;
11 import java.util.Map;
12
13
14
15
16
17
18
19
20
21
22
23
24
25 public class UserPassSecurityAdaptor implements ExpirableSecurityAdaptor {
26 private static final String USERPASSFILE = "UserPassFile";
27 private static final int USAGE_INIT = 1;
28 private static final int USAGE_VOLATILE = 2;
29 private static final int USAGE_LOAD = 3;
30
31 public String getType() {
32 return "UserPass";
33 }
34
35 public Class getSecurityCredentialClass() {
36 return UserPassSecurityCredential.class;
37 }
38
39 public Usage getUsage() {
40 return new UAnd.Builder()
41 .and(new U(Context.USERID))
42 .and(new UOr.Builder()
43 .or(new UAnd.Builder()
44 .id(USAGE_INIT)
45 .and(new UHidden(Context.USERPASS))
46 .and(new U(Context.LIFETIME))
47 .and(new UFilePath(USERPASSFILE))
48 .build()
49 )
50 .or(new U(USAGE_VOLATILE, Context.USERPASS))
51 .or(new UFile(USAGE_LOAD, USERPASSFILE))
52 .build()
53 )
54 .build();
55 }
56
57 public Default[] getDefaults(Map attributes) throws IncorrectStateException {
58 return new Default[]{
59 new Default(Context.USERID, System.getProperty("user.name"))
60 };
61 }
62
63 public SecurityCredential createSecurityCredential(int usage, Map attributes, String contextId) throws IncorrectStateException, NoSuccessException {
64 try {
65 switch(usage) {
66 case USAGE_INIT:
67 {
68
69 String name = (String) attributes.get(Context.USERID);
70 String password = (String) attributes.get(Context.USERPASS);
71 int lifetime = (attributes.containsKey(Context.LIFETIME)
72 ? UDuration.toInt(attributes.get(Context.LIFETIME))
73 : 12*3600);
74 File file = new File((String) attributes.get(USERPASSFILE));
75
76
77 PasswordEncrypterSingleton crypter = new PasswordEncrypterSingleton(name, lifetime);
78 String cryptedPassword = crypter.encrypt(password);
79 int expiryDate = PasswordEncrypterSingleton.getExpiryDate(lifetime);
80
81
82 DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
83 out.writeBytes(cryptedPassword);
84 out.close();
85
86
87 return new UserPassExpirableSecurityCredential(name, password, expiryDate);
88 }
89 case USAGE_VOLATILE:
90 {
91 return new UserPassSecurityCredential(
92 (String) attributes.get(Context.USERID),
93 (String) attributes.get(Context.USERPASS));
94 }
95 case USAGE_LOAD:
96 {
97
98 String name = (String) attributes.get(Context.USERID);
99 File file = new File((String) attributes.get(USERPASSFILE));
100
101
102 byte[] buffer = new byte[(int) file.length()];
103 DataInputStream in = new DataInputStream(new FileInputStream(file));
104 in.readFully(buffer);
105 in.close();
106 String cryptedPassword = new String(buffer);
107
108
109 PasswordDecrypterSingleton decrypter = new PasswordDecrypterSingleton(name);
110 int expiryDate = decrypter.getExpiryDate();
111 int currentDate = (int) (System.currentTimeMillis()/1000);
112 String password;
113 if (currentDate > expiryDate) {
114 this.destroySecurityAdaptor(attributes, contextId);
115 password = null;
116 } else {
117 password = decrypter.decrypt(cryptedPassword);
118 }
119 return new UserPassExpirableSecurityCredential(name, password, expiryDate);
120 }
121 default:
122 throw new NoSuccessException("INTERNAL ERROR: unexpected exception");
123 }
124 } catch(IncorrectStateException e) {
125 throw e;
126 } catch(NoSuccessException e) {
127 throw e;
128 } catch(Exception e) {
129 throw new NoSuccessException(e);
130 }
131 }
132
133 public void destroySecurityAdaptor(Map attributes, String contextId) throws Exception {
134 File file = new File((String) attributes.get(USERPASSFILE));
135 if (file.exists() && !file.delete()) {
136 throw new Exception("Failed to delete file: "+file);
137 }
138 }
139 }