zipruby 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of zipruby might be problematic. Click here for more details.

data/README.txt CHANGED
@@ -21,7 +21,7 @@ gem install zipruby
21
21
  https://rubyforge.org/frs/?group_id=6124
22
22
 
23
23
  == Example
24
- === reading zip archives
24
+ === reading zip archive
25
25
 
26
26
  require 'zipruby'
27
27
 
@@ -64,7 +64,7 @@ https://rubyforge.org/frs/?group_id=6124
64
64
  end
65
65
  end
66
66
 
67
- === creating zip archives
67
+ === creating zip archive
68
68
 
69
69
  require 'zipruby'
70
70
 
@@ -94,7 +94,7 @@ https://rubyforge.org/frs/?group_id=6124
94
94
  # args: <entry name>, <source>
95
95
  end
96
96
 
97
- === modifying zip archives
97
+ === modifying zip archive
98
98
 
99
99
  require 'zipruby'
100
100
 
@@ -130,10 +130,14 @@ https://rubyforge.org/frs/?group_id=6124
130
130
  end
131
131
  end
132
132
 
133
- === decrypt zip archives
133
+ === encrypt/decrypt zip archive
134
134
 
135
135
  require 'zipruby'
136
136
 
137
+ # encrypt
138
+ Zip::Archive.encrypt('filename.zip', 'password')
139
+
140
+ # decrypt
137
141
  Zip::Archive.decrypt('filename.zip', 'password')
138
142
 
139
143
  == License
data/ext/zip.h CHANGED
@@ -206,6 +206,7 @@ int zip_unchange_archive(struct zip *);
206
206
 
207
207
  // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
208
208
  int zip_decrypt(const char *path, const char *pwd, int pwdlen, int *errorp, int *wrongpwd);
209
+ int zip_encrypt(const char *path, const char *pwd, int pwdlen, int *errorp);
209
210
 
210
211
  #ifdef __cplusplus
211
212
  }
data/ext/zip_crypt.c CHANGED
@@ -56,7 +56,6 @@ static void init_keys(uLong *keys, const char *password, size_t len) {
56
56
  static int decrypt_header(unsigned long *keys, char *buffer, struct zip_dirent *de) {
57
57
  int i;
58
58
  char c;
59
- unsigned short dostime, dosdate;
60
59
 
61
60
  for (i = 0; i < ZIPENC_HEAD_LEN; i++) {
62
61
  c = buffer[i] ^ decrypt_byte(keys);
@@ -64,11 +63,11 @@ static int decrypt_header(unsigned long *keys, char *buffer, struct zip_dirent *
64
63
  buffer[i] = c;
65
64
  }
66
65
 
67
- _zip_u2d_time(de->last_mod, &dostime, &dosdate);
68
-
69
66
  if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
70
67
  return ((c & 0xff) == (de->crc >> 24)) ? 0 : -1;
71
68
  } else {
69
+ unsigned short dostime, dosdate;
70
+ _zip_u2d_time(de->last_mod, &dostime, &dosdate);
72
71
  return ((c & 0xff) == (dostime >> 8)) ? 0 : -1;
73
72
  }
74
73
  }
@@ -128,6 +127,97 @@ static int copy_decrypt(FILE *src, off_t len, const char *pwd, int pwdlen, struc
128
127
  return 0;
129
128
  }
130
129
 
130
+ static void generate_random_header(unsigned long *keys, char *buffer) {
131
+ static int initialized = 0;
132
+ int i;
133
+
134
+ if (!initialized) {
135
+ srand((unsigned) time(NULL));
136
+ initialized = 1;
137
+ }
138
+
139
+ for (i = 0; i < ZIPENC_HEAD_LEN - 2; i++) {
140
+ char temp = decrypt_byte(keys);
141
+ char c = rand() % 0xff;
142
+ update_keys(keys, c);
143
+ buffer[i] = temp ^ c;
144
+ }
145
+ }
146
+
147
+ static void encrypt_header(unsigned long *keys, char *buffer, struct zip_dirent *de) {
148
+ int i;
149
+ char c, temp;
150
+
151
+ for (i = 0; i < ZIPENC_HEAD_LEN - 2; i++) {
152
+ temp = decrypt_byte(keys);
153
+ c = buffer[i];
154
+ update_keys(keys, c);
155
+ buffer[i] = temp ^ c;
156
+ }
157
+
158
+ temp = decrypt_byte(keys);
159
+ c = (de->crc >> 16) & 0xff;
160
+ update_keys(keys, c);
161
+ buffer[ZIPENC_HEAD_LEN - 2] = temp ^ c;
162
+
163
+ temp = decrypt_byte(keys);
164
+ c = (de->crc >> 24) & 0xff;
165
+ update_keys(keys, c);
166
+ buffer[ZIPENC_HEAD_LEN - 1] = temp ^ c;
167
+ }
168
+
169
+ static void encrypt_data(uLong *keys, char *buffer, size_t n) {
170
+ int i;
171
+
172
+ for (i = 0; i < n; i++) {
173
+ char temp = decrypt_byte(keys);
174
+ char c = buffer[i];
175
+ update_keys(keys, c);
176
+ buffer[i] = temp ^ c;
177
+ }
178
+ }
179
+
180
+ static int copy_encrypt(FILE *src, off_t len, const char *pwd, int pwdlen, struct zip_dirent *de, FILE *dest, struct zip_error *error) {
181
+ char header[ZIPENC_HEAD_LEN];
182
+ char buf[BUFSIZE];
183
+ uLong keys[3];
184
+ int n;
185
+
186
+ if (len == 0) {
187
+ return 0;
188
+ }
189
+
190
+ init_keys(keys, pwd, pwdlen);
191
+ generate_random_header(keys, header);
192
+ init_keys(keys, pwd, pwdlen);
193
+ encrypt_header(keys, header, de);
194
+
195
+ if (fwrite(header, 1, ZIPENC_HEAD_LEN, dest) != ((size_t) ZIPENC_HEAD_LEN)) {
196
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
197
+ }
198
+
199
+ while (len > 0) {
200
+ if ((n = fread(buf, 1, MIN(len, sizeof(buf)), src)) < 0) {
201
+ _zip_error_set(error, ZIP_ER_READ, errno);
202
+ return -1;
203
+ } else if (n == 0) {
204
+ _zip_error_set(error, ZIP_ER_EOF, 0);
205
+ return -1;
206
+ }
207
+
208
+ encrypt_data(keys, buf, n);
209
+
210
+ if (fwrite(buf, 1, n, dest) != ((size_t) n)) {
211
+ _zip_error_set(error, ZIP_ER_WRITE, errno);
212
+ return -1;
213
+ }
214
+
215
+ len -= n;
216
+ }
217
+
218
+ return 0;
219
+ }
220
+
131
221
  static int _zip_crypt(struct zip *za, const char *pwd, int pwdlen, int decrypt, int *wrongpwd) {
132
222
  int i, error = 0;
133
223
  char *temp;
@@ -202,7 +292,10 @@ static int _zip_crypt(struct zip *za, const char *pwd, int pwdlen, int decrypt,
202
292
  cd->entry[i].comp_size -= ZIPENC_HEAD_LEN;
203
293
  cd->entry[i].bitflags &= ~ZIP_GPBF_ENCRYPTED;
204
294
  } else if (!decrypt && !encrypted) {
205
- // XXX
295
+ de.comp_size += ZIPENC_HEAD_LEN;
296
+ de.bitflags |= ZIP_GPBF_ENCRYPTED;
297
+ cd->entry[i].comp_size += ZIPENC_HEAD_LEN;
298
+ cd->entry[i].bitflags |= ZIP_GPBF_ENCRYPTED;
206
299
  }
207
300
 
208
301
  if (_zip_dirent_write(&de, out, 1, &za->error) < 0) {
@@ -213,8 +306,7 @@ static int _zip_crypt(struct zip *za, const char *pwd, int pwdlen, int decrypt,
213
306
  if (decrypt && encrypted) {
214
307
  error = (copy_decrypt(za->zp, cd->entry[i].comp_size, pwd, pwdlen, &de, out, &za->error, wrongpwd) < 0);
215
308
  } else if (!decrypt && !encrypted) {
216
- // XXX
217
- error = (copy_data(za->zp, cd->entry[i].comp_size, out, &za->error) < 0);
309
+ error = (copy_encrypt(za->zp, (cd->entry[i].comp_size - ZIPENC_HEAD_LEN), pwd, pwdlen, &de, out, &za->error) < 0);
218
310
  } else {
219
311
  error = (copy_data(za->zp, cd->entry[i].comp_size, out, &za->error) < 0);
220
312
  }
@@ -293,3 +385,21 @@ int zip_decrypt(const char *path, const char *pwd, int pwdlen, int *errorp, int
293
385
 
294
386
  return res;
295
387
  }
388
+
389
+ int zip_encrypt(const char *path, const char *pwd, int pwdlen, int *errorp) {
390
+ struct zip *za;
391
+ int res;
392
+
393
+ if (pwd == NULL || pwdlen < 1) {
394
+ return -1;
395
+ }
396
+
397
+ if ((za = zip_open(path, 0, errorp)) == NULL) {
398
+ return -1;
399
+ }
400
+
401
+ res = _zip_crypt(za, pwd, pwdlen, 0, NULL);
402
+ _zip_free(za);
403
+
404
+ return res;
405
+ }
data/ext/zipruby.h CHANGED
@@ -1,7 +1,7 @@
1
1
  #ifndef __ZIPRUBY_H__
2
2
  #define __ZIPRUBY_H__
3
3
 
4
- #define VERSION "0.2.1"
4
+ #define VERSION "0.2.2"
5
5
  #define ERRSTR_BUFSIZE 256
6
6
  #define DATA_BUFSIZE 8192
7
7
 
@@ -10,6 +10,7 @@ static VALUE zipruby_archive_alloc(VALUE klass);
10
10
  static void zipruby_archive_free(struct zipruby_archive *p);
11
11
  static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
12
12
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
13
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
13
14
  static VALUE zipruby_archive_close(VALUE self);
14
15
  static VALUE zipruby_archive_num_files(VALUE self);
15
16
  static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
@@ -50,6 +51,7 @@ void Init_zipruby_archive() {
50
51
  rb_include_module(Archive, rb_mEnumerable);
51
52
  rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
52
53
  rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
54
+ rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
53
55
  rb_define_method(Archive, "close", zipruby_archive_close, 0);
54
56
  rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
55
57
  rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
@@ -138,11 +140,19 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
138
140
  /* */
139
141
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
140
142
  int errorp, wrongpwd;
143
+ long pwdlen;
141
144
 
142
145
  Check_Type(path, T_STRING);
143
146
  Check_Type(password, T_STRING);
147
+ pwdlen = RSTRING(password)->len;
144
148
 
145
- if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), RSTRING(password)->len, &errorp, &wrongpwd) == -1) {
149
+ if (pwdlen < 1) {
150
+ rb_raise(Error, "Decrypt archive failed - %s: Password is empty", StringValuePtr(path));
151
+ } else if (pwdlen > 0xff) {
152
+ rb_raise(Error, "Decrypt archive failed - %s: Password is too long", StringValuePtr(path));
153
+ }
154
+
155
+ if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), pwdlen, &errorp, &wrongpwd) == -1) {
146
156
  if (wrongpwd) {
147
157
  rb_raise(Error, "Decrypt archive failed - %s: Wrong password", StringValuePtr(path));
148
158
  } else {
@@ -155,6 +165,30 @@ static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
155
165
  return Qnil;
156
166
  }
157
167
 
168
+ /* */
169
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
170
+ int errorp;
171
+ long pwdlen;
172
+
173
+ Check_Type(path, T_STRING);
174
+ Check_Type(password, T_STRING);
175
+ pwdlen = RSTRING(password)->len;
176
+
177
+ if (pwdlen < 1) {
178
+ rb_raise(Error, "Encrypt archive failed - %s: Password is empty", StringValuePtr(path));
179
+ } else if (pwdlen > 0xff) {
180
+ rb_raise(Error, "Encrypt archive failed - %s: Password is too long", StringValuePtr(path));
181
+ }
182
+
183
+ if (zip_encrypt(StringValuePtr(path), StringValuePtr(password), pwdlen, &errorp) == -1) {
184
+ char errstr[ERRSTR_BUFSIZE];
185
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
186
+ rb_raise(Error, "Encrypt archive failed - %s: %s", StringValuePtr(path), errstr);
187
+ }
188
+
189
+ return Qnil;
190
+ }
191
+
158
192
  /* */
159
193
  static VALUE zipruby_archive_close(VALUE self) {
160
194
  struct zipruby_archive *p_archive;
data/ext/zipruby_file.c CHANGED
@@ -7,6 +7,7 @@
7
7
  #endif
8
8
 
9
9
  #include "zip.h"
10
+ #include "zipint.h"
10
11
  #include "zipruby.h"
11
12
  #include "zipruby_archive.h"
12
13
  #include "zipruby_file.h"
@@ -178,6 +179,10 @@ static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
178
179
  Check_File(p_file);
179
180
  zip_stat_init(&sb);
180
181
 
182
+ if (p_file->archive->cdir->entry[0].bitflags & ZIP_GPBF_ENCRYPTED) {
183
+ rb_raise(Error, "Read file failed: File encrypted");
184
+ }
185
+
181
186
  if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
182
187
  rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
183
188
  }
data/zipruby.c CHANGED
@@ -29,6 +29,7 @@ static VALUE zipruby_archive_alloc(VALUE klass);
29
29
  static void zipruby_archive_free(struct zipruby_archive *p);
30
30
  static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
31
31
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
32
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
32
33
  static VALUE zipruby_archive_close(VALUE self);
33
34
  static VALUE zipruby_archive_num_files(VALUE self);
34
35
  static VALUE zipruby_archive_get_name(int argc, VALUE *argv, VALUE self);
@@ -69,6 +70,7 @@ void Init_zipruby_archive() {
69
70
  rb_include_module(Archive, rb_mEnumerable);
70
71
  rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
71
72
  rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
73
+ rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
72
74
  rb_define_method(Archive, "close", zipruby_archive_close, 0);
73
75
  rb_define_method(Archive, "num_files", zipruby_archive_num_files, 0);
74
76
  rb_define_method(Archive, "get_name", zipruby_archive_get_name, -1);
@@ -157,11 +159,19 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
157
159
  /* */
158
160
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
159
161
  int errorp, wrongpwd;
162
+ long pwdlen;
160
163
 
161
164
  Check_Type(path, T_STRING);
162
165
  Check_Type(password, T_STRING);
166
+ pwdlen = RSTRING(password)->len;
163
167
 
164
- if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), RSTRING(password)->len, &errorp, &wrongpwd) == -1) {
168
+ if (pwdlen < 1) {
169
+ rb_raise(Error, "Decrypt archive failed - %s: Password is empty", StringValuePtr(path));
170
+ } else if (pwdlen > 0xff) {
171
+ rb_raise(Error, "Decrypt archive failed - %s: Password is too long", StringValuePtr(path));
172
+ }
173
+
174
+ if (zip_decrypt(StringValuePtr(path), StringValuePtr(password), pwdlen, &errorp, &wrongpwd) == -1) {
165
175
  if (wrongpwd) {
166
176
  rb_raise(Error, "Decrypt archive failed - %s: Wrong password", StringValuePtr(path));
167
177
  } else {
@@ -174,6 +184,30 @@ static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
174
184
  return Qnil;
175
185
  }
176
186
 
187
+ /* */
188
+ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
189
+ int errorp;
190
+ long pwdlen;
191
+
192
+ Check_Type(path, T_STRING);
193
+ Check_Type(password, T_STRING);
194
+ pwdlen = RSTRING(password)->len;
195
+
196
+ if (pwdlen < 1) {
197
+ rb_raise(Error, "Encrypt archive failed - %s: Password is empty", StringValuePtr(path));
198
+ } else if (pwdlen > 0xff) {
199
+ rb_raise(Error, "Encrypt archive failed - %s: Password is too long", StringValuePtr(path));
200
+ }
201
+
202
+ if (zip_encrypt(StringValuePtr(path), StringValuePtr(password), pwdlen, &errorp) == -1) {
203
+ char errstr[ERRSTR_BUFSIZE];
204
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
205
+ rb_raise(Error, "Encrypt archive failed - %s: %s", StringValuePtr(path), errstr);
206
+ }
207
+
208
+ return Qnil;
209
+ }
210
+
177
211
  /* */
178
212
  static VALUE zipruby_archive_close(VALUE self) {
179
213
  struct zipruby_archive *p_archive;
@@ -845,6 +879,7 @@ void Init_zipruby_error() {
845
879
  #endif
846
880
 
847
881
  #include "zip.h"
882
+ #include "zipint.h"
848
883
  #include "zipruby.h"
849
884
  #include "zipruby_archive.h"
850
885
  #include "zipruby_file.h"
@@ -1016,6 +1051,10 @@ static VALUE zipruby_file_read(int argc, VALUE *argv, VALUE self) {
1016
1051
  Check_File(p_file);
1017
1052
  zip_stat_init(&sb);
1018
1053
 
1054
+ if (p_file->archive->cdir->entry[0].bitflags & ZIP_GPBF_ENCRYPTED) {
1055
+ rb_raise(Error, "Read file failed: File encrypted");
1056
+ }
1057
+
1019
1058
  if (zip_stat_index(p_file->archive, p_file->sb->index, 0, &sb)) {
1020
1059
  rb_raise(Error, "Read file failed: %s", zip_strerror(p_file->archive));
1021
1060
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zipruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - winebarrel