postfix_status_line 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9520446497f6f210808c56e1a5f861e4b412036d
4
- data.tar.gz: 7ee583ea8a511f2ef8735502e0f452aa39eb4479
3
+ metadata.gz: 20862ceb4887cd85c5d41c00280b4614639efd5b
4
+ data.tar.gz: e66aa89b96e0e716ea03681efd8d2f170652b644
5
5
  SHA512:
6
- metadata.gz: 112285e1abcbac3ee737a3c6ed08056e501b1de248880e8798731319be4b7af0056a62ddf3a7812f10b5878d13a764cc3c3c65a8690e852e941cb351394d7a83
7
- data.tar.gz: af9412d375e7a8a1ea2f15929c0dc4f13acf8ff1f066b2c4afbb886f2db20a0cc1b228c0854e00a684e82ad228a2d0de6b8435e36d70c84d02c93fd38fe74ed5
6
+ metadata.gz: baa5e6493ad10a43a24a3cf657fd80f528bfb0f01ad163780ace3048b813deae7992e7e1cbd7fc15655143189b5b3516fe041d307a989a5ba8a3fab12814ba59
7
+ data.tar.gz: 5ed4a6252af723a09348f8ee7ce892c8a7301d426a9959ff97eea0077bd8002ca86d1cc899b792fd326a9091561732301c6e1ffe2edd355f1016479335001675
data/README.md CHANGED
@@ -25,10 +25,11 @@ Or install it yourself as:
25
25
  ```ruby
26
26
  require "postfix_status_line"
27
27
 
28
- status_line = "Feb 27 09:02:37 MyHOSTNAME postfix/smtp[26490]: D53A72713E5: to=<myemail@bellsouth.net>, relay=gateway-f1.isp.att.net[204.127.217.16]:25, delay=0.57, delays=0.11/0.03/0.23/0.19, dsn=2.0.0, status=sent (250 ok ; id=20120227140036M0700qer4ne)"
28
+ status_line = "Feb 27 09:02:37 MyHOSTNAME postfix/smtp[26490]: D53A72713E5: to=<myemail@bellsouth.net>, relay=gateway-f1.isp.att.net[204.127.217.16]:25, conn_use=2, delay=0.57, delays=0.11/0.03/0.23/0.19, dsn=2.0.0, status=sent (250 ok ; id=20120227140036M0700qer4ne)"
29
29
 
30
30
  PostfixStatusLine.parse(status_line)
31
31
  # => {
32
+ # "conn_use" => 2,
32
33
  # "delay" => 0.57,
33
34
  # "delays" => "0.11/0.03/0.23/0.19",
34
35
  # "dsn" => "2.0.0",
@@ -39,7 +40,13 @@ PostfixStatusLine.parse(status_line)
39
40
  # "status" => "sent",
40
41
  # "status_detail" => "(250 ok ; id=20120227140036M0700qer4ne)",
41
42
  # "time" => "Feb 8 09:02:37",
42
- # "to" => "<*******@bellsouth.net>",
43
+ # "to" => "*******@bellsouth.net",
43
44
  # "domain" => "bellsouth.net"
44
45
  # }
45
46
  ```
47
+
48
+ ### Include "to" mail address SH512 hash
49
+
50
+ ```ruby
51
+ PostfixStatusLine.parse(status_line, hash: true)
52
+ ```
data/Rakefile CHANGED
@@ -10,3 +10,4 @@ end
10
10
 
11
11
  task :default => [:spec]
12
12
  task :spec => [:compile]
13
+ task :compile => [:clean]
data/ext/extconf.rb CHANGED
@@ -1,2 +1,9 @@
1
1
  require 'mkmf'
2
- create_makefile('ext/postfix_status_line_core')
2
+
3
+ if have_header('openssl/sha.h')
4
+ if have_library('ssl') and have_library('crypto')
5
+ create_makefile('ext/postfix_status_line_core')
6
+ end
7
+ else
8
+ create_makefile('ext/postfix_status_line_core')
9
+ end
@@ -1,5 +1,42 @@
1
1
  #include "postfix_status_line_core.h"
2
2
 
3
+ #ifdef HAVE_OPENSSL_SHA_H
4
+ static void sha512_to_str(unsigned char *hash, char buf[]) {
5
+ int i;
6
+
7
+ for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
8
+ snprintf(buf + (i * 2), 3, "%02x", hash[i]);
9
+ }
10
+ }
11
+
12
+ static bool digest_sha512(char *str, char *salt, size_t salt_len, char buf[]) {
13
+ SHA512_CTX ctx;
14
+ unsigned char hash[SHA512_DIGEST_LENGTH];
15
+
16
+ if (SHA512_Init(&ctx) != 1) {
17
+ return false;
18
+ }
19
+
20
+ if (SHA512_Update(&ctx, str, strlen(str)) != 1) {
21
+ return false;
22
+ }
23
+
24
+ if (salt != NULL) {
25
+ if (SHA512_Update(&ctx, salt, salt_len) != 1) {
26
+ return false;
27
+ }
28
+ }
29
+
30
+ if (SHA512_Final(hash, &ctx) != 1) {
31
+ return false;
32
+ }
33
+
34
+ sha512_to_str(hash, buf);
35
+
36
+ return true;
37
+ }
38
+ #endif // HAVE_OPENSSL_SHA_H
39
+
3
40
  static char *split(char **orig_str, const char *delim, size_t delim_len) {
4
41
  char *str = *orig_str;
5
42
  char *ptr = strstr((const char *) str, delim);
@@ -20,31 +57,31 @@ static char *split(char **orig_str, const char *delim, size_t delim_len) {
20
57
  return str;
21
58
  }
22
59
 
23
- static int split3(char buf[], char **p1, char **p2, char **p3) {
60
+ static bool split3(char buf[], char **p1, char **p2, char **p3) {
24
61
  char *buf_ptr = buf;
25
62
 
26
63
  *p1 = split(&buf_ptr, ": ", 2);
27
64
 
28
65
  if (*p1 == NULL) {
29
- return -1;
66
+ return false;
30
67
  }
31
68
 
32
69
  *p2 = split(&buf_ptr, ": ", 2);
33
70
 
34
71
  if (*p2 == NULL) {
35
- return -1;
72
+ return false;
36
73
  }
37
74
 
38
75
  *p3 = buf_ptr;
39
76
 
40
- return 0;
77
+ return true;
41
78
  }
42
79
 
43
- static int split_p1(char *str, char **time, char **hostname, char **process) {
80
+ static bool split_p1(char *str, char **time, char **hostname, char **process) {
44
81
  *process = strrchr(str, ' ');
45
82
 
46
83
  if (*process == NULL) {
47
- return -1;
84
+ return false;
48
85
  }
49
86
 
50
87
  **process = '\0';
@@ -53,11 +90,11 @@ static int split_p1(char *str, char **time, char **hostname, char **process) {
53
90
  *hostname = strrchr(str, ' ');
54
91
 
55
92
  if (*hostname == NULL) {
56
- return -1;
93
+ return false;
57
94
  }
58
95
 
59
96
  if (*hostname - str < 1) {
60
- return -1;
97
+ return false;
61
98
  }
62
99
 
63
100
  **hostname = '\0';
@@ -65,24 +102,24 @@ static int split_p1(char *str, char **time, char **hostname, char **process) {
65
102
 
66
103
  *time = str;
67
104
 
68
- return 0;
105
+ return true;
69
106
  }
70
107
 
71
- static int split_line1(char buf[], char **tm, char **hostname, char **process, char **queue_id, char **attrs) {
108
+ static bool split_line1(char buf[], char **tm, char **hostname, char **process, char **queue_id, char **attrs) {
72
109
  char *p1, *p2, *p3;
73
110
 
74
- if (split3(buf, &p1, &p2, &p3) != 0) {
75
- return -1;
111
+ if (!split3(buf, &p1, &p2, &p3)) {
112
+ return false;
76
113
  }
77
114
 
78
- if (split_p1(p1, tm, hostname, process) != 0) {
79
- return -1;
115
+ if (!split_p1(p1, tm, hostname, process)) {
116
+ return false;
80
117
  }
81
118
 
82
119
  *queue_id = p2;
83
120
  *attrs = p3;
84
121
 
85
- return 0;
122
+ return true;
86
123
  }
87
124
 
88
125
  static void mask_email(char *str) {
@@ -96,7 +133,7 @@ static void mask_email(char *str) {
96
133
  }
97
134
 
98
135
  ptr = NULL;
99
- } else if (*str == '<') {
136
+ } else if (*str == '<' || *str == '(' || *str == ' ' || *str == ',') {
100
137
  ptr = str + 1;
101
138
  }
102
139
 
@@ -104,6 +141,24 @@ static void mask_email(char *str) {
104
141
  }
105
142
  }
106
143
 
144
+ static char *remove_bracket(char *value) {
145
+ char *email = strchr(value, '<');
146
+
147
+ if (email == NULL) {
148
+ return value;
149
+ }
150
+
151
+ email++;
152
+
153
+ char *close_bracket = strchr(email, '>');
154
+
155
+ if (close_bracket != NULL) {
156
+ *close_bracket = '\0';
157
+ }
158
+
159
+ return email;
160
+ }
161
+
107
162
  static void put_domain(char *value, VALUE hash) {
108
163
  char *domain = strchr(value, '@');
109
164
 
@@ -113,20 +168,14 @@ static void put_domain(char *value, VALUE hash) {
113
168
 
114
169
  domain++;
115
170
 
116
- char *bracket = strchr(domain, '>');
117
- VALUE v_value;
171
+ rb_hash_aset(hash, rb_str_new2("domain"), rb_str_new2(domain));
172
+ }
118
173
 
119
- if (bracket == NULL) {
120
- v_value = rb_str_new2(domain);
121
- } else {
122
- size_t len = bracket - domain;
123
- v_value = rb_str_new(domain, len);
174
+ static void put_status(char *value, VALUE hash, bool mask) {
175
+ if (mask) {
176
+ mask_email(value);
124
177
  }
125
178
 
126
- rb_hash_aset(hash, rb_str_new2("domain"), v_value);
127
- }
128
-
129
- static void put_status(char *value, VALUE hash) {
130
179
  char *detail = strchr(value, ' ');
131
180
 
132
181
  if (detail != NULL) {
@@ -138,7 +187,36 @@ static void put_status(char *value, VALUE hash) {
138
187
  rb_hash_aset(hash, rb_str_new2("status"), rb_str_new2(value));
139
188
  }
140
189
 
141
- static void put_attr(char *str, VALUE hash) {
190
+ #ifdef HAVE_OPENSSL_SHA_H
191
+ static void put_hash(char *email, VALUE hash_obj, char *salt, size_t salt_len) {
192
+ char buf[SHA512_DIGEST_LENGTH * 2 + 1];
193
+
194
+ if (!digest_sha512(email, salt, salt_len, buf)) {
195
+ return;
196
+ }
197
+
198
+ rb_hash_aset(hash_obj, rb_str_new2("hash"), rb_str_new2(buf));
199
+ }
200
+ #endif // HAVE_OPENSSL_SHA_H
201
+
202
+ static void put_to(char *value, VALUE hash, bool mask, bool include_hash, char *salt, size_t salt_len) {
203
+ char *email = remove_bracket(value);
204
+
205
+ #ifdef HAVE_OPENSSL_SHA_H
206
+ if (include_hash) {
207
+ put_hash(email, hash, salt, salt_len);
208
+ }
209
+ #endif
210
+
211
+ if (mask) {
212
+ mask_email(value); // not "email"!
213
+ }
214
+
215
+ rb_hash_aset(hash, rb_str_new2("to"), rb_str_new2(email));
216
+ put_domain(value, hash);
217
+ }
218
+
219
+ static void put_attr(char *str, VALUE hash, bool mask, bool include_hash, char *salt, size_t salt_len) {
142
220
  char *value = strchr(str, '=');
143
221
 
144
222
  if (value == NULL) {
@@ -151,25 +229,23 @@ static void put_attr(char *str, VALUE hash) {
151
229
  VALUE v_key = rb_str_new2(str);
152
230
 
153
231
  if (strcmp(str, "delay") == 0) {
154
- VALUE v_value = rb_float_new(atof(value));
155
- rb_hash_aset(hash, v_key, v_value);
232
+ rb_hash_aset(hash, v_key, rb_float_new(atof(value)));
233
+ } else if (strcmp(str, "conn_use") == 0) {
234
+ rb_hash_aset(hash, v_key, INT2NUM(atoi(value)));
235
+ } else if (strcmp(str, "to") == 0) {
236
+ put_to(value, hash, mask, include_hash, salt, salt_len);
156
237
  } else if (strcmp(str, "status") == 0) {
157
- put_status(value, hash);
238
+ put_status(value, hash, mask);
158
239
  } else {
159
- VALUE v_value = rb_str_new2(value);
160
- rb_hash_aset(hash, v_key, v_value);
161
- }
240
+ if (mask) {
241
+ mask_email(value);
242
+ }
162
243
 
163
- if (strcmp(str, "to") == 0) {
164
- put_domain(value, hash);
244
+ rb_hash_aset(hash, v_key, rb_str_new2(value));
165
245
  }
166
246
  }
167
247
 
168
- static void split_line2(char *str, int mask, VALUE hash) {
169
- if (mask) {
170
- mask_email(str);
171
- }
172
-
248
+ static void split_line2(char *str, bool mask, VALUE hash, bool include_hash, char *salt, size_t salt_len) {
173
249
  char *ptr;
174
250
 
175
251
  for (;;) {
@@ -187,25 +263,47 @@ static void split_line2(char *str, int mask, VALUE hash) {
187
263
  break;
188
264
  }
189
265
 
190
- put_attr(ptr, hash);
266
+ put_attr(ptr, hash, mask, include_hash, salt, salt_len);
191
267
  }
192
268
 
193
269
  if (str) {
194
- put_attr(str, hash);
270
+ put_attr(str, hash, mask, include_hash, salt, salt_len);
195
271
  }
196
272
  }
197
273
 
198
- static VALUE rb_postfix_status_line_parse(VALUE self, VALUE v_str, VALUE v_mask) {
274
+ static VALUE rb_postfix_status_line_parse(VALUE self, VALUE v_str, VALUE v_mask, VALUE v_hash, VALUE v_salt) {
199
275
  Check_Type(v_str, T_STRING);
200
276
 
201
277
  char *str = RSTRING_PTR(v_str);
202
278
  size_t len = RSTRING_LEN(v_str);
203
- int mask = 1;
279
+ bool mask = true;
280
+
281
+ bool include_hash = false;
282
+ char *salt = NULL;
283
+ size_t salt_len = -1;
284
+
285
+ switch (TYPE(v_hash)) {
286
+ case T_FALSE:
287
+ case T_NIL:
288
+ break;
289
+ default:
290
+ #ifdef HAVE_OPENSSL_SHA_H
291
+ include_hash = true;
292
+
293
+ if (!NIL_P(v_salt)) {
294
+ Check_Type(v_salt, T_STRING);
295
+ salt = RSTRING_PTR(v_salt);
296
+ salt_len = RSTRING_LEN(v_salt);
297
+ }
298
+ #else
299
+ rb_raise(rb_eArgumentError, "OpenSSL is not linked");
300
+ #endif // HAVE_OPENSSL_SHA_H
301
+ }
204
302
 
205
303
  switch (TYPE(v_mask)) {
206
304
  case T_FALSE:
207
305
  case T_NIL:
208
- mask = 0;
306
+ mask = false;
209
307
  }
210
308
 
211
309
  if (len < 1) {
@@ -218,7 +316,7 @@ static VALUE rb_postfix_status_line_parse(VALUE self, VALUE v_str, VALUE v_mask)
218
316
 
219
317
  char *tm, *hostname, *process, *queue_id, *attrs;
220
318
 
221
- if (split_line1(buf, &tm, &hostname, &process, &queue_id, &attrs) != 0) {
319
+ if (!split_line1(buf, &tm, &hostname, &process, &queue_id, &attrs)) {
222
320
  return Qnil;
223
321
  }
224
322
 
@@ -228,7 +326,7 @@ static VALUE rb_postfix_status_line_parse(VALUE self, VALUE v_str, VALUE v_mask)
228
326
  rb_hash_aset(hash, rb_str_new2("process"), rb_str_new2(process));
229
327
  rb_hash_aset(hash, rb_str_new2("queue_id"), rb_str_new2(queue_id));
230
328
 
231
- split_line2(attrs, mask, hash);
329
+ split_line2(attrs, mask, hash, include_hash, salt, salt_len);
232
330
 
233
331
  return hash;
234
332
  }
@@ -236,5 +334,5 @@ static VALUE rb_postfix_status_line_parse(VALUE self, VALUE v_str, VALUE v_mask)
236
334
  void Init_postfix_status_line_core() {
237
335
  VALUE rb_mPostfixStatusLine = rb_define_module("PostfixStatusLine");
238
336
  VALUE rb_mPostfixStatusLineCore = rb_define_module_under(rb_mPostfixStatusLine, "Core");
239
- rb_define_module_function(rb_mPostfixStatusLineCore, "parse", rb_postfix_status_line_parse, 2);
337
+ rb_define_module_function(rb_mPostfixStatusLineCore, "parse", rb_postfix_status_line_parse, 4);
240
338
  }
@@ -1,6 +1,12 @@
1
1
  #ifndef __POSTFIX_STATUS_LINE_CORE_H__
2
2
  #define __POSTFIX_STATUS_LINE_CORE_H__
3
3
 
4
+ #include <stdbool.h>
5
+
6
+ #ifdef HAVE_OPENSSL_SHA_H
7
+ #include <openssl/sha.h>
8
+ #endif
9
+
4
10
  #include <ruby.h>
5
11
 
6
12
  #endif //__POSTFIX_STATUS_LINE_CORE_H__
@@ -1,3 +1,3 @@
1
1
  module PostfixStatusLine
2
- VERSION = '0.1.7'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -2,8 +2,11 @@ require 'postfix_status_line/version'
2
2
  require 'postfix_status_line_core'
3
3
 
4
4
  module PostfixStatusLine
5
- def parse(str, mask = true)
6
- Core.parse(str, mask)
5
+ def parse(str, options)
6
+ mask = options.has_key?(:mask) ? options[:mask] : true
7
+ hash = options[:hash]
8
+ salt = options[:salt]
9
+ PostfixStatusLine::Core.parse(str, mask, hash, salt)
7
10
  end
8
11
  module_function :parse
9
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: postfix_status_line
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-12-23 00:00:00.000000000 Z
11
+ date: 2015-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler