postfix_status_line 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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