7.2. Globus Toolkit data grid low-level API: globus_io

To use this API, you must activate the GLOBUS_IO module in your program:

globus_module_activate(GLOBUS_IO_MODULE)

Note

The complete Globus IO API documentation is available from the Globus project Web site at the following URL:

http://www-unix.globus.org/api/c-globus-2.2/globus_io/html/index.html


The globus_io library was motivated by the desire to provide a uniform I/O interface to stream and datagram style communications. It provides wrappers for using TCP and UDP sockets and file I/O.

The Globus Toolkit 2.2 uses a specific handle to refer to a file. It is defined as globus_io_handle_t.

Two functions are provided to retrieve I/O handles:

  • globus_io_file_posix_convert(), which can convert a normal file descriptor into a Globus Toolkit 2.2 handle

  • globus_io_file_open(), which creates a Globus Toolkit 2.2 handle from a file name

The Globus Toolkit 2.2 provides I/O functions that map the POSIX systems calls and use the Globus Toolkit 2.2 file handle as a parameter instead of the file descriptor.

  • globus_io_read(), globus_io_write()

  • globus_io_writev() for vectorized write operations

Globus Toolkit 2.2 provides an asynchronous or non-blocking I/O that uses a callback mechanism. The callback is a function given as a parameter to the globus_io calls that will be called when the operation has completed. By using condition variables, the call back can alert the process that the operation has completed.

  • globus_io_register_read(),globus_io_register_write()

  • globus_io_register_writev()

The Globus Toolkit 2.2 provides functions to manipulate socket attributes, and by doing so extends the POSIX system sockets calls. In particular, it provides a set of functions, globus_io_attr_*(), that are used to establish authentication and authorization at the socket level (see Example 7-12 on page 173 and Example 7-13 on page 176).

An Internet socket is described as a globus_io_handle_t structure in the globus_io API. This handle is created when calling the followings Globus functions:

  • globus_io_tcp_create_listener()

  • globus_io_tcp_accept(), globus_io_tcp_register_accept()

  • globus_io_tcp_connect()

These functions are respectively equivalent to the listen(), accept(), and connect() POSIX system calls. globus_io_tcp_register_accept() is the asynchronous version of globus_io_tcp_accept().

The Globus API adds authorization, authentication, and encryption features to the normal POSIX sockets via GSI and OpenSSL libraries. A handle of type globus_io_secure_authorization_data_t is used to manipulate these additional security attributes. It needs to be initialized via globus_io_secure_authorization_data_initialize() before being used in other functions.

  • globus_io_attr_set_secure_authentication_mode() is used to determine whether to call the GSSAPI security context establishment functions once a socket connection is established. A credential handle is provided to the function and needs to be initialized before it is used. See the getCredential() function in Example 7-12 on page 173.

    Example 7-6. Activating GSSAPI security on a socket communication
    globus_io_attr_set_secure_authentication_mode(
          &io_attr,       //globus_io_handle_t
          GLOBUS_IO_SECURE_AUTHENTICATION_MODE_GSSAPI, // use GSI
          credential_handle));
    

  • globus_io_attr_set_secure_authorization_mode() is used to determine what security identities to authorize as the peer-to-security handshake that is done when making an authenticated connection. The functions take both a globus_io handle and a Globus secure attribute handle.

    The mode is specified in the second argument. GLOBUS_IO_SECURE_AUTHORIZATION_MODE_SELF authorizes any connection with the same credentials as the local credentials used when creating this handle.

For the complete list of available authorization modes, see

http://www-unix.globus.org/api/c-globus-2.2/globus_io/html/group__security.html#a7

Example 7-7. globus_io_attr_set_secure_authorization_mode()
globus_io_attr_set_secure_authorization_mode(
      &io_attr, //globus_io_handle_t
      GLOBUS_IO_SECURE_AUTHORIZATION_MODE_SELF,
      &auth_data)

  • globus_io_attr_set_secure_channel_mode() is used to determine if any data wrapping should be done on the socket connection. GLOBUS_IO_SECURE_CHANNEL_MODE_GSI_WRAP indicates that data protection is provided, with support for GSI features, such as delegation.

    Example 7-8. globus_io_attr_set_secure_channel_mode()
    globus_io_attr_set_secure_channel_mode(
          &io_attr,    //globus_io_handle_t
          GLOBUS_IO_SECURE_CHANNEL_MODE_GSI_WRAP);
    

  • globus_io_attr_set_secure_protection_mode() is used to determine if any data protection should be done on the socket connection. Use GLOBUS_IO_SECURE_PROTECTION_MODE_PRIVATE for encrypted messages, GLOBUS_IO_SECURE_PROTECTION_MODE_SAFE to only check the message integrity, and GLOBUS_IO_SECURE_PROTECTION_MODE_NONE for no protection.

    Example 7-9. Encrypted sockets
    globus_io_attr_set_secure_protection_mode(
          &io_attr,    //globus_io_handle_t
          GLOBUS_IO_SECURE_PROTECTION_MODE_PRIVATE);
    

  • globus_io_attr_set_secure_delegation_mode() is used to determine whether the process' credentials should be delegated to the other side of the connection. GLOBUS_IO_SECURE_DELEGATION_MODE_FULL_PROXY delegates full credentials to the server.

    Example 7-10. Delegation mode
    globus_io_attr_set_secure_delegation_mode(
          &io_attr,    //globus_io_handle_t
          GLOBUS_IO_SECURE_DELEGATION_MODE_FULL_PROXY);
    

  • globus_io_attr_set_secure_proxy_mode() is used to determine whether the process should accept limited proxy certificates for authentication. Use GLOBUS_IO_SECURE_PROXY_MODE_MANY to accept any proxy as a valid authentication.

    Example 7-11. globus_io_set_secure_proxy_mode()
    globus_io_attr_set_secure_proxy_mode(
          &io_attr,    //globus_io_handle_t
          GLOBUS_IO_SECURE_PROXY_MODE_MANY);
    

7.2.1. globus_io example

In this example we establish a secure and authenticated communication between two hosts by using the globus_io functions. We submit from host m0.itso-maya.com a job (gsiclient2) to t2.itso-tupi.com that will try to communicate with a server already running on m0.itso-maya.com (gsiserver2). This process will print Hello World as soon as the message is received. The two processes will use mutual authentication, which means that they need to run with the same credentials on both hosts. By using the gatekeeper, the submitted job will use the same credentials as the user that submitted the job. The communication will be securely authenticated between the two hosts. The communication is also encrypted: We use the globus_io_attr_set_secure_protection_mode() call to activate encryption.

Figure 7-3. Using globus_io for secure communication


To compile the two programs:

1.
First create the Makefile header with:

globus-makefile-header -flavor gcc32 globus_io globus_gss_assist >
globus_header

2.
Use the following Makefile to compile:

include globus_header

all: gsi gsisocketclient gsisocketserver

gsisocketclient: gsisocketclient.C
   g++ -g -o gsisocketclient $(GLOBUS_CPPFLAGS) $(GLOBUS_LDFLAGS)
gsisocketclient.C $(GLOBUS_PKG_LIBS)

gsisocketserver: gsisocketserver.C
   g++ -g -o gsisocketserver $(GLOBUS_CPPFLAGS) $(GLOBUS_LDFLAGS)
gsisocketserver.C $(GLOBUS_PKG_LIBS)

3.
Start the monitoring program on m0.itso-maya.com by issuing:

./gsisocketserver

4.
Submit the job on t2.itso-tupi.com:

[globus@m0 globus]$ grid-proxy-init
Your identity: /O=Grid/O=Globus/OU=itso-maya.com/CN=globus
Enter GRID pass phrase for this identity:
Creating proxy ........................................... Done
Your proxy is valid until: Mon Mar 3 23:37:23 2003
[globus@m0 globus]$ gsiscp gsiclient2 t2.itso-tupi.com:.
gsiclient2           100% |**************************************|  126
KB    00:00
[globus@m0 globus]$ globusrun -o -r t2
'&(executable=/home/globus/gsisocketclient)
(arguments=http://m0.itso-maya.com:10000)'
m0.itso-maya.com
10000
23

On the monitoring side you should see:

[globus@m0 globus]$ ./gsisocketserver
Hello world (secured) !@23

7.2.2. Skeleton source code for creating a simple GSI socket

Below we review the skeleton source code for creating a simple GSI socket.

Example 7-12. globus-io client - gsisocketclient.C
#include <iostream>
#include <globus_io.h>
#include "globus_gss_assist.h"
#include <string>

// macro to use a C++ string class as a char* parmeter in a C function
#define STR(a) const_cast<char*>(a.c_str())

//*****************************************************************************
// This macro is defined for debugging reasons.  It checks the status of the
// globus calls and displays the Globus error message
// The t variable needs to be defined before
// ****************************************************************************
#define _(a) t=a;
   if (t!=GLOBUS_SUCCESS) {
                 cerr <<
globus_object_printable_to_string(globus_error_get(t));
       }
// ****************************************************************************


// ****************************************************************************
// This function is used to check the validity of the local credentials
// probably generated by gatekeeper or gsi ssh server
// ****************************************************************************
bool getCredential(gss_cred_id_t* credential_handle) {
   OM_uint32 major_status;
   OM_uint32 minor_status;

   major_status = globus_gss_assist_acquire_cred(&minor_status,
                               GSS_C_INITIATE, /* or GSS_C_ACCEPT */
                               credential_handle);

        if (major_status != GSS_S_COMPLETE)
       return false;
    else
       return true;
}

// ****************************************************************************
// ****************************************************************************
// Here is the main program: create a socket, connect to the server and say
Hello
// _() macro is used to check the error code of each Globus function and
//      display the Globus Error message
// The first argument will be used to indicate the server to connect
// to, for example http://m0.itso-maya.com:10000
//
*******************************************************************************
main(int argc, char** argv) {
   //First thing to do, activate the module !
   globus_module_activate(GLOBUS_IO_MODULE);

   globus_io_attr_t io_attr;
   globus_io_tcpattr_init(&io_attr);
   gss_cred_id_t credential_handle = GSS_C_NO_CREDENTIAL;
   if (!getCredential(&credential_handle)) {
      cerr << "you are not authenticated";
      exit(1);
   }

   globus_io_secure_authorization_data_t auth_data;
   globus_io_secure_authorization_data_initialize (&auth_data);
   globus_result_t t;
   _(globus_io_attr_set_secure_authentication_mode(
                  &io_attr,
                  GLOBUS_IO_SECURE_AUTHENTICATION_MODE_GSSAPI,  // use GSI
                  credential_handle));
   _(globus_io_attr_set_secure_authorization_mode(
        &io_attr,
        GLOBUS_IO_SECURE_AUTHORIZATION_MODE_SELF,
        &auth_data));
   // We want encrypted communication !
   // if not use GLOBUS_IO_SECURE_CHANNEL_MODE_CLEAR
   _(globus_io_attr_set_secure_channel_mode(
         &io_attr,
         GLOBUS_IO_SECURE_CHANNEL_MODE_GSI_WRAP));
   _(globus_io_attr_set_secure_protection_mode(
         &io_attr,
         GLOBUS_IO_SECURE_PROTECTION_MODE_PRIVATE)); //encryption
   // will see later for the delegation
   _(globus_io_attr_set_secure_delegation_mode(
         &io_attr,
         GLOBUS_IO_SECURE_DELEGATION_MODE_FULL_PROXY));
   _(globus_io_attr_set_secure_proxy_mode(
                       &io_attr,
                       GLOBUS_IO_SECURE_PROXY_MODE_MANY));

   // The first argument like http://m0.itso-tupi.com:10000 is
   // parsed by using the globus_url_parse() function
   globus_url_t     parsed_url;
   if (globus_url_parse(argv[1], &parsed_url)!=GLOBUS_SUCCESS) {
      cerr << "invalid URL" << endl;
      exit(1);
   };

   globus_io_handle_t connection;
   // use globus_io_tcp_register_connect for
   // asynchronous connect. Here, this is a blocking call
   _(globus_io_tcp_connect(
         parsed_url.host,
         parsed_url.port,
         &io_attr,
         &connection));
   cout << parsed_url.host << endl << parsed_url.port << endl;

   globus_size_t n;
   string msg("Hello world (secured) !");
   _(globus_io_write(&connection,
          (globus_byte_t*)STR(msg),
          msg.length(),
          &n));
   cout << n <<endl;
};

Example 7-13. globus-io example server - gsisocketserver.C
#include <iostream>
#include <globus_io.h>
#include <globus_io.h>
#include "globus_gss_assist.h"

//*****************************************************************************
// This macro is defined for debugging reasons.  It checks the status of the
// globus calls and displays the Globus error message
// The t variable needs to be defined before
// ****************************************************************************
#define _(a) t=a;
        if (t!=GLOBUS_SUCCESS) {
                 cerr <<
globus_object_printable_to_string(globus_error_get(t));
                 exit(1);
        }
//****************************************************************************
// This function is used to check the validity of the local credentials
// probably generated by the grid-proxy-init
bool getCredential(gss_cred_id_t* credential_handle) {
           OM_uint32 major_status;
           OM_uint32 minor_status;

            major_status = globus_gss_assist_acquire_cred(&minor_status,
                                       GSS_C_INITIATE, /* or GSS_C_ACCEPT */
                                            credential_handle);

            if (major_status != GSS_S_COMPLETE)
                    return false;
            else
                    return true;
}

//****************************************************************************
// Main program: create a listen socket, receive the message and close the
socket
// _() macro is used to check the error code of each Globus function and
// display the Globus Error message
// ****************************************************************************
main() {
   //First thing to do, activate the module !
    globus_module_activate(GLOBUS_IO_MODULE);
    globus_result_t t;

    globus_io_attr_t io_attr;
         globus_io_tcpattr_init(&io_attr);

    gss_cred_id_t credential_handle = GSS_C_NO_CREDENTIAL;
    // Authenticate with the GSSAPI library
        if (!getCredential(&credential_handle)) {
                cerr << "you are not authenticated";
                exit(1);
        };

    globus_io_secure_authorization_data_t auth_data;
    globus_io_secure_authorization_data_initialize (&auth_data);
    _(globus_io_attr_set_secure_authentication_mode(
       &io_attr,
       GLOBUS_IO_SECURE_AUTHENTICATION_MODE_GSSAPI,
       credential_handle));
       _(globus_io_attr_set_secure_authorization_mode(
                 &io_attr,
            GLOBUS_IO_SECURE_AUTHORIZATION_MODE_SELF,
                 &auth_data));
       // We want encrypted communication !
       // if not use GLOBUS_IO_SECURE_CHANNEL_MODE_CLEAR
         _(globus_io_attr_set_secure_channel_mode(
                 &io_attr,
                 GLOBUS_IO_SECURE_CHANNEL_MODE_GSI_WRAP));
          _(globus_io_attr_set_secure_protection_mode(
                 &io_attr,
                 GLOBUS_IO_SECURE_PROTECTION_MODE_PRIVATE)); //encryption
         // will see later for the delegation
         _(globus_io_attr_set_secure_delegation_mode(
                 &io_attr,
                 GLOBUS_IO_SECURE_DELEGATION_MODE_FULL_PROXY));
    _(globus_io_attr_set_secure_proxy_mode(
          &io_attr,
          GLOBUS_IO_SECURE_PROXY_MODE_MANY));

    unsigned short port=10000;
    globus_io_handle_t handle;
    _(globus_io_tcp_create_listener(
          &port,
          -1,
          &io_attr,
          &handle));

    _(globus_io_tcp_listen(&handle));
    globus_io_handle_t newhandle;
    _(globus_io_tcp_accept(&handle,GLOBUS_NULL,&newhandle));
    globus_size_t n;
    char buf[500];
    _(globus_io_read( &newhandle,
           (globus_byte_t*)buf,
           500,
           5,
           &n));
    cout << buf << n << endl;
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.246.148