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 +4 -4
- data/README.md +9 -2
- data/Rakefile +1 -0
- data/ext/extconf.rb +8 -1
- data/ext/postfix_status_line_core.c +147 -49
- data/ext/postfix_status_line_core.h +6 -0
- data/lib/postfix_status_line/version.rb +1 -1
- data/lib/postfix_status_line.rb +5 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20862ceb4887cd85c5d41c00280b4614639efd5b
|
4
|
+
data.tar.gz: e66aa89b96e0e716ea03681efd8d2f170652b644
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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" => "
|
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
data/ext/extconf.rb
CHANGED
@@ -1,2 +1,9 @@
|
|
1
1
|
require 'mkmf'
|
2
|
-
|
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
|
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
|
66
|
+
return false;
|
30
67
|
}
|
31
68
|
|
32
69
|
*p2 = split(&buf_ptr, ": ", 2);
|
33
70
|
|
34
71
|
if (*p2 == NULL) {
|
35
|
-
return
|
72
|
+
return false;
|
36
73
|
}
|
37
74
|
|
38
75
|
*p3 = buf_ptr;
|
39
76
|
|
40
|
-
return
|
77
|
+
return true;
|
41
78
|
}
|
42
79
|
|
43
|
-
static
|
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
|
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
|
93
|
+
return false;
|
57
94
|
}
|
58
95
|
|
59
96
|
if (*hostname - str < 1) {
|
60
|
-
return
|
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
|
105
|
+
return true;
|
69
106
|
}
|
70
107
|
|
71
|
-
static
|
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)
|
75
|
-
return
|
111
|
+
if (!split3(buf, &p1, &p2, &p3)) {
|
112
|
+
return false;
|
76
113
|
}
|
77
114
|
|
78
|
-
if (split_p1(p1, tm, hostname, process)
|
79
|
-
return
|
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
|
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
|
-
|
117
|
-
|
171
|
+
rb_hash_aset(hash, rb_str_new2("domain"), rb_str_new2(domain));
|
172
|
+
}
|
118
173
|
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
-
|
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
|
-
|
155
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
240
|
+
if (mask) {
|
241
|
+
mask_email(value);
|
242
|
+
}
|
162
243
|
|
163
|
-
|
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,
|
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
|
-
|
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 =
|
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)
|
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,
|
337
|
+
rb_define_module_function(rb_mPostfixStatusLineCore, "parse", rb_postfix_status_line_parse, 4);
|
240
338
|
}
|
data/lib/postfix_status_line.rb
CHANGED
@@ -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,
|
6
|
-
|
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.
|
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-
|
11
|
+
date: 2015-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|