summaryrefslogtreecommitdiff
path: root/backend/python
Unidiff
Diffstat (limited to 'backend/python') (more/less context) (ignore whitespace changes)
-rw-r--r--backend/python/src/clipperz.py19
1 files changed, 8 insertions, 11 deletions
diff --git a/backend/python/src/clipperz.py b/backend/python/src/clipperz.py
index c8d91de..bd5d030 100644
--- a/backend/python/src/clipperz.py
+++ b/backend/python/src/clipperz.py
@@ -1,281 +1,278 @@
1 # 1#
2 #Copyright 2008-2011 Clipperz Srl 2 #Copyright 2008-2011 Clipperz Srl
3 # 3 #
4 #This file is part of Clipperz's Javascript Crypto Library. 4 #This file is part of Clipperz Community Edition.
5 #Javascript Crypto Library provides web developers with an extensive 5 #Clipperz Community Edition is an online password manager.
6 #and efficient set of cryptographic functions. The library aims to
7 #obtain maximum execution speed while preserving modularity and
8 #reusability.
9 #For further information about its features and functionalities please 6 #For further information about its features and functionalities please
10 #refer to http://www.clipperz.com 7 #refer to http://www.clipperz.com.
11 # 8 #
12 #* Javascript Crypto Library is free software: you can redistribute 9 #* Clipperz Community Edition is free software: you can redistribute
13 # it and/or modify it under the terms of the GNU Affero General Public 10 # it and/or modify it under the terms of the GNU Affero General Public
14 # License as published by the Free Software Foundation, either version 11 # License as published by the Free Software Foundation, either version
15 # 3 of the License, or (at your option) any later version. 12 # 3 of the License, or (at your option) any later version.
16 # 13 #
17 #* Javascript Crypto Library is distributed in the hope that it will 14 #* Clipperz Community Edition is distributed in the hope that it will
18 # be useful, but WITHOUT ANY WARRANTY; without even the implied 15 # be useful, but WITHOUT ANY WARRANTY; without even the implied
19 # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 # See the GNU Affero General Public License for more details. 17 # See the GNU Affero General Public License for more details.
21 # 18 #
22 #* You should have received a copy of the GNU Affero General Public 19 #* You should have received a copy of the GNU Affero General Public
23 # License along with Javascript Crypto Library. If not, see 20 # License along with Clipperz Community Edition. If not, see
24 # <http://www.gnu.org/licenses/>. 21 # <http://www.gnu.org/licenses/>.
25 # 22#
26 23
27import os 24import os
28import cgi 25import cgi
29import wsgiref.handlers 26import wsgiref.handlers
30 27
31import datetime 28import datetime
32import uuid 29import uuid
33import random 30import random
34import hashlib 31import hashlib
35 32
36import logging 33import logging
37 34
38from google.appengine.api import users 35from google.appengine.api import users
39from google.appengine.ext import webapp 36from google.appengine.ext import webapp
40from google.appengine.ext import db 37from google.appengine.ext import db
41from google.appengine.ext.webapp import template 38from google.appengine.ext.webapp import template
42 39
43from django.utils import simplejson 40from django.utils import simplejson
44 41
45#============================================================================== 42#==============================================================================
46 43
47sessionTimeout = datetime.timedelta(minutes=-2) 44sessionTimeout = datetime.timedelta(minutes=-2)
48 45
49def randomSeed(): 46def randomSeed():
50 return hex(random.getrandbits(32*8))[2:-1] 47 return hex(random.getrandbits(32*8))[2:-1]
51 48
52def clipperzHash(aString): 49def clipperzHash(aString):
53 #logging.info(">>> string: " + aString) 50 #logging.info(">>> string: " + aString)
54 firstRound = hashlib.sha256() 51 firstRound = hashlib.sha256()
55 firstRound.update(aString) 52 firstRound.update(aString)
56 #logging.info("firstRound: " + firstRound.hexdigest() + " - " + firstRound.digest()) 53 #logging.info("firstRound: " + firstRound.hexdigest() + " - " + firstRound.digest())
57 result = hashlib.sha256() 54 result = hashlib.sha256()
58 result.update(firstRound.digest()) 55 result.update(firstRound.digest())
59 #logging.info("<<< finalResul: " + result.hexdigest()) 56 #logging.info("<<< finalResul: " + result.hexdigest())
60 57
61 return result.hexdigest() 58 return result.hexdigest()
62 59
63#============================================================================== 60#==============================================================================
64 61
65class User(db.Model): 62class User(db.Model):
66 username= db.StringProperty() 63 username= db.StringProperty()
67 srp_s = db.StringProperty() 64 srp_s = db.StringProperty()
68 srp_v = db.StringProperty() 65 srp_v = db.StringProperty()
69 header = db.TextProperty() 66 header = db.TextProperty()
70 statistics= db.TextProperty() 67 statistics= db.TextProperty()
71 auth_version= db.StringProperty() 68 auth_version= db.StringProperty()
72 version = db.StringProperty() 69 version = db.StringProperty()
73 lock = db.StringProperty() 70 lock = db.StringProperty()
74 71
75 def updateCredentials(self, someCredentials): 72 def updateCredentials(self, someCredentials):
76 self.username = someCredentials['C'] 73 self.username = someCredentials['C']
77 self.srp_s = someCredentials['s'] 74 self.srp_s = someCredentials['s']
78 self.srp_v = someCredentials['v'] 75 self.srp_v = someCredentials['v']
79 self.auth_version= someCredentials['version'] 76 self.auth_version= someCredentials['version']
80 77
81 def update(self, someData): 78 def update(self, someData):
82 self.header = someData['header'] 79 self.header = someData['header']
83 self.statistics= someData['statistics'] 80 self.statistics= someData['statistics']
84 self.version= someData['version'] 81 self.version= someData['version']
85 self.lock = someData['lock'] 82 self.lock = someData['lock']
86 83
87#------------------------------------------------------------------------------ 84#------------------------------------------------------------------------------
88 85
89class Record(db.Model): 86class Record(db.Model):
90 user = db.ReferenceProperty(User) 87 user = db.ReferenceProperty(User)
91 reference = db.StringProperty() 88 reference = db.StringProperty()
92 data = db.TextProperty() 89 data = db.TextProperty()
93 version = db.StringProperty() 90 version = db.StringProperty()
94 creation_date= db.DateTimeProperty(auto_now_add=True) 91 creation_date= db.DateTimeProperty(auto_now_add=True)
95 update_date = db.DateTimeProperty(auto_now_add=True) 92 update_date = db.DateTimeProperty(auto_now_add=True)
96 access_date = db.DateTimeProperty(auto_now_add=True) 93 access_date = db.DateTimeProperty(auto_now_add=True)
97 94
98#------------------------------------------------------------------------------ 95#------------------------------------------------------------------------------
99 96
100class RecordVersion(db.Model): 97class RecordVersion(db.Model):
101 record = db.ReferenceProperty(Record) 98 record = db.ReferenceProperty(Record)
102 reference = db.StringProperty() 99 reference = db.StringProperty()
103 header = db.TextProperty() 100 header = db.TextProperty()
104 data = db.TextProperty() 101 data = db.TextProperty()
105 version = db.StringProperty() 102 version = db.StringProperty()
106 previousVersionKey= db.StringProperty() 103 previousVersionKey= db.StringProperty()
107 previousVersion = db.SelfReferenceProperty() 104 previousVersion = db.SelfReferenceProperty()
108 creation_date = db.DateTimeProperty(auto_now_add=True) 105 creation_date = db.DateTimeProperty(auto_now_add=True)
109 update_date = db.DateTimeProperty(auto_now_add=True) 106 update_date = db.DateTimeProperty(auto_now_add=True)
110 access_date = db.DateTimeProperty(auto_now_add=True) 107 access_date = db.DateTimeProperty(auto_now_add=True)
111 108
112 def update(self, someData): 109 def update(self, someData):
113 recordData = someData['record']; 110 recordData = someData['record'];
114 self.parent().reference =recordData['reference'] 111 self.parent().reference =recordData['reference']
115 self.parent().data = recordData['data'] 112 self.parent().data = recordData['data']
116 self.parent().version = recordData['version'] 113 self.parent().version = recordData['version']
117 self.parent().update_date =datetime.datetime.now() 114 self.parent().update_date =datetime.datetime.now()
118 115
119 recordVersionData = someData['currentRecordVersion']; 116 recordVersionData = someData['currentRecordVersion'];
120 self.reference = recordVersionData ['reference'] 117 self.reference = recordVersionData ['reference']
121 self.data = recordVersionData ['data'] 118 self.data = recordVersionData ['data']
122 self.version = recordVersionData ['version'] 119 self.version = recordVersionData ['version']
123 #self.previous_version =#recordVersionData ['previousVersion'] 120 #self.previous_version =#recordVersionData ['previousVersion']
124 self.previous_version_key =recordVersionData ['previousVersionKey'] 121 self.previous_version_key =recordVersionData ['previousVersionKey']
125 self.update_date = datetime.datetime.now() 122 self.update_date = datetime.datetime.now()
126 123
127#------------------------------------------------------------------------------ 124#------------------------------------------------------------------------------
128 125
129class OneTimePassword(db.Model): 126class OneTimePassword(db.Model):
130 user = db.ReferenceProperty(User) 127 user = db.ReferenceProperty(User)
131 status = db.StringProperty() 128 status = db.StringProperty()
132 reference = db.StringProperty() 129 reference = db.StringProperty()
133 keyValue = db.StringProperty() 130 keyValue = db.StringProperty()
134 keyChecksum = db.StringProperty() 131 keyChecksum = db.StringProperty()
135 data = db.TextProperty() 132 data = db.TextProperty()
136 version = db.StringProperty() 133 version = db.StringProperty()
137 creation_date= db.DateTimeProperty(auto_now_add=True) 134 creation_date= db.DateTimeProperty(auto_now_add=True)
138 request_date= db.DateTimeProperty() 135 request_date= db.DateTimeProperty()
139 usage_date = db.DateTimeProperty() 136 usage_date = db.DateTimeProperty()
140 137
141 def update(self, someParameters, aStatus): 138 def update(self, someParameters, aStatus):
142 self.reference = someParameters['reference'] 139 self.reference = someParameters['reference']
143 self.keyValue = someParameters['key'] 140 self.keyValue = someParameters['key']
144 self.keyChecksum = someParameters['keyChecksum'] 141 self.keyChecksum = someParameters['keyChecksum']
145 self.data = someParameters['data'] 142 self.data = someParameters['data']
146 self.version = someParameters['version'] 143 self.version = someParameters['version']
147 self.status = aStatus 144 self.status = aStatus
148 145
149 def reset(self, aStatus): 146 def reset(self, aStatus):
150 self.data = "" 147 self.data = ""
151 self.status =aStatus 148 self.status =aStatus
152 149
153 return self 150 return self
154 151
155#------------------------------------------------------------------------------ 152#------------------------------------------------------------------------------
156 153
157class Session(db.Expando): 154class Session(db.Expando):
158 sessionId= db.StringProperty() 155 sessionId= db.StringProperty()
159 access_date= db.DateTimeProperty() 156 access_date= db.DateTimeProperty()
160 157
161#============================================================================== 158#==============================================================================
162 159
163class MainPage(webapp.RequestHandler): 160class MainPage(webapp.RequestHandler):
164 def get(self): 161 def get(self):
165 path = os.path.join(os.path.dirname(__file__), 'static%s' % self.request.path) 162 path = os.path.join(os.path.dirname(__file__), 'static%s' % self.request.path)
166 self.response.out.write(template.render(path, {})) 163 self.response.out.write(template.render(path, {}))
167 164
168#============================================================================== 165#==============================================================================
169 166
170class XHR(webapp.RequestHandler): 167class XHR(webapp.RequestHandler):
171 168
172 #========================================================================== 169 #==========================================================================
173 170
174 def get(self): 171 def get(self):
175 logging.info("self.request.path: " + self.request.path) 172 logging.info("self.request.path: " + self.request.path)
176 if self.request.path == "/dump": 173 if self.request.path == "/dump":
177 session = self.getSession() 174 session = self.getSession()
178 userData = {} 175 userData = {}
179 offline_data_placeholder = "" 176 offline_data_placeholder = ""
180 177
181 user = db.Query(User).filter('username =', session.C).get() 178 user = db.Query(User).filter('username =', session.C).get()
182 179
183 userData['users'] = { 180 userData['users'] = {
184 'catchAllUser': { 181 'catchAllUser': {
185 '__masterkey_test_value__': 'masterkey', 182 '__masterkey_test_value__': 'masterkey',
186 's': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', 183 's': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
187 'v': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' 184 'v': '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
188 } 185 }
189 } 186 }
190 187
191 records = {} 188 records = {}
192 for currentRecord in db.Query(Record).ancestor(user): 189 for currentRecord in db.Query(Record).ancestor(user):
193 versions = {} 190 versions = {}
194 for currentVersion in db.Query(RecordVersion).ancestor(currentRecord): 191 for currentVersion in db.Query(RecordVersion).ancestor(currentRecord):
195 versions[currentVersion.reference] ={ 192 versions[currentVersion.reference] ={
196 'header': currentVersion.header, 193 'header': currentVersion.header,
197 'data': currentVersion.data, 194 'data': currentVersion.data,
198 'version': currentVersion.version, 195 'version': currentVersion.version,
199 'creationDate':str(currentVersion.creation_date), 196 'creationDate':str(currentVersion.creation_date),
200 'updateDate':str(currentVersion.update_date), 197 'updateDate':str(currentVersion.update_date),
201 'accessDate':str(currentVersion.access_date) 198 'accessDate':str(currentVersion.access_date)
202 } 199 }
203 200
204 records[currentRecord.reference] = { 201 records[currentRecord.reference] = {
205 'data': currentRecord.data, 202 'data': currentRecord.data,
206 'version': currentRecord.version, 203 'version': currentRecord.version,
207 'creationDate': str(currentRecord.creation_date), 204 'creationDate': str(currentRecord.creation_date),
208 'updateDate': str(currentRecord.update_date), 205 'updateDate': str(currentRecord.update_date),
209 'accessDate': str(currentRecord.access_date), 206 'accessDate': str(currentRecord.access_date),
210 'currentVersion':currentVersion.reference, 207 'currentVersion':currentVersion.reference,
211 'versions': versions 208 'versions': versions
212 } 209 }
213 210
214 userData['users'][user.username] = { 211 userData['users'][user.username] = {
215 's': user.srp_s, 212 's': user.srp_s,
216 'v': user.srp_v, 213 'v': user.srp_v,
217 'version': user.auth_version, 214 'version': user.auth_version,
218 'maxNumberOfRecords':'100', 215 'maxNumberOfRecords':'100',
219 'userDetails': user.header, 216 'userDetails': user.header,
220 'statistics': user.statistics, 217 'statistics': user.statistics,
221 'userDetailsVersion':user.version, 218 'userDetailsVersion':user.version,
222 'records': records 219 'records': records
223 } 220 }
224 221
225 offline_data_placeholder = offline_data_placeholder + "_clipperz_dump_data_ = " + simplejson.dumps(userData, indent=4) + "\n" 222 offline_data_placeholder = offline_data_placeholder + "_clipperz_dump_data_ = " + simplejson.dumps(userData, indent=4) + "\n"
226 offline_data_placeholder = offline_data_placeholder + "Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline();" + "\n" 223 offline_data_placeholder = offline_data_placeholder + "Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline();" + "\n"
227 offline_data_placeholder = offline_data_placeholder + "Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();" + "\n" 224 offline_data_placeholder = offline_data_placeholder + "Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();" + "\n"
228 225
229 path = os.path.join(os.path.dirname(__file__), 'static/dump.html') 226 path = os.path.join(os.path.dirname(__file__), 'static/dump.html')
230 227
231 self.response.headers.add_header('Content-Type', 'text/html') 228 self.response.headers.add_header('Content-Type', 'text/html')
232 self.response.headers.add_header('Content-Disposition', 'attachment', filename='Clipperz.html') 229 self.response.headers.add_header('Content-Disposition', 'attachment', filename='Clipperz.html')
233 self.response.out.write(template.render(path, {'offline_data_placeholder': offline_data_placeholder})) 230 self.response.out.write(template.render(path, {'offline_data_placeholder': offline_data_placeholder}))
234 231
235 #========================================================================== 232 #==========================================================================
236 233
237 def post(self): 234 def post(self):
238 method = self.request.get('method') 235 method = self.request.get('method')
239 parameters = simplejson.loads(self.request.get('parameters')) 236 parameters = simplejson.loads(self.request.get('parameters'))
240 session = self.getSession() 237 session = self.getSession()
241 result = {}; 238 result = {};
242 239
243 #---------------------------------------------------------------------- 240 #----------------------------------------------------------------------
244 241
245 if method == 'registration': 242 if method == 'registration':
246 message = parameters['message']; 243 message = parameters['message'];
247 244
248 if message == 'completeRegistration': 245 if message == 'completeRegistration':
249 user = User() 246 user = User()
250 247
251 user.updateCredentials(parameters['credentials']) 248 user.updateCredentials(parameters['credentials'])
252 user.update(parameters['user']) 249 user.update(parameters['user'])
253 user.put() 250 user.put()
254 251
255 result['lock'] = user.lock 252 result['lock'] = user.lock
256 result['result'] = "done" 253 result['result'] = "done"
257 254
258 #---------------------------------------------------------------------- 255 #----------------------------------------------------------------------
259 256
260 elif method == 'handshake': 257 elif method == 'handshake':
261 srp_g = 2L 258 srp_g = 2L
262 srp_n = long("0x%s" % "115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16) 259 srp_n = long("0x%s" % "115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16)
263 260
264 message = parameters['message']; 261 message = parameters['message'];
265 262
266 #------------------------------------------------------------------ 263 #------------------------------------------------------------------
267 264
268 if message == 'connect': 265 if message == 'connect':
269 session.C = parameters['parameters']['C'] 266 session.C = parameters['parameters']['C']
270 session.A = parameters['parameters']['A'] 267 session.A = parameters['parameters']['A']
271 268
272 user = db.Query(User).filter('username =', session.C).get() 269 user = db.Query(User).filter('username =', session.C).get()
273 270
274 if user != None: 271 if user != None:
275 try: 272 try:
276 optId = session.otpId 273 optId = session.otpId
277 274
278 oneTimePassword = db.Query(OneTimePassword).filter('keyValue =', optId).get() 275 oneTimePassword = db.Query(OneTimePassword).filter('keyValue =', optId).get()
279 276
280 if oneTimePassword.parent().username != user.username: 277 if oneTimePassword.parent().username != user.username:
281 oneTimePassword.reset('DISABLED').put() 278 oneTimePassword.reset('DISABLED').put()