1 package org.mortbay.jetty.servlet;
2
3 import java.security.NoSuchAlgorithmException;
4 import java.security.SecureRandom;
5 import java.util.Random;
6
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpSession;
9
10 import org.mortbay.component.AbstractLifeCycle;
11 import org.mortbay.jetty.Server;
12 import org.mortbay.jetty.SessionIdManager;
13 import org.mortbay.log.Log;
14
15 public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager
16 {
17 private final static String __NEW_SESSION_ID="org.mortbay.jetty.newSessionId";
18 protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG";
19 protected final static String SESSION_ID_RANDOM_ALGORITHM_ALT = "IBMSecureRandom";
20
21 protected Random _random;
22 protected boolean _weakRandom;
23 protected String _workerName;
24 protected Server _server;
25
26
27 public AbstractSessionIdManager(Server server)
28 {
29 _server=server;
30 }
31
32
33 public AbstractSessionIdManager(Server server, Random random)
34 {
35 _random=random;
36 _server=server;
37 }
38
39 public String getWorkerName()
40 {
41 return _workerName;
42 }
43
44 public void setWorkerName (String name)
45 {
46 _workerName=name;
47 }
48
49
50 public Random getRandom()
51 {
52 return _random;
53 }
54
55
56 public void setRandom(Random random)
57 {
58 _random=random;
59 _weakRandom=false;
60 }
61
62
63
64
65
66 public String newSessionId(HttpServletRequest request, long created)
67 {
68 synchronized (this)
69 {
70
71 String requested_id=request.getRequestedSessionId();
72 if (requested_id!=null)
73 {
74 String cluster_id=getClusterId(requested_id);
75 if (idInUse(cluster_id))
76 return cluster_id;
77 }
78
79
80 String new_id=(String)request.getAttribute(__NEW_SESSION_ID);
81 if (new_id!=null&&idInUse(new_id))
82 return new_id;
83
84
85
86
87 String id=null;
88 while (id==null||id.length()==0||idInUse(id))
89 {
90 long r=_weakRandom
91 ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^(((long)request.hashCode())<<32))
92 :_random.nextLong();
93 r^=created;
94 if (request!=null && request.getRemoteAddr()!=null)
95 r^=request.getRemoteAddr().hashCode();
96 if (r<0)
97 r=-r;
98 id=Long.toString(r,36);
99
100
101
102 id=_workerName + id;
103 }
104
105 request.setAttribute(__NEW_SESSION_ID,id);
106 return id;
107 }
108 }
109
110
111 public void doStart()
112 {
113 initRandom();
114 }
115
116
117
118
119
120
121
122
123
124 public void initRandom ()
125 {
126 if (_random==null)
127 {
128 try
129 {
130 _random=SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM);
131 }
132 catch (NoSuchAlgorithmException e)
133 {
134 try
135 {
136 _random=SecureRandom.getInstance(SESSION_ID_RANDOM_ALGORITHM_ALT);
137 _weakRandom=false;
138 }
139 catch (NoSuchAlgorithmException e_alt)
140 {
141 Log.warn("Could not generate SecureRandom for session-id randomness",e);
142 _random=new Random();
143 _weakRandom=true;
144 }
145 }
146 }
147 _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory());
148 }
149 }