@@ -197,7 +197,7 @@ int setup_socket(int argc, char *argv[])
197197}
198198
199199static int event_to_string (struct audit_dispatcher_header * hdr ,
200- char * data , char * * out , int * outlen )
200+ char * data , char * * out , int * outlen )
201201{
202202 char * v = NULL , * ptr , unknown [32 ];
203203 int len ;
@@ -246,75 +246,161 @@ static int event_to_string(struct audit_dispatcher_header *hdr,
246246 return 1 ;
247247}
248248
249- void read_audit_record (int ifd )
249+ /*
250+ * read_binary_record - read a binary dispatcher record
251+ * @fd: input descriptor
252+ * @hdr: pointer to header storage
253+ * @data: pointer to data storage
254+ *
255+ * This function reads exactly sizeof(*hdr) bytes followed by hdr->size
256+ * bytes from @fd. It returns the total bytes read or -1 on error and
257+ * 0 when EOF is reached.
258+ */
259+ static int read_binary_record (int fd , struct audit_dispatcher_header * hdr ,
260+ char * data )
250261{
251- do {
252- int len ;
262+ size_t len = sizeof (* hdr );
263+ char * ptr = (char * )hdr ;
264+ ssize_t rc ;
265+
266+ while (len ) {
267+ rc = read (fd , ptr , len );
268+ if (rc <= 0 ) {
269+ if (rc < 0 && errno == EINTR )
270+ continue ;
271+ return rc ;
272+ }
273+ ptr += rc ;
274+ len -= rc ;
275+ }
253276
254- // Read stdin
255- if ((len = auplugin_fgets (rx_buf ,MAX_AUDIT_EVENT_FRAME_SIZE + 1 ,
256- ifd )) > 0 ) {
257- #ifdef DEBUG
258- write (1 , rx_buf , len );
259- #endif
260- if (client && !stop ) {
261- // Send it to the client
262- int rc ;
263- struct audit_dispatcher_header * hdr =
264- (struct audit_dispatcher_header * )rx_buf ;
265- char * data = rx_buf +
266- sizeof (struct audit_dispatcher_header );
267-
268- if (inbound_protocol == -1 ) {
269- if (hdr -> ver == AUDISP_PROTOCOL_VER ||
270- hdr -> ver == AUDISP_PROTOCOL_VER2 )
271- inbound_protocol = F_BINARY ;
272- else
273- inbound_protocol = F_STRING ;
274- }
277+ if (hdr -> size > MAX_AUDIT_MESSAGE_LENGTH )
278+ hdr -> size = MAX_AUDIT_MESSAGE_LENGTH ;
279+
280+ len = hdr -> size ;
281+ ptr = data ;
282+ while (len ) {
283+ rc = read (fd , ptr , len );
284+ if (rc <= 0 ) {
285+ if (rc < 0 && errno == EINTR )
286+ continue ;
287+ return rc ;
288+ }
289+ ptr += rc ;
290+ len -= rc ;
291+ }
275292
276- if (format == F_STRING ) {
293+ return sizeof (* hdr ) + hdr -> size ;
294+ }
277295
278- char * str = NULL ;
279- int str_len = 0 ;
280- if (event_to_string (hdr , data , & str ,
281- & str_len ) < 0 ) {
282- // what to do with error?
283- continue ;
284- }
296+ void read_audit_record (int ifd )
297+ {
298+ int len ;
285299
286- do {
287- rc = write (conn , str , str_len );
288- } while (rc < 0 && errno == EINTR );
289- free (str );
290- } else if (format == F_BINARY ) {
291- struct iovec vec [2 ];
300+ if (inbound_protocol == F_BINARY || inbound_protocol == -1 ) {
301+ struct audit_dispatcher_header * hdr =
302+ (struct audit_dispatcher_header * )rx_buf ;
303+ char * data = rx_buf + sizeof (* hdr );
292304
293- vec [0 ].iov_base = hdr ;
294- vec [0 ].iov_len =
305+ len = read_binary_record (ifd , hdr , data );
306+ if (len <= 0 ) {
307+ if (len == 0 )
308+ stop = 1 ;
309+ return ;
310+ }
311+ if (inbound_protocol == -1 )
312+ inbound_protocol = F_BINARY ;
313+
314+ if (client && !stop ) {
315+ int rc ;
316+
317+ if (format == F_STRING ) {
318+ char * str = NULL ;
319+ int str_len = 0 ;
320+
321+ if (event_to_string (hdr , data , & str ,
322+ & str_len ) < 0 )
323+ return ;
324+
325+ do {
326+ rc = write (conn , str , str_len );
327+ } while (rc < 0 && errno == EINTR );
328+ free (str );
329+ } else if (format == F_BINARY ) {
330+ struct iovec vec [2 ];
331+
332+ vec [0 ].iov_base = hdr ;
333+ vec [0 ].iov_len = sizeof (* hdr );
334+
335+ vec [1 ].iov_base = data ;
336+ vec [1 ].iov_len = hdr -> size ;
337+
338+ do {
339+ rc = writev (conn , vec , 2 );
340+ } while (rc < 0 && errno == EINTR );
341+ if (rc < 0 && errno == EPIPE ) {
342+ close (conn );
343+ conn = -1 ; // FIXME: is this right?
344+ client = 0 ;
345+ auplugin_fgets_clear ();
346+ }
347+ }
348+ }
349+ } else {
350+ do {
351+ len = auplugin_fgets (rx_buf ,
352+ MAX_AUDIT_EVENT_FRAME_SIZE + 1 , ifd );
353+ if (len > 0 ) {
354+ if (inbound_protocol == -1 )
355+ inbound_protocol = F_STRING ;
356+ if (client && !stop ) {
357+ int rc ;
358+ char * data = rx_buf +
295359 sizeof (struct audit_dispatcher_header );
296-
297- vec [1 ].iov_base = data ;
298- vec [1 ].iov_len =
299- MAX_AUDIT_MESSAGE_LENGTH ;
300-
301- do {
302- rc = writev (conn , vec , 2 );
303- } while (rc < 0 && errno == EINTR );
304- if (rc < 0 && errno == EPIPE ) {
305- close (conn );
306- conn = -1 ;
307- client = 0 ;
308- auplugin_fgets_clear ();
360+ struct audit_dispatcher_header * hdr =
361+ (struct audit_dispatcher_header * )rx_buf ;
362+
363+ if (format == F_STRING ) {
364+ char * str = NULL ;
365+ int str_len = 0 ;
366+ if (event_to_string (hdr , data ,
367+ & str ,
368+ & str_len ) < 0 )
369+ continue ;
370+
371+ do {
372+ rc = write (conn , str ,
373+ str_len );
374+ } while (rc < 0 && errno == EINTR );
375+ free (str );
376+ } else if (format == F_BINARY ) {
377+ struct iovec vec [2 ];
378+
379+ vec [0 ].iov_base = hdr ;
380+ vec [0 ].iov_len =
381+ sizeof (* hdr );
382+
383+ vec [1 ].iov_base = data ;
384+ vec [1 ].iov_len =
385+ MAX_AUDIT_MESSAGE_LENGTH ;
386+
387+ do {
388+ rc = writev (conn , vec ,
389+ 2 );
390+ } while (rc < 0 && errno == EINTR );
391+ if (rc < 0 && errno == EPIPE ) {
392+ close (conn );
393+ conn = -1 ;
394+ client = 0 ;
395+ auplugin_fgets_clear ();
396+ }
309397 }
310- //if (rc >= 0 && rc != len) {
311- // what to do with leftovers?
312- //}
313398 }
314- }
315- } else if (auplugin_fgets_eof ())
316- stop = 1 ;
317- } while (!stop && auplugin_fgets_more (MAX_AUDIT_EVENT_FRAME_SIZE ));
399+ } else if (auplugin_fgets_eof ())
400+ stop = 1 ;
401+ } while (!stop &&
402+ auplugin_fgets_more (MAX_AUDIT_EVENT_FRAME_SIZE ));
403+ }
318404}
319405
320406void accept_connection (void )
0 commit comments