Coverage Report

Created: 2025-07-01 06:46

/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(WINPR_ATTR_UNUSED 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
  char* colonPos = NULL;
46
47
0
  if (!appender)
48
0
    return FALSE;
49
50
0
  udpAppender = (wLogUdpAppender*)appender;
51
52
0
  if (udpAppender->targetAddrLen) /* already opened */
53
0
    return TRUE;
54
55
0
  colonPos = strchr(udpAppender->host, ':');
56
57
0
  if (!colonPos)
58
0
    return FALSE;
59
60
0
  const size_t addrLen = WINPR_ASSERTING_INT_CAST(size_t, (colonPos - udpAppender->host));
61
0
  memcpy(addressString, udpAppender->host, addrLen);
62
0
  addressString[addrLen] = '\0';
63
0
  hints.ai_family = AF_INET;
64
0
  hints.ai_socktype = SOCK_DGRAM;
65
0
  status = getaddrinfo(addressString, colonPos + 1, &hints, &result);
66
67
0
  if (status != 0)
68
0
    return FALSE;
69
70
0
  if (result->ai_addrlen > sizeof(udpAppender->targetAddr))
71
0
  {
72
0
    freeaddrinfo(result);
73
0
    return FALSE;
74
0
  }
75
76
0
  memcpy(&udpAppender->targetAddr, result->ai_addr, result->ai_addrlen);
77
0
  udpAppender->targetAddrLen = (int)result->ai_addrlen;
78
0
  freeaddrinfo(result);
79
0
  return TRUE;
80
0
}
81
82
static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
83
0
{
84
0
  if (!log || !appender)
85
0
    return FALSE;
86
87
0
  return TRUE;
88
0
}
89
90
static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
91
0
{
92
0
  char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
93
0
  wLogUdpAppender* udpAppender = NULL;
94
95
0
  if (!log || !appender || !message)
96
0
    return FALSE;
97
98
0
  udpAppender = (wLogUdpAppender*)appender;
99
0
  message->PrefixString = prefix;
100
0
  WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
101
0
  (void)_sendto(udpAppender->sock, message->PrefixString,
102
0
                (int)strnlen(message->PrefixString, INT_MAX), 0, &udpAppender->targetAddr,
103
0
                udpAppender->targetAddrLen);
104
0
  (void)_sendto(udpAppender->sock, message->TextString,
105
0
                (int)strnlen(message->TextString, INT_MAX), 0, &udpAppender->targetAddr,
106
0
                udpAppender->targetAddrLen);
107
0
  (void)_sendto(udpAppender->sock, "\n", 1, 0, &udpAppender->targetAddr,
108
0
                udpAppender->targetAddrLen);
109
0
  return TRUE;
110
0
}
111
112
static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
113
                                              wLogMessage* message)
114
0
{
115
0
  if (!log || !appender || !message)
116
0
    return FALSE;
117
118
0
  return TRUE;
119
0
}
120
121
static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
122
                                               wLogMessage* message)
123
0
{
124
0
  if (!log || !appender || !message)
125
0
    return FALSE;
126
127
0
  return TRUE;
128
0
}
129
130
static BOOL WLog_UdpAppender_Set(wLogAppender* appender, const char* setting, void* value)
131
0
{
132
0
  const char target[] = "target";
133
0
  wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
134
135
  /* Just check the value string is not empty */
136
0
  if (!value || (strnlen(value, 2) == 0))
137
0
    return FALSE;
138
139
0
  if (strncmp(target, setting, sizeof(target)) != 0)
140
0
    return FALSE;
141
142
0
  udpAppender->targetAddrLen = 0;
143
144
0
  if (udpAppender->host)
145
0
    free(udpAppender->host);
146
147
0
  udpAppender->host = _strdup((const char*)value);
148
0
  return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
149
0
}
150
151
static void WLog_UdpAppender_Free(wLogAppender* appender)
152
0
{
153
0
  wLogUdpAppender* udpAppender = NULL;
154
155
0
  if (appender)
156
0
  {
157
0
    udpAppender = (wLogUdpAppender*)appender;
158
159
0
    if (udpAppender->sock != INVALID_SOCKET)
160
0
    {
161
0
      closesocket(udpAppender->sock);
162
0
      udpAppender->sock = INVALID_SOCKET;
163
0
    }
164
165
0
    free(udpAppender->host);
166
0
    free(udpAppender);
167
0
  }
168
0
}
169
170
wLogAppender* WLog_UdpAppender_New(wLog* log)
171
0
{
172
0
  wLogUdpAppender* appender = NULL;
173
0
  DWORD nSize = 0;
174
0
  LPCSTR name = NULL;
175
0
  appender = (wLogUdpAppender*)calloc(1, sizeof(wLogUdpAppender));
176
177
0
  if (!appender)
178
0
    return NULL;
179
180
0
  appender->Type = WLOG_APPENDER_UDP;
181
0
  appender->Open = WLog_UdpAppender_Open;
182
0
  appender->Close = WLog_UdpAppender_Close;
183
0
  appender->WriteMessage = WLog_UdpAppender_WriteMessage;
184
0
  appender->WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
185
0
  appender->WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
186
0
  appender->Free = WLog_UdpAppender_Free;
187
0
  appender->Set = WLog_UdpAppender_Set;
188
0
  appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
189
190
0
  if (appender->sock == INVALID_SOCKET)
191
0
    goto error_sock;
192
193
0
  name = "WLOG_UDP_TARGET";
194
0
  nSize = GetEnvironmentVariableA(name, NULL, 0);
195
196
0
  if (nSize)
197
0
  {
198
0
    appender->host = (LPSTR)malloc(nSize);
199
200
0
    if (!appender->host)
201
0
      goto error_open;
202
203
0
    if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
204
0
      goto error_open;
205
206
0
    if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
207
0
      goto error_open;
208
0
  }
209
0
  else
210
0
  {
211
0
    appender->host = _strdup("127.0.0.1:20000");
212
213
0
    if (!appender->host)
214
0
      goto error_open;
215
0
  }
216
217
0
  return (wLogAppender*)appender;
218
0
error_open:
219
0
  free(appender->host);
220
0
  closesocket(appender->sock);
221
0
error_sock:
222
0
  free(appender);
223
0
  return NULL;
224
0
}