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 +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
|