libkafs: derivation from non-DES key (rxkad-kdf)
[heimdal.git] / lib / roken / syslogc.c
blobf4fb539a634fd65ed3b702d8f7c5d4d0ba72e6f2
1 /***********************************************************************
2 * Copyright (c) 2009, Secure Endpoints Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 **********************************************************************/
33 * Based on code by Alexander Yaworsky
36 #include <config.h>
38 #include <roken.h>
40 #define SYSLOG_DGRAM_SIZE 1024
42 static BOOL syslog_opened = FALSE;
44 static int syslog_mask = 0xFF;
45 static char syslog_ident[ 128 ] = "";
46 static int syslog_facility = LOG_USER;
47 static char syslog_procid_str[ 20 ];
49 static SOCKADDR_IN syslog_hostaddr;
50 static SOCKET syslog_socket = INVALID_SOCKET;
51 static char local_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ];
53 static char syslog_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ] = "localhost";
54 static unsigned short syslog_port = SYSLOG_PORT;
56 static int datagramm_size;
58 volatile BOOL initialized = FALSE;
59 BOOL wsa_initialized = FALSE;
60 CRITICAL_SECTION cs_syslog;
62 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
63 init_syslog(const char * hostname)
65 WSADATA wsd;
66 char * service;
68 if ( initialized )
69 return;
71 if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) ) {
72 fprintf(stderr, "Can't initialize WinSock\n");
73 /* we let the rest of the initialization code go through,
74 although none of the syslog calls would succeed. */
75 } else {
76 wsa_initialized = TRUE;
79 if (hostname)
80 strcpy_s(syslog_hostname, sizeof(syslog_hostname), hostname);
81 else
82 strcpy_s(syslog_hostname, sizeof(syslog_hostname), "");
84 service = strchr(syslog_hostname, ':');
86 if (service) {
87 int tp;
89 *service++ = '\0';
91 if ((tp = atoi(service)) <= 0) {
92 struct servent * se;
94 se = getservbyname(service, "udp");
96 syslog_port = (se == NULL)? SYSLOG_PORT: se->s_port;
97 } else {
98 syslog_port = (unsigned short) tp;
100 } else {
101 syslog_port = SYSLOG_PORT;
104 InitializeCriticalSection(&cs_syslog);
105 initialized = TRUE;
107 atexit(exit_syslog);
110 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
111 exit_syslog(void)
113 if ( !initialized )
114 return;
116 closelog();
118 if ( wsa_initialized )
119 WSACleanup();
121 DeleteCriticalSection(&cs_syslog);
122 initialized = FALSE;
125 static void init_logger_addr()
127 struct hostent * phe = NULL;
129 memset( &syslog_hostaddr, 0, sizeof(SOCKADDR_IN) );
130 syslog_hostaddr.sin_family = AF_INET;
132 if (syslog_hostname[0] == '\0')
133 goto use_default;
135 phe = gethostbyname( syslog_hostname );
136 if( !phe )
137 goto use_default;
139 memcpy( &syslog_hostaddr.sin_addr.s_addr, phe->h_addr, phe->h_length );
141 syslog_hostaddr.sin_port = htons( syslog_port );
142 return;
144 use_default:
145 syslog_hostaddr.sin_addr.S_un.S_addr = htonl( 0x7F000001 );
146 syslog_hostaddr.sin_port = htons( SYSLOG_PORT );
149 /******************************************************************************
150 * closelog
152 * Close desriptor used to write to system logger.
154 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
155 closelog()
157 if ( !initialized )
158 return;
160 EnterCriticalSection(&cs_syslog);
161 if( syslog_opened ) {
162 closesocket( syslog_socket );
163 syslog_socket = INVALID_SOCKET;
164 syslog_opened = FALSE;
166 LeaveCriticalSection(&cs_syslog);
169 /******************************************************************************
170 * openlog
172 * Open connection to system logger.
174 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
175 openlog( char* ident, int option, int facility )
177 BOOL failed = FALSE;
178 SOCKADDR_IN sa_local;
179 DWORD n;
180 int size;
182 if ( !initialized )
183 return;
185 EnterCriticalSection(&cs_syslog);
187 if( syslog_opened )
188 goto done;
190 failed = TRUE;
192 syslog_facility = facility? facility : LOG_USER;
194 if( option & LOG_PID )
195 sprintf_s( syslog_procid_str, sizeof(syslog_procid_str), "[%lu]", GetCurrentProcessId() );
196 else
197 syslog_procid_str[0] = '\0';
199 /* FIXME: handle other options */
201 n = sizeof(local_hostname);
202 if( !GetComputerName( local_hostname, &n ) )
203 goto done;
205 syslog_socket = INVALID_SOCKET;
207 init_logger_addr();
209 for( n = 0;; n++ )
211 syslog_socket = socket( AF_INET, SOCK_DGRAM, 0 );
212 if( INVALID_SOCKET == syslog_socket )
213 goto done;
215 memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
216 sa_local.sin_family = AF_INET;
217 if( bind( syslog_socket, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
218 break;
219 rk_closesocket( syslog_socket );
220 syslog_socket = INVALID_SOCKET;
221 if( n == 100 )
222 goto done;
223 Sleep(0);
226 /* get size of datagramm */
227 size = sizeof(datagramm_size);
228 if( getsockopt( syslog_socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &size ) )
229 goto done;
230 if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 )
231 goto done;
232 if( datagramm_size > SYSLOG_DGRAM_SIZE )
233 datagramm_size = SYSLOG_DGRAM_SIZE;
235 if (ident)
236 strcpy_s(syslog_ident, sizeof(syslog_ident), ident);
238 syslog_facility = (facility ? facility : LOG_USER);
239 failed = FALSE;
241 done:
242 if( failed ) {
243 if( syslog_socket != INVALID_SOCKET )
244 rk_closesocket( syslog_socket );
246 syslog_opened = !failed;
248 LeaveCriticalSection(&cs_syslog);
251 /******************************************************************************
252 * setlogmask
254 * Set the log mask level.
256 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
257 setlogmask( int mask )
259 int ret;
261 if ( !initialized )
262 return 0;
264 EnterCriticalSection(&cs_syslog);
266 ret = syslog_mask;
267 if( mask )
268 syslog_mask = mask;
270 LeaveCriticalSection(&cs_syslog);
272 return ret;
275 /******************************************************************************
276 * syslog
278 * Generate a log message using FMT string and option arguments.
280 ROKEN_LIB_FUNCTION void
281 syslog( int pri, char* fmt, ... )
283 va_list ap;
285 va_start( ap, fmt );
286 vsyslog( pri, fmt, ap );
287 va_end( ap );
290 /******************************************************************************
291 * vsyslog
293 * Generate a log message using FMT and using arguments pointed to by AP.
295 ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
296 vsyslog( int pri, char* fmt, va_list ap )
298 static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
299 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
300 char datagramm[ SYSLOG_DGRAM_SIZE ];
301 SYSTEMTIME stm;
302 int len;
303 char *p;
305 if ( !initialized )
306 return;
308 EnterCriticalSection(&cs_syslog);
310 if( !(LOG_MASK( LOG_PRI( pri )) & syslog_mask) )
311 goto done;
313 openlog( NULL, 0, pri & LOG_FACMASK );
314 if( !syslog_opened )
315 goto done;
317 if( !(pri & LOG_FACMASK) )
318 pri |= syslog_facility;
320 GetLocalTime( &stm );
321 len = sprintf_s( datagramm, sizeof(datagramm),
322 "<%d>%s %2d %02d:%02d:%02d %s %s%s: ",
323 pri,
324 month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond,
325 local_hostname, syslog_ident, syslog_procid_str );
326 vsprintf_s( datagramm + len, datagramm_size - len, fmt, ap );
327 p = strchr( datagramm, '\n' );
328 if( p )
329 *p = 0;
330 p = strchr( datagramm, '\r' );
331 if( p )
332 *p = 0;
334 sendto( syslog_socket, datagramm, strlen(datagramm), 0, (SOCKADDR*) &syslog_hostaddr, sizeof(SOCKADDR_IN) );
336 done:
337 LeaveCriticalSection(&cs_syslog);