C++ СИСТЕМА ОБНОВЛЕНИЯ ПРИЛОЖЕНИЙ 2.0

 

СЕРВЕРНАЯ ЧАСТЬ

Здесь, в новой версии, добавлен функционал чтения файла "~/madConfig.cfg", куда можно добавлять имена обновляемых программ и из актуальные индексы. Это позволяет обойтись без перекомпиляции сервиса при обновлении списка.  Помимо всего прочего, здесь на всякий случай реализован механизм одновременной обработки нескольких входящих подключений.

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fstream>
#include <map>
 
// Функция для создания сокета
int SocketCreate() {
    return socket(AF_INET, SOCK_STREAM, 0);
}
 
// Функция для связывания сокета
int BindCreatedSocket(int socket_desc) {
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY; // Слушать на всех интерфейсах
    server.sin_port = htons(8888);
 
    return bind(socket_desc, (struct sockaddr *)&server, sizeof(server));
}
 
// Функция для получения версии программы из конфигурационного файла
std::string getVersion(const std::string &programName) {
    std::ifstream configFile("~/madConfig.cfg");
    std::string line;
    std::map<std::string, std::string> versions;
 
    // Чтение конфигурационного файла
    while (std::getline(configFile, line)) {
        size_t pos = line.find(" ");
        if (pos != std::string::npos) {
            std::string name = line.substr(0, pos);
            std::string version = line.substr(pos + 1);
            versions[name] = version;
        }
    }
 
    if (versions.find(programName) != versions.end()) {
        return versions[programName];
    }
    return "unknown";
}
 
// Функция для обработки клиента
void *handleClient(void *socket_desc) {
    int sock = *(int *)socket_desc;
    char client_message[200] = {0};
    char message[100] = {0};
 
    // Получение сообщения от клиента
    if (recv(sock, client_message, sizeof(client_message), 0) < 0) {
        perror("Receive failed");
        close(sock);
        return NULL;
    }
 
    printf("Client message: %s\n", client_message);
 
    // Получение версии программы
    std::string version = getVersion(client_message);
 
    if (version != "unknown") {
        strcpy(message, version.c_str());
        printf("Sending version %s to client: %s\n", message, client_message);
    } else {
        strcpy(message, "Program not recognized!");
        printf("Sending unrecognized message to client: %s\n", client_message);
    }
 
    // Отправка версии клиенту
    if (send(sock, message, strlen(message), 0) < 0) {
        perror("Send failed");
        close(sock);
        return NULL;
    }
 
    // Вывод информации о версии
    if (version != "unknown") {
        printf("Current version for %s is %s\n", client_message, message);
    }
 
    // Закрытие сокета клиента
    close(sock);
    printf("Connection closed for client: %s\n", client_message);
    return NULL;
}
 
int main(int argc, char *argv[]) {
    int socket_desc, sock, clientLen;
    struct sockaddr_in client;
 
    // Создание сокета
    socket_desc = SocketCreate();
    if (socket_desc == -1) {
        perror("Could not create socket");
        return 1;
    }
    printf("Socket created\n");
 
    // Привязка сокета
    if (BindCreatedSocket(socket_desc) < 0) {
        perror("Bind failed");
        close(socket_desc);
        return 1;
    }
    printf("Bind done\n");
 
    // Прослушивание входящих соединений
    if (listen(socket_desc, 3) < 0) {
        perror("Listen failed");
        close(socket_desc);
        return 1;
    }
    printf("Listening for incoming connections...\n");
 
    // Принятие входящих соединений
    while (1) {
        clientLen = sizeof(client);
 
        // Принятие соединения от клиента
        sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&clientLen);
        if (sock < 0) {
            perror("Accept failed");
            continue; // Пропускаем итерацию в случае ошибки
        }
        printf("Connection accepted from IP: %s, Port: %d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
 
        // Создание потока для обработки клиента
        pthread_t clientThread;
        if (pthread_create(&clientThread, NULL, handleClient, (void *)&sock) < 0) {
            perror("Could not create thread");
            close(sock);
            continue; // Пропускаем итерацию в случае ошибки
        }
 
        // Отсоединяем поток, чтобы не дожидаться его завершения
        pthread_detach(clientThread);
    }
 
    // Закрытие сокета перед завершением (не достигнет в текущем состоянии)
    close(socket_desc);
    return 0;
}
 

У меня когда-то была версия этого приложения, которая еще умела общаться с кейлоггером, но я что-то подумал и решил что лучше сделать две отдельные проги на для таких сулчаев. Тем более, что там с кейлоггером вообще пока неясно как лучше сделать. По-хорошему, там надо основательно продумать все вопросы безопасности, чтобы полностью исключить вероятность перехвата данных бабуинами с вирешарком.