NAME

catgen_server - initialize and enter Agent server mode

SYNOPSIS

#include <cat/gen.h>

int catgen_server(const char *service, int argc, char **argv, catgen_sessfunc *newsession, void *data);

DESCRIPTION

This function runs an entire standalone Agent, leaving only the protocol-specific parts to be implemented. All information needed to run the Agent is located, using the catinfo interface, in the configuration.

The argc/argv are command line arguments. These are described in catgen.

catgen_server calls a number of other catgen functions. The same tasks can be performed explicitly if necessary. The catgen_server function implements the following steps:

Each new client connection causes the supplied function newsession() to be called, with the new session, the port where the connection was accepted (as a string), and the data pointer given as the last argument to catgen_server(). The catgen_sessfunc type looks as follows:

catgen_sessfunc(cat_session *sess, const char *port, void *data);

See catgen_listen for a more complete description of this callback function.

The newsession() function should handle authentication encryption negotiation schemes. This is preferably performed by the catgen_checkauth() and the catgen_serverencryption() functions. If everything is OK, the newsession() function should return CAT_CONTINUE to hand control to the framework.

The application server connection will always be established before newsession() is called.

LOGGING

If the Agent Host Virtual Card cannot be loaded, the CATLOG_HOSTPSDERR log event is generated.

If the configuration parameter .global.log.hostpsd is non-zero, the CATLOG_HOSTPSD event is logged.

If the server cannot be contacted, the CATLOG_CONNFAIL event is generated.

EXAMPLE

The following is a minimal, yet complete, code exercise illustrating how to build a proxy that filters any data passing through it and converts to uppercase any text received from the server.

 #include <cat/gen.h>
 #include <stdio.h>

 static int newsession(cat_session *, const char *, void *);
 static int upcase_fun(cat_session *, cat_filter *, int);

 #define AUTH             /* Undefine this to skip authentication. */

 int
 main(int argc, char **argv)
 {
     int code;

     code = catgen_server("agent-1.0", argc, argv,
                          newsession, NULL);
     exit(code);
 }

 /*
  * The callback function that gets called for each
  * incoming connection. 
  */
 static int
 newsession(cat_session *sess, const char *port, void *data)
 {
     int ret;
     cat_filter f;

     /* Perform encryption negotiation.
      * Depending on configuration, the agent
      * will use either DASP/ALLTAK or SSL
      * negotiation.
      */ 
     ret = catgen_serverencryption(sess);
     if (ret < 0) {
         return ret;
     }

 #ifdef AUTH
     /*
      * Check the user's access rights. If SSL
      * has been performed, the PAC will be 
      * checked for valid EARs. If DASP/ALLTAAS
      * has been performed, catgen_checkauth will
      * check with the Keon Security Server.
      */
     ret = catgen_checkauth(sess, NULL, NULL);
     if (ret < 0) {
         return ret;
     }     
 #endif

     /*
      * Push a filter to turn any text from the server 
      * into uppercase. Register the filter on the 
      * server read file descriptor. This means that
      * the filter's r/w function will only be called 
      * when there is data on that descriptor.  
      */
     memset(&f, 0, sizeof(f));
     f.fd_ids = CAT_SERVER_RFD;
     f.rw = upcase_fun;
     cat_pushfilter(sess, &f);

     /*
      * Everything has been set up. Hand over
      * control back to the frame work that will
      * start to shuffle data between the client and
      * the server.
      */        
     return CAT_CONTINUE;
 }

 /*
  * Filter r/w function. Turns any characters to uppercase.
  */
 int
 upcase_fun(cat_session *sess, cat_filter *filt, int id)
 {
     unsigned char *p;
     cat_buffer *buf;
     int n;

     /*
      * Get the data from the filter stack.
      */
     buf = catbuf_get(sess, id);        

     /*
      * Access each byte in the data buffer directly, and
      * modify them in-place.
      */
     while ((n = catbuf_block(buf, &p)) > -1) {
         while (n-- > 0) {
             if (*p >= 'A' && *p <= 'Z')
             *p += 'a'-'A';
             p++;
         }
     }

     /* 
      * Return the data to the filter stack.
      */
     catbuf_put(sess, id, buf);

     return CAT_OK;
 }

RETURN VALUES

catgen_server() will return only under the following circumstances:

  1. An error has occurred.

  2. The Agent times out.

  3. The control server instructs the Agent to exit.

catgen_server() returns a suitable exit code for the Agent to use as argument to exit(), with 0 indicating successful completion.

NOTES

The catgen_server function should be called only once during the lifetime of a process.

SEE ALSO

cat, catgen, catgen_listen, catgen_run, catgen_checkauth, catgen_serverencryption