1

I am sending messages from my windows application to remote syslog server (rsyslog). I can see that message is being sent successfully but I can see this error in syslog server: rsyslogd: unexpected GnuTLS error -54 in nsd_gtls.c:551: Error in the pull function. [v8.24.0-52.el7_8.2 try http://www.rsyslog.com/e/2078 Following is the code I am using:

additional info: I also tried sneding logs from one rsyslog client to another rsyslog server using these steps and it works perfectly fine without any error: https://www.thegeekdiary.com/how-to-configure-rsyslog-server-to-accept-logs-via-ssl-tls/ I am getting pull request error only when I am trying with this code. I am new to openSSL, is there anything I am missing in this code. can someone please help?

```
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Wspiapi.h>  // This is for pre XP machines to work with new APIs. See MSDN

#include "openssl/sha.h"
#include "openssl/rsa.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/x509v3.h"
#include "openssl/rand.h"
#include "openssl/crypto.h"
#include <errno.h>
#include <iostream>

#include <thread>
using namespace std;
#include <string>

SSL_CTX *InitSSL_CTX(void)   
{

  const SSL_METHOD *method = TLSv1_2_method(); // Create new client-method instance 
  SSL_CTX *ctx = SSL_CTX_new(method);
  // Trusted root CA certificate bundle
  int iRetVal = SSL_CTX_load_verify_locations(ctx, "ca.pem", NULL);
  if (iRetVal != ERR_LIB_NONE)
  {
    cout<<"Failed to load trusted CA certificates bundle";
    exit(EXIT_FAILURE);
  }

  if (ctx == nullptr)
  {
     ERR_print_errors_fp(stderr);
     exit(EXIT_FAILURE);
  }
   return ctx;
}


int OpenConnection(const char *hostname, const char *port)
{
    SOCKET ConnectSocket;
    struct addrinfo *result, *ptr, hints;
    int iResult;
    char portStr[1024];


   /*
    Initialize Winsock.
    WSAStartup allows to specify what version of WinSock you want to use.
    It sets up all the "behind the scenes stuff" that any process needs to use sockets.
    winSockDLL is loaded into the process and it sets up many internal structures.
    Each process must call WSAStartup to initialize the structures within its own memory space       and WSACleanup to tear them down again when it is finished using sockets.
   */
   WSADATA wsaData;
   iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
   if (iResult != 0) {
       cout << "WSAStartup failed with error: " << iResult << endl;
       return 1;
    }


ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

// Resolve the server address and port
iResult = getaddrinfo(hostname, port, &hints, &result);
if (iResult != 0)
{
    cout << "getaddrinfo failed with error: " << iResult;
    WSACleanup();
    return 1;
}

// Attempt to connect to an address
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
    ptr->ai_protocol);
    if (ConnectSocket == INVALID_SOCKET)
    {
        cout << "socket failed with error: " << WSAGetLastError();
        break;
    }

    // Connect to server.
    iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
        cout << "connect failed" << endl;
        continue;
    }
    break;
}

freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
    cout << "Unable to connect to server!" << endl;
    WSACleanup();
    return 1;
}
return ConnectSocket;
}

 int main()
 {
      SSL_CTX *ctx = InitSSL_CTX();
      SSL *ssl = SSL_new(ctx);
      if (ssl == nullptr)
      {
        cout << "SSL_new() failed\n";
        exit(EXIT_FAILURE);
       }

    //Host is hardcoded to localhost for testing purposes
    const int sfd = OpenConnection("172.16.74.4", "6514");
    SSL_set_fd(ssl, sfd);

    const int status = SSL_connect(ssl);
    if (status != 1)
    {
       SSL_get_error(ssl, status);
       ERR_print_errors_fp(stderr); //High probability this doesn't do anything
       cout << "SSL_connect failed with SSL_get_error code :" << status << endl;
       exit(EXIT_FAILURE);
    }

    cout << "Connected with %s encryption\n" << SSL_get_cipher(ssl) << endl;
    DisplayCerts(ssl);

     SSL_write(ssl, "hello", strlen("hello"));
     SSL_write(ssl, "hello1", strlen("hello1"));
     SSL_write(ssl, "hello2", strlen("hello2"));

     SSL_free(ssl);

     SSL_CTX_free(ctx);

     return 0;
  }


``` 
aromahola
  • 190
  • 1
  • 12
  • Your program does not follow the syslog over TCP protocol, so what did you expect? – Botje Nov 16 '20 at 12:17
  • It is following TLS over TCP but I guess I am doing something wrong as I am getting error on the syslog server side "rsyslogd: unexpected GnuTLS error -54 in nsd_gtls.c:551: Error in the pull function. [v8.24.0-52.el7_8.2 try http://www.rsyslog.com/e/2078" – aromahola Nov 16 '20 at 17:57
  • @Botje actually I would be grateful if this error gets resolved or if I get to know whether I am doing something wrong in my code – aromahola Nov 16 '20 at 17:58
  • Start by testing this against `openssl s_server` to see if your bytes actually come through. Then, implement the [syslog over TCP protocol](https://tools.ietf.org/html/rfc6587#section-3.4) properly. – Botje Nov 16 '20 at 23:33

0 Answers0