Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

решения / server_ssl

.cpp
Скачиваний:
4
Добавлен:
18.02.2023
Размер:
8.13 Кб
Скачать
// server_ssl.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
// Обеспечить замену символов из имен файлов в нескольких каталогах. Клиент посылает серверу искомые символы и 
// символы для замены. Сервер после завершения операции возвращает результат клиенту в виде имен файлов, где 
// было удалено заданное слово. Протокол взаимодействия UDP.

#include <iostream>
#include <sstream>
#include <string.h>
#include <winsock2.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

using namespace std;

// link with ws2_32.lib
#pragma comment(lib, "ws2_32.lib")

SOCKET create_socket(int port)
{
    WORD wVersionRequested = MAKEWORD(2, 2);
    WSADATA wsa;
    SOCKET s;
    struct sockaddr_in addr;

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (WSAStartup(wVersionRequested, &wsa) != 0)
    {
        std::cout << "Unable to startup. Error Code: " << WSAGetLastError() << std::endl;
        system("pause");
        exit(EXIT_FAILURE);
    }
    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0)
    {
        std::cout << "Unable to create socket" << std::endl;
        WSACleanup();
        system("pause");
        exit(EXIT_FAILURE);
    }
    if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        std::cout << "Unable to bind" << std::endl;
        WSACleanup();
        system("pause");
        exit(EXIT_FAILURE);
    }
    if (listen(s, 1) < 0)
    {
        std::cout << "Unable to listen" << std::endl;
        WSACleanup();
        system("pause");
        exit(EXIT_FAILURE);
    }
    return s;
}

void init_openssl()
{
    // registers the error strings for all libcrypto functions and also registers the libssl error strings.
    SSL_load_error_strings();

    // registers the available SSL/TLS ciphers and digests.
    SSL_library_init(); // заменено на равнозначное с OpenSSL_add_ssl_algorithms 
}

SSL_CTX* create_context()
{
    const SSL_METHOD* method;
    SSL_CTX* ctx;

    // These are the general - purpose version - flexible SSL / TLS methods.
    method = TLS_server_method(); // заменены с SSLv23_server_method на рекомендуемые 
    if (!method)
    {
        std::cout << "Unable to collect SSL method" << std::endl;
        system("pause");
        exit(EXIT_FAILURE);
    }

    // creates a new SSL_CTX object as framework to establish TLS / SSL enabled connections.
    ctx = SSL_CTX_new(method);
    if (!ctx)
    {
        std::cout << "Unable to create SSL context" << std::endl;
        system("pause");
        exit(EXIT_FAILURE);
    }

    return ctx;
}

void configure_context(SSL_CTX* ctx)
{
    SSL_CTX_set_ecdh_auto(ctx, 1);
    /* Set the key and cert */
    if (SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM) != 1)
    {
        std::cout << "cert.pem" << std::endl;
        system("pause");
        exit(EXIT_FAILURE);
    }
    if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) != 1)
    {
        std::cout << "key.pem" << std::endl;
        system("pause");
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char** argv)
{
    setlocale(LC_ALL, "Russian");
    SOCKET sock;
    SSL_CTX* ctx;

    init_openssl();
    ctx = create_context();
    configure_context(ctx);
    sock = create_socket(4433);

    /* Handle connections */
    while (1)
    {
        struct sockaddr_in addr;
        int len = sizeof(addr);
        SSL* ssl;
        SOCKET client = accept(sock, (struct sockaddr*)&addr, &len);
        if (client < 0)
        {
            std::cout << "Unable to accept" << std::endl;
            continue;
        }
        ssl = SSL_new(ctx); // create a new SSL structure for a connection
        SSL_set_fd(ssl, (int)client); // connect the SSL object with a file descriptor
        if (SSL_accept(ssl) <= 0) // wait for a TLS/SSL client to initiate a TLS/SSL handshake
        {
            char* err = new char[1024];
            ERR_error_string_n(ERR_get_error(), err, 1024);
            std::cout << err << std::endl;
            delete[] err;
        }
        else // The TLS/SSL handshake was successfully completed
        {
            char* input = new char[256];
            string path, search, replace;
            SSL_read(ssl, input, 256); // получаем папку для поиска
            path = string(input);
            SSL_read(ssl, input, 256); // получаем искомое значение
            search = string(input);
            SSL_read(ssl, input, 256); // получаем значение для замены
            replace = string(input);
            cout << path << endl << search << endl << replace << endl;
            delete[] input;

            if (path.back() != '\\') path += '\\'; // добавляем в путь обратный слеш если его нет

            int count = 0;
            stringstream found;
            WIN32_FIND_DATA FindFileData;
            string exp = path + "*" + string(search) + "*";
            wstring exp_tmp = wstring(exp.begin(), exp.end());
            LPCWSTR exp_final = exp_tmp.c_str(); // преобразуем кодировку
            //HANDLE hFind = FindFirstFile((LPCWSTR)((path + "*" + string(search) + "*").c_str()), &FindFileData);
            HANDLE hFind = FindFirstFile(exp_final, &FindFileData);
            while (hFind != INVALID_HANDLE_VALUE)
            {
                wstring file_tmp = wstring(FindFileData.cFileName);
                string file = string(file_tmp.begin(), file_tmp.end()); // преобразуем кодировку обратно
                found << file << endl;
                count++;
                if (!FindNextFile(hFind, &FindFileData)) break;
            }
            FindClose(hFind);

            wstring w_path = wstring(path.begin(), path.end());
            for (int i = 0; i < count; i++)
            {
                string oldfilename, newfilename;
                found >> oldfilename;
                newfilename = oldfilename;

                size_t pos = newfilename.find(search, 0);
                while (pos != string::npos)
                {
                    newfilename.erase(pos, search.length());
                    newfilename.insert(pos, replace);
                    pos += replace.length();
                    pos = newfilename.find(search, pos);
                }
                cout << oldfilename << " -> " << newfilename << endl;
                if (oldfilename == newfilename) continue;
                // преобразуем кодировку
                wstring w_oldfilename = wstring(oldfilename.begin(), oldfilename.end());
                wstring w_newfilename = wstring(newfilename.begin(), newfilename.end());
                w_oldfilename.insert(0, w_path);
                w_newfilename.insert(0, w_path);
                // переименовываем файл
                if (MoveFile(w_oldfilename.c_str(), w_newfilename.c_str()) != 0)
                    SSL_write(ssl, newfilename.c_str(), 256);//(int)newfilename.length()
                else std::cout << "Unable to rename file: " << oldfilename << std::endl;
            }
            SSL_write(ssl, "END", 4);
        }
        SSL_shutdown(ssl); // shut down a TLS/SSL connection
        SSL_free(ssl); // free an allocated SSL structure
        closesocket(client);
    }
    closesocket(sock);
    SSL_CTX_free(ctx); // free an allocated SSL_CTX object
    WSACleanup();
    system("pause");
    return 0;
}
Соседние файлы в папке решения