Browse Source

added sources

tags/v1.0.0
Robin Thoni 7 years ago
parent
commit
05422b1cac

+ 12
- 0
CMakeLists.txt View File

@@ -0,0 +1,12 @@
1
+cmake_minimum_required(VERSION 2.8)
2
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules/")
3
+set(PROJECT_NAME milter-sasl)
4
+set(LIBS -lmilter -ljsoncpp -lcrypto)
5
+project(${PROJECT_NAME})
6
+find_package(GTest)
7
+find_package(OpenSSL REQUIRED)
8
+add_subdirectory(src)
9
+if (GTEST_FOUND)
10
+    enable_testing()
11
+    add_subdirectory(tests)
12
+endif (GTEST_FOUND)

+ 46
- 0
CMakeModules/FindJsonCpp.cmake View File

@@ -0,0 +1,46 @@
1
+# -*- cmake -*-
2
+# - Find JSONCpp
3
+# Find the JSONCpp includes and library
4
+# This module defines
5
+#  JSONCPP_INCLUDE_DIRS, where to find json.h, etc.
6
+#  JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
7
+#  JSONCPP_FOUND, If false, do not try to use jsoncpp.
8
+#  also defined, but not for general use are
9
+#  JSONCPP_LIBRARIES, where to find the jsoncpp library.
10
+
11
+FIND_PATH(JSONCPP_INCLUDE_DIRS json/json.h
12
+        /usr/include
13
+        /usr/local/include
14
+        ${CMAKE_SOURCE_DIR}/win32-deps/include
15
+        PATH_SUFFIXES jsoncpp/json jsoncpp
16
+        )
17
+
18
+
19
+FIND_LIBRARY(JSONCPP_LIBRARIES NAMES jsoncpp HINTS /usr/lib /usr/local/lib 	${CMAKE_SOURCE_DIR}/win32-deps/lib)
20
+
21
+IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
22
+    SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES})
23
+    SET(JSONCPP_FOUND "YES")
24
+ELSE (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
25
+    SET(JSONCPP_FOUND "NO")
26
+ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
27
+
28
+
29
+IF (JSONCPP_FOUND)
30
+    IF (NOT JSONCPP_FIND_QUIETLY)
31
+        MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
32
+    ENDIF (NOT JSONCPP_FIND_QUIETLY)
33
+ELSE (JSONCPP_FOUND)
34
+    IF (JSONCPP_FIND_REQUIRED)
35
+        MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}")
36
+    ENDIF (JSONCPP_FIND_REQUIRED)
37
+ENDIF (JSONCPP_FOUND)
38
+
39
+# Deprecated declarations.
40
+SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS} )
41
+GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH)
42
+
43
+MARK_AS_ADVANCED(
44
+        JSONCPP_LIBRARIES
45
+        JSONCPP_INCLUDE_DIRS
46
+)

+ 8
- 0
README.md View File

@@ -0,0 +1,8 @@
1
+CMake C++ starter kit
2
+=====================
3
+Here is a starter kit for C++ using CMake build system. The aim is to be used with CLion. It include a test project with GTest and a cmake module to find JsonCpp library.
4
+
5
+Usage
6
+-----
7
+
8
+Just clone and open the directory with CLion, it will generate a target to build the exe and the tests (if GTest is found).

+ 3
- 0
milter-sasl.json View File

@@ -0,0 +1,3 @@
1
+{
2
+  "key": "insert your AES key here"
3
+}

+ 116
- 0
src/Business/CryptoBusiness.cpp View File

@@ -0,0 +1,116 @@
1
+//
2
+// Created by robin on 2/26/17.
3
+//
4
+
5
+#include <openssl/aes.h>
6
+#include <cstring>
7
+#include "CryptoBusiness.h"
8
+
9
+std::string CryptoBusiness::_hex = "0123456789ABCDEF";
10
+
11
+CryptoBusiness::CryptoBusiness()
12
+{
13
+
14
+}
15
+
16
+std::string CryptoBusiness::getKey() const
17
+{
18
+    return _key;
19
+}
20
+
21
+void CryptoBusiness::setKey(std::string key)
22
+{
23
+    _key = key;
24
+}
25
+
26
+std::string CryptoBusiness::encrypt16(std::string data)
27
+{
28
+    unsigned char enc_out[16 * sizeof(char)];
29
+    AES_KEY enc_key;
30
+    AES_set_encrypt_key((const unsigned char*)_key.c_str(), 128, &enc_key);
31
+    AES_encrypt((const unsigned char*)data.c_str(), enc_out, &enc_key);
32
+    return std::string((char*)enc_out, 16 * sizeof(char));
33
+}
34
+
35
+std::string CryptoBusiness::encrypt(std::string data)
36
+{
37
+    std::string out;
38
+    if (data.length() % 16 != 0)
39
+    {
40
+        data += std::string(16 - data.length() % 16, 0);
41
+    }
42
+    for (size_t i = 0; i < data.length(); i += 16)
43
+    {
44
+        out += encrypt16(data.substr(i, i + 16));
45
+    }
46
+    return out;
47
+}
48
+
49
+std::string CryptoBusiness::decrypt16(std::string data)
50
+{
51
+    unsigned char dec_out[16 * sizeof(char)];
52
+    memset(dec_out, 0, 16);
53
+    AES_KEY dec_key;
54
+    AES_set_decrypt_key((const unsigned char*)_key.c_str(), 128, &dec_key);
55
+    AES_decrypt((const unsigned char*)data.c_str(), dec_out, &dec_key);
56
+    int s = 16;
57
+    for(int i = 15; i >= 0 && dec_out[i] == 0; --i)
58
+        --s;
59
+    return std::string((char*)dec_out, s);
60
+}
61
+
62
+std::string CryptoBusiness::decrypt(std::string data)
63
+{
64
+    std::string out;
65
+    for (size_t i = 0; i < data.length(); i += 16)
66
+    {
67
+        out += decrypt16(data.substr(i, i + 16));
68
+    }
69
+    return out;
70
+}
71
+
72
+std::string CryptoBusiness::toHex(std::string data)
73
+{
74
+    size_t len = data.length();
75
+
76
+    std::string output;
77
+    output.reserve(2 * len);
78
+    for (size_t i = 0; i < len; ++i)
79
+    {
80
+        const unsigned char c = data[i];
81
+        output.push_back(_hex[c >> 4]);
82
+        output.push_back(_hex[c & 15]);
83
+    }
84
+    return output;
85
+}
86
+
87
+std::string CryptoBusiness::fromHex(std::string data)
88
+{
89
+    size_t len = data.length();
90
+
91
+    std::string output;
92
+    output.reserve(len / 2);
93
+    for (size_t i = 0; i < len; i += 2)
94
+    {
95
+        char a = data[i];
96
+        const char* p = std::lower_bound(_hex.c_str(), _hex.c_str() + 16, a);
97
+
98
+        char b = data[i + 1];
99
+        const char* q = std::lower_bound(_hex.c_str(), _hex.c_str() + 16, b);
100
+
101
+        output.push_back(((p - _hex.c_str()) << 4) | (q - _hex.c_str()));
102
+    }
103
+    return output;
104
+}
105
+
106
+std::string CryptoBusiness::encryptToHex(std::string data)
107
+{
108
+    auto encrypted = encrypt(data);
109
+    return toHex(encrypted);
110
+}
111
+
112
+std::string CryptoBusiness::decryptFromHex(std::string data)
113
+{
114
+    auto d = fromHex(data);
115
+    return decrypt(d);
116
+}

+ 43
- 0
src/Business/CryptoBusiness.h View File

@@ -0,0 +1,43 @@
1
+//
2
+// Created by robin on 2/26/17.
3
+//
4
+
5
+#ifndef MILTER_SASL_CRYPTOBUSINESS_H
6
+#define MILTER_SASL_CRYPTOBUSINESS_H
7
+
8
+#include <string>
9
+
10
+class CryptoBusiness
11
+{
12
+public:
13
+    CryptoBusiness();
14
+
15
+    std::string getKey() const;
16
+
17
+    void setKey(std::string key);
18
+
19
+    std::string encryptToHex(std::string data);
20
+
21
+    std::string encrypt(std::string data);
22
+
23
+    std::string decryptFromHex(std::string data);
24
+
25
+    std::string decrypt(std::string data);
26
+
27
+    std::string toHex(std::string data);
28
+
29
+    std::string fromHex(std::string data);
30
+
31
+protected:
32
+    std::string encrypt16(std::string data);
33
+
34
+    std::string decrypt16(std::string data);
35
+
36
+private:
37
+    std::string _key;
38
+
39
+    static std::string _hex;
40
+};
41
+
42
+
43
+#endif //MILTER_SASL_CRYPTOBUSINESS_H

+ 15
- 0
src/CMakeLists.txt View File

@@ -0,0 +1,15 @@
1
+include_directories(.)
2
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
3
+set(SOURCE_FILES
4
+  main.cpp
5
+  Interface/MainClass.cpp
6
+  Interface/MainClass.h
7
+  Interface/CommandLineParser.cpp
8
+  Interface/CommandLineParser.h
9
+  DBO/CommandLineOption.cpp
10
+  DBO/CommandLineOption.h
11
+        Business/CryptoBusiness.cpp
12
+  Business/CryptoBusiness.h)
13
+
14
+add_executable(${PROJECT_NAME} ${SOURCE_FILES})
15
+target_link_libraries(${PROJECT_NAME} ${LIBS})

+ 98
- 0
src/DBO/CommandLineOption.cpp View File

@@ -0,0 +1,98 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include "CommandLineOption.h"
6
+
7
+CommandLineOption::CommandLineOption(const std::string &longName, char shortName, const std::string &description,
8
+                                     const std::string &valueName, const std::string &defaultValue)
9
+    : _longName(longName)
10
+    , _shortName(shortName)
11
+    , _description(description)
12
+    , _valueName(valueName)
13
+    , _defaultValue(defaultValue)
14
+    , _isSet(false)
15
+{
16
+}
17
+
18
+const std::string &CommandLineOption::getLongName() const
19
+{
20
+    return _longName;
21
+}
22
+
23
+void CommandLineOption::setLongName(const std::string &longName)
24
+{
25
+    _longName = longName;
26
+}
27
+
28
+char CommandLineOption::getShortName() const
29
+{
30
+    return _shortName;
31
+}
32
+
33
+void CommandLineOption::setShortName(char shortName)
34
+{
35
+    _shortName = shortName;
36
+}
37
+
38
+const std::string &CommandLineOption::getDescription() const
39
+{
40
+    return _description;
41
+}
42
+
43
+void CommandLineOption::setDescription(const std::string &description)
44
+{
45
+    _description = description;
46
+}
47
+
48
+const std::string &CommandLineOption::getValueName() const
49
+{
50
+    return _valueName;
51
+}
52
+
53
+void CommandLineOption::setValueName(const std::string &valueName)
54
+{
55
+    _valueName = valueName;
56
+}
57
+
58
+const std::string &CommandLineOption::getDefaultValue() const
59
+{
60
+    return _defaultValue;
61
+}
62
+
63
+void CommandLineOption::setDefaultValue(const std::string &defaultValue)
64
+{
65
+    _defaultValue = defaultValue;
66
+}
67
+
68
+const std::vector<std::string> &CommandLineOption::getValues() const
69
+{
70
+    return _values;
71
+}
72
+
73
+void CommandLineOption::addValue(const std::string &value)
74
+{
75
+    _values.push_back(value);
76
+}
77
+
78
+bool CommandLineOption::isSet() const
79
+{
80
+    return _isSet;
81
+}
82
+
83
+void CommandLineOption::setIsSet(bool isSet)
84
+{
85
+    _isSet = isSet;
86
+}
87
+
88
+bool CommandLineOption::hasValue() const
89
+{
90
+    return !_valueName.empty();
91
+}
92
+
93
+const std::string &CommandLineOption::getValue() const
94
+{
95
+    if (_values.empty())
96
+        return _defaultValue;
97
+    return _values[_values.size() - 1];
98
+}

+ 66
- 0
src/DBO/CommandLineOption.h View File

@@ -0,0 +1,66 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEOPTION_H
6
+#define PDNS_SLAVE_COMMANDLINEOPTION_H
7
+
8
+# include <string>
9
+# include <vector>
10
+
11
+class CommandLineOption
12
+{
13
+public:
14
+    CommandLineOption(const std::string& longName, char shortName, const std::string& description,
15
+                      const std::string& valueName = "", const std::string& defaultValue = "");
16
+
17
+    const std::string &getLongName() const;
18
+
19
+    void setLongName(const std::string &longName);
20
+
21
+    char getShortName() const;
22
+
23
+    void setShortName(char shortName);
24
+
25
+    const std::string &getDescription() const;
26
+
27
+    void setDescription(const std::string &description);
28
+
29
+    const std::string &getValueName() const;
30
+
31
+    void setValueName(const std::string &valueName);
32
+
33
+    const std::string &getDefaultValue() const;
34
+
35
+    void setDefaultValue(const std::string &defaultValue);
36
+
37
+    const std::vector<std::string> &getValues() const;
38
+
39
+    const std::string &getValue() const;
40
+
41
+    void addValue(const std::string &value);
42
+
43
+    bool isSet() const;
44
+
45
+    void setIsSet(bool isSet);
46
+
47
+    bool hasValue() const;
48
+
49
+private:
50
+    std::string _longName;
51
+
52
+    char _shortName;
53
+
54
+    std::string _description;
55
+
56
+    std::string _valueName;
57
+
58
+    std::string _defaultValue;
59
+
60
+    std::vector<std::string> _values;
61
+
62
+    bool _isSet;
63
+};
64
+
65
+
66
+#endif //PDNS_SLAVE_COMMANDLINEOPTION_H

+ 0
- 0
src/DataAccess/.gitkeep View File


+ 79
- 0
src/Interface/CommandLineParser.cpp View File

@@ -0,0 +1,79 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <getopt.h>
6
+#include <iostream>
7
+#include "CommandLineParser.h"
8
+
9
+CommandLineParser::CommandLineParser(int argc, char **argv)
10
+    : _argc(argc)
11
+    , _argv(argv)
12
+{
13
+}
14
+
15
+bool CommandLineParser::parse()
16
+{
17
+    std::string shortOpts;
18
+    option opts[_options.size() + 1];
19
+    for (unsigned i = 0; i < _options.size(); ++i)
20
+    {
21
+        auto opt = _options[i];
22
+        shortOpts += opt->getShortName();
23
+        if (opt->hasValue())
24
+            shortOpts += ":";
25
+        opts[i].name = opt->getLongName().c_str();
26
+        opts[i].has_arg = opt->hasValue();
27
+        opts[i].flag = 0;
28
+        opts[i].val = opt->getShortName();
29
+    }
30
+    opts[_options.size()] = {0, 0, 0, 0};
31
+    int option;
32
+    extern int optind;
33
+    extern char* optarg;
34
+    bool valid = true;
35
+    while ((option = getopt_long(_argc, _argv, shortOpts.c_str(), opts, 0)) != -1)
36
+    {
37
+        bool optValid = false;
38
+        for (unsigned i = 0; i < _options.size(); ++i)
39
+        {
40
+            auto opt = _options[i];
41
+            if (opt->getShortName() == option)
42
+            {
43
+                optValid = true;
44
+                opt->setIsSet(true);
45
+                if (opt->hasValue())
46
+                    opt->addValue(optarg);
47
+            }
48
+        }
49
+        if (!optValid)
50
+            valid = false;
51
+    }
52
+    return optind == _argc && valid;
53
+}
54
+
55
+void CommandLineParser::addOption(CommandLineOption* opt)
56
+{
57
+    _options.push_back(opt);
58
+}
59
+
60
+int CommandLineParser::showHelp(int status, bool stdErr)
61
+{
62
+    auto& out = stdErr ? std::cerr : std::cout;
63
+    out << "Options:" << std::endl;
64
+    for (auto opt : _options)
65
+    {
66
+        out << "  -" << opt->getShortName() << ", --" << opt->getLongName();
67
+        if (opt->hasValue())
68
+        {
69
+            out << " <" << opt->getValueName();
70
+            if (opt->getDefaultValue().length())
71
+            {
72
+                out << "=" << opt->getDefaultValue();
73
+            }
74
+            out << ">";
75
+        }
76
+        out << " " << opt->getDescription() << std::endl;
77
+    }
78
+    return status;
79
+}

+ 30
- 0
src/Interface/CommandLineParser.h View File

@@ -0,0 +1,30 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_COMMANDLINEPARSER_H
6
+#define PDNS_SLAVE_COMMANDLINEPARSER_H
7
+
8
+# include "DBO/CommandLineOption.h"
9
+
10
+class CommandLineParser
11
+{
12
+public:
13
+    CommandLineParser(int argc, char** argv);
14
+
15
+    bool parse();
16
+
17
+    int showHelp(int status = 0, bool stdErr = true);
18
+
19
+    void addOption(CommandLineOption* opt);
20
+
21
+private:
22
+    int _argc;
23
+
24
+    char** _argv;
25
+
26
+    std::vector<CommandLineOption*> _options;
27
+};
28
+
29
+
30
+#endif //PDNS_SLAVE_COMMANDLINEPARSER_H

+ 186
- 0
src/Interface/MainClass.cpp View File

@@ -0,0 +1,186 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#include <iostream>
6
+#include <fstream>
7
+#include <sysexits.h>
8
+#include <jsoncpp/json/json.h>
9
+#include <cstring>
10
+#include "CommandLineParser.h"
11
+#include "MainClass.h"
12
+
13
+MainClass* MainClass::_instance = nullptr;
14
+
15
+MainClass *MainClass::getInstance()
16
+{
17
+    return _instance;
18
+}
19
+
20
+sfsistat mlfi_header(SMFICTX *ctx)
21
+{
22
+    return MainClass::getInstance()->mlfiHeader(ctx);
23
+}
24
+
25
+MainClass::MainClass(int argc, char *argv[])
26
+    : _argc(argc)
27
+    , _argv(argv)
28
+{
29
+    _instance = this;
30
+    _cryptoBusiness = std::make_shared<CryptoBusiness>();
31
+}
32
+
33
+MainClass::~MainClass()
34
+{
35
+}
36
+
37
+int MainClass::main()
38
+{
39
+    CommandLineParser commandLineParser(_argc, _argv);
40
+    CommandLineOption configOption("config", 'c', "Use FILE as configuration file.", "FILE", "/etc/milter-sasl/milter-sasl.json");
41
+    commandLineParser.addOption(&configOption);
42
+    CommandLineOption decryptOption("decrypt", 'd', "Decrypt DATA and exit. Can be specified multiple times. Use - to read from stdin.", "DATA");
43
+    commandLineParser.addOption(&decryptOption);
44
+    CommandLineOption socketOption("milter", 'm', "Launch milter and specify the socket to listen on (eg: inet:4242@localhost).", "SOCKET");
45
+    commandLineParser.addOption(&socketOption);
46
+    CommandLineOption helpOption("help", 'h', "Show this help.");
47
+    commandLineParser.addOption(&helpOption);
48
+
49
+    if (!commandLineParser.parse())
50
+    {
51
+        return commandLineParser.showHelp(EX_USAGE, true);
52
+    }
53
+
54
+    if (helpOption.isSet())
55
+    {
56
+        return commandLineParser.showHelp(0, false);
57
+    }
58
+
59
+    auto configFile = configOption.getValue();
60
+    auto configResult = loadConfig(configFile);
61
+    if (configResult != 0)
62
+    {
63
+        std::cerr << "Failed to read configuration file: " << strerror(configResult) << std::endl;
64
+        return EX_NOINPUT;
65
+    }
66
+    else if (socketOption.isSet())
67
+    {
68
+        return launchMilter(socketOption.getValue());
69
+    }
70
+    else if (decryptOption.isSet())
71
+    {
72
+        return launchDecrypt(decryptOption.getValues());
73
+    }
74
+
75
+    return commandLineParser.showHelp(EX_USAGE, true);
76
+}
77
+
78
+sfsistat MainClass::mlfiHeader(SMFICTX *ctx)
79
+{
80
+    Json::Value root;
81
+    auto auth_authen = smfi_getsymval(ctx, (char*)"{auth_authen}");
82
+    if (auth_authen)
83
+    {
84
+        root["auth_authen"] = randomizeString(auth_authen);
85
+    }
86
+    auto auth_author = smfi_getsymval(ctx, (char*)"{auth_author}");
87
+    if (auth_author)
88
+    {
89
+        root["auth_author"] = randomizeString(auth_author);
90
+    }
91
+    auto auth_type = smfi_getsymval(ctx, (char*)"{auth_type}");
92
+    if (auth_type)
93
+    {
94
+        root["auth_type"] = randomizeString(auth_type);
95
+    }
96
+
97
+    Json::StyledWriter w;
98
+    auto json = w.write(root);
99
+    auto encrypted = _cryptoBusiness->encryptToHex(json);
100
+
101
+    smfi_addheader(ctx, (char*)"X-Sasl-User", (char*)encrypted.c_str());
102
+
103
+    return SMFIS_CONTINUE;
104
+}
105
+
106
+int MainClass::loadConfig(const std::string& filePath)
107
+{
108
+    std::ifstream stream(filePath, std::ifstream::in);
109
+    if (stream)
110
+    {
111
+        Json::Reader reader;
112
+        Json::Value root;
113
+        reader.parse(stream, root);
114
+        _cryptoBusiness->setKey(root["key"].asString());
115
+    }
116
+    return errno;
117
+}
118
+
119
+int MainClass::launchMilter(const std::string &socket)
120
+{
121
+    srand(time(nullptr));
122
+    struct smfiDesc smfilter =
123
+            {
124
+                    (char*)"milter-sasl",	/* filter name */
125
+                    SMFI_VERSION,	/* version code -- do not change */
126
+                    SMFIF_ADDHDRS,	/* flags */
127
+                    NULL,		/* connection info filter */
128
+                    NULL,		/* SMTP HELO command filter */
129
+                    NULL,	/* envelope sender filter */
130
+                    NULL,		/* envelope recipient filter */
131
+                    NULL,	/* header filter */
132
+                    NULL,	/* end of header */
133
+                    NULL,	/* body block filter */
134
+                    mlfi_header,	/* end of message */
135
+                    NULL,	/* message aborted */
136
+                    NULL,	/* connection cleanup */
137
+                    NULL,	/* unknown/unimplemented SMTP commands */
138
+                    NULL,	/* DATA command filter */
139
+                    NULL	/* option negotiation at connection startup */
140
+            };
141
+
142
+    if (smfi_setconn((char*)socket.c_str()) == MI_FAILURE)
143
+    {
144
+        std::cerr << "smfi_setconn failed" << std::endl;
145
+        return EX_UNAVAILABLE;
146
+    }
147
+
148
+    if (smfi_register(smfilter) == MI_FAILURE)
149
+    {
150
+        std::cerr << "smfi_register failed" << std::endl;
151
+        return EX_UNAVAILABLE;
152
+    }
153
+
154
+    return smfi_main();
155
+}
156
+
157
+int MainClass::launchDecrypt(const std::vector<std::string> values)
158
+{
159
+    for (auto value : values)
160
+    {
161
+        if (value == "-")
162
+        {
163
+            std::cin >> value;
164
+        }
165
+        std::cout << _cryptoBusiness->decryptFromHex(value) << std::endl;
166
+    }
167
+    return 0;
168
+}
169
+
170
+std::string MainClass::randomizeString(const std::string &str)
171
+{
172
+    int cc = 2;
173
+    std::string out;
174
+    for (int i = 0; i < cc; ++i)
175
+    {
176
+        auto c = 'a' + (rand() % 26);
177
+        out.push_back((char)c);
178
+    }
179
+    out += "|" + str + "|";
180
+    for (int i = 0; i < cc; ++i)
181
+    {
182
+        auto c = 'a' + (rand() % 26);
183
+        out.push_back((char)c);
184
+    }
185
+    return out;
186
+}

+ 45
- 0
src/Interface/MainClass.h View File

@@ -0,0 +1,45 @@
1
+//
2
+// Created by robin on 8/8/15.
3
+//
4
+
5
+#ifndef PDNS_SLAVE_MAINCLASS_H
6
+#define PDNS_SLAVE_MAINCLASS_H
7
+
8
+#include <Business/CryptoBusiness.h>
9
+#include <boost/shared_ptr.hpp>
10
+#include "libmilter/mfapi.h"
11
+#include "libmilter/mfdef.h"
12
+
13
+class MainClass {
14
+public:
15
+    static MainClass* getInstance();
16
+
17
+    MainClass(int argc, char* argv[]);
18
+    virtual ~MainClass();
19
+
20
+    int main();
21
+
22
+    sfsistat mlfiHeader(SMFICTX *ctx);
23
+
24
+    std::string randomizeString(const std::string& str);
25
+
26
+protected:
27
+    int loadConfig(const std::string& filePath);
28
+
29
+    int launchMilter(const std::string& socket);
30
+
31
+    int launchDecrypt(const std::vector<std::string> values);
32
+
33
+private:
34
+    int _argc;
35
+
36
+    char** _argv;
37
+
38
+    std::shared_ptr<CryptoBusiness> _cryptoBusiness;
39
+
40
+    static MainClass* _instance;
41
+
42
+};
43
+
44
+
45
+#endif //PDNS_SLAVE_MAINCLASS_H

+ 7
- 0
src/main.cpp View File

@@ -0,0 +1,7 @@
1
+#include "Interface/MainClass.h"
2
+
3
+int main(int argc, char* argv[])
4
+{
5
+    MainClass m(argc, argv);
6
+    return m.main();
7
+}

+ 12
- 0
tests/CMakeLists.txt View File

@@ -0,0 +1,12 @@
1
+enable_testing()
2
+include_directories(${CHECK_INCLUDE_DIRS})
3
+include_directories(. ../src)
4
+find_package (Threads)
5
+set(LIBS ${LIBS} gtest pthread)
6
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
7
+add_executable(test-${PROJECT_NAME}
8
+        test-main.cpp
9
+        ../src/Business/CryptoBusiness.cpp
10
+  )
11
+target_link_libraries(test-${PROJECT_NAME} ${LIBS})
12
+add_test(test-${PROJECT_NAME} ${CMAKE_CURRENT_BINARY_DIR}/test-${PROJECT_NAME})

+ 3
- 0
tests/milter-sasl.json View File

@@ -0,0 +1,3 @@
1
+{
2
+  "key": "x%p~;mZ(A4FG]CDj"
3
+}

+ 58
- 0
tests/test-main.cpp View File

@@ -0,0 +1,58 @@
1
+#include <iostream>
2
+#include <string.h>
3
+#include <gtest/gtest.h>
4
+#include <Business/CryptoBusiness.h>
5
+
6
+TEST(Crypto, Basic)
7
+{
8
+  std::string key = "m{L%H$HgY##LJ&6Fs";
9
+  CryptoBusiness cryptoBusiness;
10
+  cryptoBusiness.setKey(key);
11
+  std::string data = "some data";
12
+  std::string encrypted = cryptoBusiness.encrypt(data);
13
+  std::string decrypted = cryptoBusiness.decrypt(encrypted);
14
+  ASSERT_NE(encrypted, decrypted);
15
+  ASSERT_EQ(data, decrypted);
16
+}
17
+
18
+TEST(Crypto, Hex1)
19
+{
20
+  CryptoBusiness cryptoBusiness;
21
+  std::string data = "some data";
22
+  std::string toHex = cryptoBusiness.toHex(data);
23
+  std::string fromHex = cryptoBusiness.fromHex(toHex);
24
+  ASSERT_NE(toHex, fromHex);
25
+  ASSERT_EQ(data, fromHex);
26
+}
27
+
28
+TEST(Crypto, Hex2)
29
+{
30
+  CryptoBusiness cryptoBusiness;
31
+  std::string data;
32
+  for (int i = 0; i <= 255; ++i)
33
+  {
34
+    data += (char)i;
35
+  }
36
+  std::string toHex = cryptoBusiness.toHex(data);
37
+  std::string fromHex = cryptoBusiness.fromHex(toHex);
38
+  ASSERT_NE(toHex, fromHex);
39
+  ASSERT_EQ(data, fromHex);
40
+}
41
+
42
+TEST(Crypto, EncryptHex)
43
+{
44
+  std::string key = "m{L%H$HgY##LJ&6Fs";
45
+  CryptoBusiness cryptoBusiness;
46
+  cryptoBusiness.setKey(key);
47
+  std::string data = "some data";
48
+  std::string encrypted = cryptoBusiness.encryptToHex(data);
49
+  std::string decrypted = cryptoBusiness.decryptFromHex(encrypted);
50
+  ASSERT_NE(encrypted, decrypted);
51
+  ASSERT_EQ(data, decrypted);
52
+}
53
+
54
+int main(int argc, char* argv[])
55
+{
56
+  ::testing::InitGoogleTest(&argc, argv);
57
+  return RUN_ALL_TESTS();
58
+}

Loading…
Cancel
Save