rmega 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -0
  3. data/CHANGELOG.md +16 -0
  4. data/README.md +1 -1
  5. data/TODO.md +3 -5
  6. data/bin/rmega-dl +47 -0
  7. data/bin/rmega-up +31 -0
  8. data/lib/rmega.rb +35 -3
  9. data/lib/rmega/api_response.rb +80 -0
  10. data/lib/rmega/cli.rb +121 -0
  11. data/lib/rmega/crypto.rb +20 -0
  12. data/lib/rmega/crypto/aes_cbc.rb +46 -0
  13. data/lib/rmega/crypto/aes_ctr.rb +15 -84
  14. data/lib/rmega/crypto/aes_ecb.rb +25 -0
  15. data/lib/rmega/crypto/rsa.rb +21 -12
  16. data/lib/rmega/errors.rb +3 -51
  17. data/lib/rmega/loggable.rb +0 -3
  18. data/lib/rmega/net.rb +56 -0
  19. data/lib/rmega/nodes/deletable.rb +0 -3
  20. data/lib/rmega/nodes/downloadable.rb +73 -30
  21. data/lib/rmega/nodes/expandable.rb +14 -10
  22. data/lib/rmega/nodes/factory.rb +30 -17
  23. data/lib/rmega/nodes/file.rb +0 -4
  24. data/lib/rmega/nodes/folder.rb +4 -14
  25. data/lib/rmega/nodes/inbox.rb +0 -2
  26. data/lib/rmega/nodes/node.rb +48 -25
  27. data/lib/rmega/nodes/node_key.rb +44 -0
  28. data/lib/rmega/nodes/root.rb +0 -4
  29. data/lib/rmega/nodes/trash.rb +0 -3
  30. data/lib/rmega/nodes/uploadable.rb +42 -33
  31. data/lib/rmega/not_inspectable.rb +10 -0
  32. data/lib/rmega/options.rb +22 -5
  33. data/lib/rmega/pool.rb +18 -7
  34. data/lib/rmega/progress.rb +53 -13
  35. data/lib/rmega/session.rb +125 -52
  36. data/lib/rmega/storage.rb +25 -21
  37. data/lib/rmega/utils.rb +23 -183
  38. data/lib/rmega/version.rb +2 -1
  39. data/rmega.gemspec +3 -5
  40. data/spec/integration/file_download_spec.rb +14 -32
  41. data/spec/integration/file_integrity_spec.rb +41 -0
  42. data/spec/integration/file_upload_spec.rb +11 -57
  43. data/spec/integration/folder_download_spec.rb +17 -0
  44. data/spec/integration/folder_operations_spec.rb +30 -30
  45. data/spec/integration/login_spec.rb +3 -3
  46. data/spec/integration/resume_download_spec.rb +53 -0
  47. data/spec/integration_spec_helper.rb +9 -4
  48. data/spec/rmega/lib/cli_spec.rb +12 -0
  49. data/spec/rmega/lib/session_spec.rb +31 -0
  50. data/spec/rmega/lib/storage_spec.rb +27 -0
  51. data/spec/rmega/lib/utils_spec.rb +16 -78
  52. data/spec/spec_helper.rb +1 -4
  53. metadata +30 -40
  54. data/lib/rmega/crypto/aes.rb +0 -35
  55. data/lib/rmega/crypto/crypto.rb +0 -107
  56. data/lib/rmega/crypto/rsa_mega.js +0 -455
  57. data/spec/rmega/lib/crypto/aes_spec.rb +0 -12
  58. data/spec/rmega/lib/crypto/crypto_spec.rb +0 -27
@@ -1,35 +0,0 @@
1
- require 'openssl'
2
-
3
- module Rmega
4
- module Crypto
5
- module Aes
6
- extend self
7
-
8
- def packing
9
- 'l>*'
10
- end
11
-
12
- def cipher
13
- @cipher ||= OpenSSL::Cipher::AES.new(128, :CBC)
14
- end
15
-
16
- def encrypt(key, data)
17
- cipher.reset
18
- cipher.padding = 0
19
- cipher.encrypt
20
- cipher.key = key.pack(packing)
21
- result = cipher.update data.pack(packing)
22
- result.unpack packing
23
- end
24
-
25
- def decrypt(key, data)
26
- cipher.reset
27
- cipher.padding = 0
28
- cipher.decrypt
29
- cipher.key = key.pack packing
30
- result = cipher.update data.pack(packing)
31
- result.unpack packing
32
- end
33
- end
34
- end
35
- end
@@ -1,107 +0,0 @@
1
- require 'rmega/utils'
2
- require 'rmega/crypto/aes'
3
- require 'rmega/crypto/aes_ctr'
4
- require 'rmega/crypto/rsa'
5
-
6
- module Rmega
7
- module Crypto
8
- extend self
9
-
10
- def random_key
11
- Array.new(6).map { rand(0..0xFFFFFFFF) }
12
- end
13
-
14
- def prepare_key(ary)
15
- pkey = [0x93C467E3,0x7DB0C7A4,0xD1BE3F81,0x0152CB56]
16
- 65536.times do
17
- 0.step(ary.size-1, 4) do |j|
18
- key = [0,0,0,0]
19
- 4.times do |i|
20
- key[i] = ary[i+j] if i+j < ary.size
21
- end
22
- pkey = Aes.encrypt key, pkey
23
- end
24
- end
25
- pkey
26
- end
27
-
28
- def decrypt_rsa_privk(key, privk)
29
- privk = Utils.a32_to_str decrypt_key(key, Utils.base64_to_a32(privk))
30
- rsa_privk = Array.new 4
31
-
32
- # Decompose private key
33
- 4.times do |i|
34
- l = ((privk[0].ord * 256 + privk[1].ord + 7) >> 3) + 2
35
- rsa_privk[i] = Utils.mpi2b privk[0..l-1]
36
- privk = privk[l..-1]
37
- end
38
-
39
- rsa_privk
40
- end
41
-
42
- def decrypt_sid(rsa_privk, csid)
43
- # if csid ...
44
- t = Utils.mpi2b Utils.base64urldecode(csid)
45
-
46
- # TODO - remove execjs and build the key using the ruby lib
47
- # rsa_key = Crypto::Rsa.build_rsa_key rsa_privk
48
- decrypted_t = Rsa.decrypt t, rsa_privk
49
- Utils.base64urlencode Utils.b2s(decrypted_t)[0..42]
50
- end
51
-
52
- def encrypt_attributes(key, attributes_hash)
53
- a32key = key.dup
54
- if a32key.size > 4
55
- a32key = [a32key[0] ^ a32key[4], a32key[1] ^ a32key[5], a32key[2] ^ a32key[6], a32key[3] ^ a32key[7]]
56
- end
57
- attributes_str = "MEGA#{attributes_hash.to_json}"
58
- attributes_str << ("\x00" * (16 - (attributes_str.size % 16)))
59
- Crypto::Aes.encrypt a32key, Utils.str_to_a32(attributes_str)
60
- end
61
-
62
- def decrypt_attributes(key, attributes_base64)
63
- a32key = key.dup
64
- if a32key.size > 4
65
- a32key = [a32key[0] ^ a32key[4], a32key[1] ^ a32key[5], a32key[2] ^ a32key[6], a32key[3] ^ a32key[7]]
66
- end
67
- attributes = Crypto::Aes.decrypt a32key, Utils.base64_to_a32(attributes_base64)
68
- attributes = Utils.a32_to_str attributes
69
- JSON.parse attributes.gsub(/^MEGA/, '').rstrip
70
- end
71
-
72
- def prepare_key_pw(password_str)
73
- prepare_key Utils.str_to_a32(password_str)
74
- end
75
-
76
- def stringhash(aes_key, string)
77
- s32 = Utils::str_to_a32 string
78
- h32 = [0,0,0,0]
79
-
80
- s32.size.times { |i| h32[i & 3] ^= s32[i] }
81
- 16384.times { h32 = Aes.encrypt aes_key, h32 }
82
-
83
- Utils::a32_to_base64 [h32[0],h32[2]]
84
- end
85
-
86
- def encrypt_key(key, data)
87
- return Aes.encrypt(key, data) if data.size == 4
88
- x = []
89
- (0..data.size).step(4) do |i|
90
- # cdata = [data[i] || 0, data[i+1] || 0, data[i+2] || 0, data[i+3] || 0]
91
- cdata = [data[i] || 0, data[i+1] || 0, data[i+2], data[i+3]].compact
92
- x.concat Crypto::Aes.encrypt(key, cdata)
93
- end
94
- x
95
- end
96
-
97
- def decrypt_key(key, data)
98
- return Aes.decrypt(key, data) if data.size == 4
99
- x = []
100
- (0..data.size).step(4) do |i|
101
- cdata = [data[i] || 0, data[i+1] || 0, data[i+2] || 0, data[i+3] || 0]
102
- x.concat Crypto::Aes.decrypt(key, cdata)
103
- end
104
- x
105
- end
106
- end
107
- end
@@ -1,455 +0,0 @@
1
-
2
- /* RSA public key encryption/decryption
3
- * The following functions are (c) 2000 by John M Hanna and are
4
- * released under the terms of the Gnu Public License.
5
- * You must freely redistribute them with their source -- see the
6
- * GPL for details.
7
- * -- Latest version found at http://sourceforge.net/projects/shop-js
8
- *
9
- * Modifications and GnuPG multi precision integer (mpi) conversion added
10
- * 2004 by Herbert Hanewinkel, www.haneWIN.de
11
- */
12
-
13
- // --- Arbitrary Precision Math ---
14
- // badd(a,b), bsub(a,b), bsqr(a), bmul(a,b)
15
- // bdiv(a,b), bmod(a,b), bexpmod(g,e,m), bmodexp(g,e,m)
16
-
17
- // bs is the shift, bm is the mask
18
- // set single precision bits to 28
19
- var bs=28;
20
- var bx2=1<<bs, bm=bx2-1, bx=bx2>>1, bd=bs>>1, bdm=(1<<bd)-1;
21
-
22
- var log2=Math.log(2);
23
-
24
- function zeros(n)
25
- {
26
- var r=new Array(n);
27
-
28
- while(n-->0) r[n]=0;
29
- return r;
30
- }
31
-
32
- function zclip(r)
33
- {
34
- var n = r.length;
35
- if(r[n-1]) return r;
36
- while(n>1 && r[n-1]==0) n--;
37
- return r.slice(0,n);
38
- }
39
-
40
- // returns bit length of integer x
41
- function nbits(x)
42
- {
43
- var n = 1, t;
44
- if((t=x>>>16) != 0) { x = t; n += 16; }
45
- if((t=x>>8) != 0) { x = t; n += 8; }
46
- if((t=x>>4) != 0) { x = t; n += 4; }
47
- if((t=x>>2) != 0) { x = t; n += 2; }
48
- if((t=x>>1) != 0) { x = t; n += 1; }
49
- return n;
50
- }
51
-
52
- function badd(a,b)
53
- {
54
- var al=a.length;
55
- var bl=b.length;
56
-
57
- if(al < bl) return badd(b,a);
58
-
59
- var r=new Array(al);
60
- var c=0, n=0;
61
-
62
- for(; n<bl; n++)
63
- {
64
- c+=a[n]+b[n];
65
- r[n]=c & bm;
66
- c>>>=bs;
67
- }
68
- for(; n<al; n++)
69
- {
70
- c+=a[n];
71
- r[n]=c & bm;
72
- c>>>=bs;
73
- }
74
- if(c) r[n]=c;
75
- return r;
76
- }
77
-
78
- function bsub(a,b)
79
- {
80
- var al=a.length;
81
- var bl=b.length;
82
-
83
- if(bl > al) return [];
84
- if(bl == al)
85
- {
86
- if(b[bl-1] > a[bl-1]) return [];
87
- if(bl==1) return [a[0]-b[0]];
88
- }
89
-
90
- var r=new Array(al);
91
- var c=0;
92
-
93
- for(var n=0; n<bl; n++)
94
- {
95
- c+=a[n]-b[n];
96
- r[n]=c & bm;
97
- c>>=bs;
98
- }
99
- for(;n<al; n++)
100
- {
101
- c+=a[n];
102
- r[n]=c & bm;
103
- c>>=bs;
104
- }
105
- if(c) return [];
106
-
107
- return zclip(r);
108
- }
109
-
110
- function ip(w, n, x, y, c)
111
- {
112
- var xl = x&bdm;
113
- var xh = x>>bd;
114
-
115
- var yl = y&bdm;
116
- var yh = y>>bd;
117
-
118
- var m = xh*yl+yh*xl;
119
- var l = xl*yl+((m&bdm)<<bd)+w[n]+c;
120
- w[n] = l&bm;
121
- c = xh*yh+(m>>bd)+(l>>bs);
122
- return c;
123
- }
124
-
125
- // Multiple-precision squaring, HAC Algorithm 14.16
126
-
127
- function bsqr(x)
128
- {
129
- var t = x.length;
130
- var n = 2*t;
131
- var r = zeros(n);
132
- var c = 0;
133
- var i, j;
134
-
135
- for(i = 0; i < t; i++)
136
- {
137
- c = ip(r,2*i,x[i],x[i],0);
138
- for(j = i+1; j < t; j++)
139
- {
140
- c = ip(r,i+j,2*x[j],x[i],c);
141
- }
142
- r[i+t] = c;
143
- }
144
-
145
- return zclip(r);
146
- }
147
-
148
- // Multiple-precision multiplication, HAC Algorithm 14.12
149
-
150
- function bmul(x,y)
151
- {
152
- var n = x.length;
153
- var t = y.length;
154
- var r = zeros(n+t-1);
155
- var c, i, j;
156
-
157
- for(i = 0; i < t; i++)
158
- {
159
- c = 0;
160
- for(j = 0; j < n; j++)
161
- {
162
- c = ip(r,i+j,x[j],y[i],c);
163
- }
164
- r[i+n] = c;
165
- }
166
-
167
- return zclip(r);
168
- }
169
-
170
- function toppart(x,start,len)
171
- {
172
- var n=0;
173
- while(start >= 0 && len-->0) n=n*bx2+x[start--];
174
- return n;
175
- }
176
-
177
- // Multiple-precision division, HAC Algorithm 14.20
178
-
179
- function bdiv(a,b)
180
- {
181
- var n=a.length-1;
182
- var t=b.length-1;
183
- var nmt=n-t;
184
-
185
- // trivial cases; a < b
186
- if(n < t || n==t && (a[n]<b[n] || n>0 && a[n]==b[n] && a[n-1]<b[n-1]))
187
- {
188
- this.q=[0]; this.mod=a;
189
- return this;
190
- }
191
-
192
- // trivial cases; q < 4
193
- if(n==t && toppart(a,t,2)/toppart(b,t,2) <4)
194
- {
195
- var x=a.concat();
196
- var qq=0;
197
- var xx;
198
- for(;;)
199
- {
200
- xx=bsub(x,b);
201
- if(xx.length==0) break;
202
- x=xx; qq++;
203
- }
204
- this.q=[qq]; this.mod=x;
205
- return this;
206
- }
207
-
208
- // normalize
209
- var shift2=Math.floor(Math.log(b[t])/log2)+1;
210
- var shift=bs-shift2;
211
-
212
- var x=a.concat();
213
- var y=b.concat();
214
-
215
- if(shift)
216
- {
217
- for(i=t; i>0; i--) y[i]=((y[i]<<shift) & bm) | (y[i-1] >> shift2);
218
- y[0]=(y[0]<<shift) & bm;
219
- if(x[n] & ((bm <<shift2) & bm))
220
- {
221
- x[++n]=0; nmt++;
222
- }
223
- for(i=n; i>0; i--) x[i]=((x[i]<<shift) & bm) | (x[i-1] >> shift2);
224
- x[0]=(x[0]<<shift) & bm;
225
- }
226
-
227
- var i, j, x2;
228
- var q=zeros(nmt+1);
229
- var y2=zeros(nmt).concat(y);
230
- for(;;)
231
- {
232
- x2=bsub(x,y2);
233
- if(x2.length==0) break;
234
- q[nmt]++;
235
- x=x2;
236
- }
237
-
238
- var yt=y[t], top=toppart(y,t,2)
239
- for(i=n; i>t; i--)
240
- {
241
- var m=i-t-1;
242
- if(i >= x.length) q[m]=1;
243
- else if(x[i] == yt) q[m]=bm;
244
- else q[m]=Math.floor(toppart(x,i,2)/yt);
245
-
246
- var topx=toppart(x,i,3);
247
- while(q[m] * top > topx) q[m]--;
248
-
249
- //x-=q[m]*y*b^m
250
- y2=y2.slice(1);
251
- x2=bsub(x,bmul([q[m]],y2));
252
- if(x2.length==0)
253
- {
254
- q[m]--;
255
- x2=bsub(x,bmul([q[m]],y2));
256
- }
257
- x=x2;
258
- }
259
- // de-normalize
260
- if(shift)
261
- {
262
- for(i=0; i<x.length-1; i++) x[i]=(x[i]>>shift) | ((x[i+1] << shift2) & bm);
263
- x[x.length-1]>>=shift;
264
- }
265
-
266
- this.q = zclip(q);
267
- this.mod = zclip(x);
268
- return this;
269
- }
270
-
271
- function simplemod(i,m) // returns the mod where m < 2^bd
272
- {
273
- var c=0, v;
274
- for(var n=i.length-1; n>=0; n--)
275
- {
276
- v=i[n];
277
- c=((v >> bd) + (c<<bd)) % m;
278
- c=((v & bdm) + (c<<bd)) % m;
279
- }
280
- return c;
281
- }
282
-
283
- function bmod(p,m)
284
- {
285
- if(m.length==1)
286
- {
287
- if(p.length==1) return [p[0] % m[0]];
288
- if(m[0] < bdm) return [simplemod(p,m[0])];
289
- }
290
-
291
- var r=bdiv(p,m);
292
- return r.mod;
293
- }
294
-
295
- // Barrett's modular reduction, HAC Algorithm 14.42
296
-
297
- function bmod2(x,m,mu)
298
- {
299
- var xl=x.length - (m.length << 1);
300
- if(xl > 0) return bmod2(x.slice(0,xl).concat(bmod2(x.slice(xl),m,mu)),m,mu);
301
-
302
- var ml1=m.length+1, ml2=m.length-1,rr;
303
- //var q1=x.slice(ml2)
304
- //var q2=bmul(q1,mu)
305
- var q3=bmul(x.slice(ml2),mu).slice(ml1);
306
- var r1=x.slice(0,ml1);
307
- var r2=bmul(q3,m).slice(0,ml1);
308
- var r=bsub(r1,r2);
309
-
310
- if(r.length==0)
311
- {
312
- r1[ml1]=1;
313
- r=bsub(r1,r2);
314
- }
315
- for(var n=0;;n++)
316
- {
317
- rr=bsub(r,m);
318
- if(rr.length==0) break;
319
- r=rr;
320
- if(n>=3) return bmod2(r,m,mu);
321
- }
322
- return r;
323
- }
324
-
325
- // Modular exponentiation, HAC Algorithm 14.79
326
-
327
- function bexpmod(g,e,m)
328
- {
329
- var a = g.concat();
330
- var l = e.length-1;
331
- var n = nbits(e[l])-2;
332
-
333
- for(; l >= 0; l--)
334
- {
335
- for(; n >= 0; n-=1)
336
- {
337
- a=bmod(bsqr(a),m);
338
- if(e[l] & (1<<n)) a=bmod(bmul(a,g),m);
339
- }
340
- n = bs-1;
341
- }
342
- return a;
343
- }
344
-
345
- // Modular exponentiation using Barrett reduction
346
-
347
- function bmodexp(g,e,m)
348
- {
349
- var a=g.concat();
350
- var l=e.length-1;
351
- var n=m.length*2;
352
- var mu=zeros(n+1);
353
- mu[n]=1;
354
- mu=bdiv(mu,m).q;
355
-
356
- n = nbits(e[l])-2;
357
-
358
- for(; l >= 0; l--)
359
- {
360
- for(; n >= 0; n-=1)
361
- {
362
- a=bmod2(bsqr(a),m, mu);
363
- if(e[l] & (1<<n)) a=bmod2(bmul(a,g),m, mu);
364
- }
365
- n = bs-1;
366
- }
367
- return a;
368
- }
369
-
370
- // -----------------------------------------------------
371
- // Compute s**e mod m for RSA public key operation
372
-
373
- function RSAencrypt(s, e, m) { return bexpmod(s,e,m); }
374
-
375
- // Compute m**d mod p*q for RSA private key operations.
376
-
377
- function RSAdecrypt(m, d, p, q, u)
378
- {
379
- var xp = bmodexp(bmod(m,p), bmod(d,bsub(p,[1])), p);
380
- var xq = bmodexp(bmod(m,q), bmod(d,bsub(q,[1])), q);
381
-
382
- var t=bsub(xq,xp);
383
- if(t.length==0)
384
- {
385
- t=bsub(xp,xq);
386
- t=bmod(bmul(t, u), q);
387
- t=bsub(q,t);
388
- }
389
- else
390
- {
391
- t=bmod(bmul(t, u), q);
392
- }
393
- return badd(bmul(t,p), xp);
394
- }
395
-
396
- // -----------------------------------------------------------------
397
- // conversion functions: num array <-> multi precision integer (mpi)
398
- // mpi: 2 octets with length in bits + octets in big endian order
399
-
400
- function mpi2b(s)
401
- {
402
- var bn=1, r=[0], rn=0, sb=256;
403
- var c, sn=s.length;
404
- if(sn < 2) return 0;
405
-
406
- var len=(sn-2)*8;
407
- var bits=s.charCodeAt(0)*256+s.charCodeAt(1);
408
- if(bits > len || bits < len-8) return 0;
409
-
410
- for(var n=0; n<len; n++)
411
- {
412
- if((sb<<=1) > 255)
413
- {
414
- sb=1; c=s.charCodeAt(--sn);
415
- }
416
- if(bn > bm)
417
- {
418
- bn=1;
419
- r[++rn]=0;
420
- }
421
- if(c & sb) r[rn]|=bn;
422
- bn<<=1;
423
- }
424
- return r;
425
- }
426
-
427
- function b2mpi(b)
428
- {
429
- var bn=1, bc=0, r=[0], rb=1, rn=0;
430
- var bits=b.length*bs;
431
- var n, rr='';
432
-
433
- for(n=0; n<bits; n++)
434
- {
435
- if(b[bc] & bn) r[rn]|=rb;
436
- if((rb<<=1) > 255)
437
- {
438
- rb=1; r[++rn]=0;
439
- }
440
- if((bn<<=1) > bm)
441
- {
442
- bn=1; bc++;
443
- }
444
- }
445
-
446
- while(rn && r[rn]==0) rn--;
447
-
448
- bn=256;
449
- for(bits=8; bits>0; bits--) if(r[rn] & (bn>>=1)) break;
450
- bits+=rn*8;
451
-
452
- rr+=String.fromCharCode(bits/256)+String.fromCharCode(bits%256);
453
- if(bits) for(n=rn; n>=0; n--) rr+=String.fromCharCode(r[n]);
454
- return rr;
455
- }