Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/winpr/libwinpr/utils/wlog/UdpAppender.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * WinPR Logger
4
 *
5
 * Copyright © 2015 Thincast Technologies GmbH
6
 * Copyright © 2015 David FORT <contact@hardening-consulting.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <winpr/config.h>
22
23
#include <winpr/crt.h>
24
#include <winpr/environment.h>
25
#include <winpr/winsock.h>
26
27
#include "wlog.h"
28
29
typedef struct
30
{
31
  WLOG_APPENDER_COMMON();
32
  char* host;
33
  struct sockaddr targetAddr;
34
  int targetAddrLen;
35
  SOCKET sock;
36
} wLogUdpAppender;
37
38
static BOOL WLog_UdpAppender_Open(wLog* log, wLogAppender* appender)
39
0
{
40
0
  wLogUdpAppender* udpAppender = NULL;
41
0
  char addressString[256] = { 0 };
42
0
  struct addrinfo hints = { 0 };
43
0
  struct addrinfo* result = { 0 };
44
0
  int status = 0;
45
0
  size_t addrLen = 0;
46
0
  char* colonPos = NULL;
47
48
0
  if (!appender)
49
0
    return FALSE;
50
51
0
  udpAppender = (wLogUdpAppender*)appender;
52
53
0
  if (udpAppender->targetAddrLen) /* already opened */
54
0
    return TRUE;
55
56
0
  colonPos = strchr(udpAppender->host, ':');
57
58
0
  if (!colonPos)
59
0
    return FALSE;
60
61
0
  addrLen = (colonPos - udpAppender->host);
62
0
  memcpy(addressString, udpAppender->host, addrLen);
63
0
  addressString[addrLen] = '\0';
64
0
  hints.ai_family = AF_INET;
65
0
  hints.ai_socktype = SOCK_DGRAM;
66
0
  status = getaddrinfo(addressString, colonPos + 1, &hints, &result);
67
68
0
  if (status != 0)
69
0
    return FALSE;
70
71
0
  if (result->ai_addrlen > sizeof(udpAppender->targetAddr))
72
0
  {
73
0
    freeaddrinfo(result);
74
0
    return FALSE;
75
0
  }
76
77
0
  memcpy(&udpAppender->targetAddr, result->ai_addr, result->ai_addrlen);
78
0
  udpAppender->targetAddrLen = (int)result->ai_addrlen;
79
0
  freeaddrinfo(result);
80
0
  return TRUE;
81
0
}
82
83
static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
84
0
{
85
0
  if (!log || !appender)
86
0
    return FALSE;
87
88
0
  return TRUE;
89
0
}
90
91
static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
92
0
{
93
0
  char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
94
0
  wLogUdpAppender* udpAppender = NULL;
95
96
0
  if (!log || !appender || !message)
97
0
    return FALSE;
98
99
0
  udpAppender = (wLogUdpAppender*)appender;
100
0
  message->PrefixString = prefix;
101
0
  WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
102
0
  _sendto(udpAppender->sock, message->PrefixString, (int)strnlen(message->PrefixString, INT_MAX),
103
0
          0, &udpAppender->targetAddr, udpAppender->targetAddrLen);
104
0
  _sendto(udpAppender->sock, message->TextString, (int)strnlen(message->TextString, INT_MAX), 0,
105
0
          &udpAppender->targetAddr, udpAppender->targetAddrLen);
106
0
  _sendto(udpAppender->sock, "\n", 1, 0, &udpAppender->targetAddr, udpAppender->targetAddrLen);
107
0
  return TRUE;
108
0
}
109
110
static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
111
                                              wLogMessage* message)
112
0
{
113
0
  if (!log || !appender || !message)
114
0
    return FALSE;
115
116
0
  return TRUE;
117
0
}
118
119
static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
120
                                               wLogMessage* message)
121
0
{
122
0
  if (!log || !appender || !message)
123
0
    return FALSE;
124
125
0
  return TRUE;
126
0
}
127
128
static BOOL WLog_UdpAppender_Set(wLogAppender* appender, const char* setting, void* value)
129
0
{
130
0
  const char target[] = "target";
131
0
  wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
132
133
  /* Just check the value string is not empty */
134
0
  if (!value || (strnlen(value, 2) == 0))
135
0
    return FALSE;
136
137
0
  if (strncmp(target, setting, sizeof(target)))
138
0
    return FALSE;
139
140
0
  udpAppender->targetAddrLen = 0;
141
142
0
  if (udpAppender->host)
143
0
    free(udpAppender->host);
144
145
0
  udpAppender->host = _strdup((const char*)value);
146
0
  return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
147
0
}
148
149
static void WLog_UdpAppender_Free(wLogAppender* appender)
150
0
{
151
0
  wLogUdpAppender* udpAppender = NULL;
152
153
0
  if (appender)
154
0
  {
155
0
    udpAppender = (wLogUdpAppender*)appender;
156
157
0
    if (udpAppender->sock != INVALID_SOCKET)
158
0
    {
159
0
      closesocket(udpAppender->sock);
160
0
      udpAppender->sock = INVALID_SOCKET;
161
0
    }
162
163
0
    free(udpAppender->host);
164
0
    free(udpAppender);
165
0
  }
166
0
}
167
168
wLogAppender* WLog_UdpAppender_New(wLog* log)
169
0
{
170
0
  wLogUdpAppender* appender = NULL;
171
0
  DWORD nSize = 0;
172
0
  LPCSTR name = NULL;
173
0
  appender = (wLogUdpAppender*)calloc(1, sizeof(wLogUdpAppender));
174
175
0
  if (!appender)
176
0
    return NULL;
177
178
0
  appender->Type = WLOG_APPENDER_UDP;
179
0
  appender->Open = WLog_UdpAppender_Open;
180
0
  appender->Close = WLog_UdpAppender_Close;
181
0
  appender->WriteMessage = WLog_UdpAppender_WriteMessage;
182
0
  appender->WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
183
0
  appender->WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
184
0
  appender->Free = WLog_UdpAppender_Free;
185
0
  appender->Set = WLog_UdpAppender_Set;
186
0
  appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
187
188
0
  if (appender->sock == INVALID_SOCKET)
189
0
    goto error_sock;
190
191
0
  name = "WLOG_UDP_TARGET";
192
0
  nSize = GetEnvironmentVariableA(name, NULL, 0);
193
194
0
  if (nSize)
195
0
  {
196
0
    appender->host = (LPSTR)malloc(nSize);
197
198
0
    if (!appender->host)
199
0
      goto error_open;
200
201
0
    if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
202
0
      goto error_open;
203
204
0
    if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
205
0
      goto error_open;
206
0
  }
207
0
  else
208
0
  {
209
0
    appender->host = _strdup("127.0.0.1:20000");
210
211
0
    if (!appender->host)
212
0
      goto error_open;
213
0
  }
214
215
0
  return (wLogAppender*)appender;
216
0
error_open:
217
0
  free(appender->host);
218
0
  closesocket(appender->sock);
219
0
error_sock:
220
0
  free(appender);
221
0
  return NULL;
222
0
}