628 lines
28 KiB
HTML
628 lines
28 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE html
|
||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html lang="en-us" xml:lang="en-us">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="security" content="public" />
|
||
|
<meta name="Robots" content="index,follow" />
|
||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
||
|
<meta name="DC.Type" content="reference" />
|
||
|
<meta name="DC.Title" content="Example: GSKit secure server with asynchronous handshake" />
|
||
|
<meta name="abstract" content="The gsk_secure_soc_startInit() API allows you to create secure server applications that can handle request asynchronously." />
|
||
|
<meta name="description" content="The gsk_secure_soc_startInit() API allows you to create secure server applications that can handle request asynchronously." />
|
||
|
<meta name="DC.Relation" scheme="URI" content="x1ssl.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="cgskit.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="xgskserver.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/createiocompletionport.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/users_14.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/waitforiocompletion.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/destroyiocompletionport.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/bind.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/socket.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/listen.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/close.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/accept.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_open.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_buffer.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_enum.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_init.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_open.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_set_numeric_value.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_init.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/users_25.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_close.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_environment_close.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_attribute_get_numeric_value.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_write.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gskstartinit.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="../apis/gsk_secure_soc_read.htm" />
|
||
|
<meta name="DC.Relation" scheme="URI" content="xgskclient.htm" />
|
||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 2001, 2006" />
|
||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 2001, 2006" />
|
||
|
<meta name="DC.Format" content="XHTML" />
|
||
|
<meta name="DC.Identifier" content="xgskasynch" />
|
||
|
<meta name="DC.Language" content="en-us" />
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
||
|
<title>Example: GSKit secure server with asynchronous handshake </title>
|
||
|
</head>
|
||
|
<body id="xgskasynch"><a name="xgskasynch"><!-- --></a>
|
||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
||
|
<h1 class="topictitle1">Example: GSKit secure server with asynchronous handshake </h1>
|
||
|
<div><p>The <span class="apiname">gsk_secure_soc_startInit()</span> API allows you
|
||
|
to create secure server applications that can handle request asynchronously.</p>
|
||
|
<div class="section"><p>The following code sample provides an example of how this API
|
||
|
can be used. It is similar to the GSKit secure server with asynchronous data
|
||
|
receive example, but uses this new API to start a secure session. </p>
|
||
|
</div>
|
||
|
<div class="section"><p>The following graphic shows the function calls used to negotiate
|
||
|
an asynchronous handshake on a secure server:</p>
|
||
|
<br /><img src="rzab6514.gif" alt="Socket flow of events: GSKit secure server that uses asynchronous handshake" /><br /></div>
|
||
|
<div class="section"><p>To view the client portion of this graphic, see <a href="xgskclient.dita#xgskclient/gskclgraphic" target="_blank">GSKit client </a>.</p>
|
||
|
</div>
|
||
|
<div class="section"><h4 class="sectiontitle">Socket flow of events: GSKit secure server that uses asynchronous
|
||
|
handshake</h4><p>This flow describes the socket calls in the following
|
||
|
sample application.</p>
|
||
|
<ol><li>The <span class="apiname">QsoCreateIOCompletionPort()</span> function creates an
|
||
|
I/O completion port.</li>
|
||
|
<li>The <span class="apiname">pthread_create</span> function creates a worker thread
|
||
|
to process all client requests. The worker thread waits for client requests
|
||
|
to arrive on the I/O completion port just created.</li>
|
||
|
<li>A call to <span class="apiname">gsk_environment_open()</span> to obtain a handle
|
||
|
to an SSL environment.</li>
|
||
|
<li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the
|
||
|
SSL environment. At a minimum, either a call to <span class="apiname">gsk_attribute_set_buffer()</span> to
|
||
|
set the GSK_OS400_APPLICATION_ID value or to set the GSK_KEYRING_FILE value.
|
||
|
Only one of these should be set. It is preferred that you use the GSK_OS400_APPLICATION_ID
|
||
|
value. Also ensure you set the type of application (client or server), GSK_SESSION_TYPE,
|
||
|
using <span class="apiname">gsk_attribute_set_enum()</span>.</li>
|
||
|
<li>A call to <span class="apiname">gsk_environment_init()</span> to initialize this
|
||
|
environment for SSL processing and to establish the SSL security information
|
||
|
for all SSL sessions that run using this environment.</li>
|
||
|
<li>The <span class="apiname">socket</span> function creates a socket descriptor. The
|
||
|
server then issues the standard set of socket calls: <span class="apiname">bind()</span>, <span class="apiname">listen()</span>,
|
||
|
and <span class="apiname">accept()</span> to enable a server to accept incoming connection
|
||
|
requests.</li>
|
||
|
<li>The <span class="apiname">gsk_secure_soc_open()</span> function obtains storage
|
||
|
for a secure session, sets default values for attributes, and returns a handle
|
||
|
that must be saved and used on secure session-related function calls. </li>
|
||
|
<li>One or more calls to gsk_attribute_set_xxxxx() to set attributes of the
|
||
|
secure session. At a minimum, a call to <span class="apiname">gsk_attribute_set_numeric_value()</span> to
|
||
|
associate a specific socket with this secure session.</li>
|
||
|
<li>The <span class="apiname">gsk_secure_soc_startInit()</span> function
|
||
|
starts an asynchronous negotiation of a secure session, using the attributes
|
||
|
set for the SSL environment and the secure session. Control returns to the
|
||
|
program here. When the handshake processing is completed, the completion port
|
||
|
is posted with the results. The thread can continue on with other processing;
|
||
|
however, for simplicity, wait here for worker thread to complete. <div class="note"><span class="notetitle">Note:</span> Typically,
|
||
|
a server program must provide a certificate for an SSL handshake to succeed.
|
||
|
A server must also have access to the private key that is associated with
|
||
|
the server certificate and the key database file where the certificate is
|
||
|
stored. In some cases, a client must also provide a certificate during the
|
||
|
SSL handshake processing. This occurs if the server which the client is connecting
|
||
|
to has enabled client authentication. The <span class="apiname">gsk_attribute_set_buffer</span>(GSK_OS400_APPLICATION_ID)
|
||
|
or <span class="apiname">gsk_attribute_set_buffer</span>(GSK_KEYRING_FILE) API calls
|
||
|
identify (though in dissimilar ways) the key database file from which the
|
||
|
certificate and private key that are used during the handshake are obtained.</div>
|
||
|
|
||
|
</li>
|
||
|
<li>The <span class="apiname">pthread_join</span> synchronizes the server
|
||
|
and worker programs. This function waits for the thread to end, detaches the
|
||
|
thread, then returns the threads exit status to the server.</li>
|
||
|
<li>The <span class="apiname">gsk_secure_soc_close()</span> function ends the secure
|
||
|
session.</li>
|
||
|
<li>The <span class="apiname">gsk_environment_close()</span> function closes the SSL
|
||
|
environment. </li>
|
||
|
<li>The <span class="apiname">close()</span> function ends the listening socket.</li>
|
||
|
<li>The <span class="apiname">close()</span> ends the accepted (client connection) socket.</li>
|
||
|
<li>The <span class="apiname">QsoDestroyIOCompletionPort()</span> function destroys
|
||
|
the completion port.</li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
<div class="section"><h4 class="sectiontitle">Socket flow of events: Worker thread that process secure asynchronous
|
||
|
requests</h4><ol><li>After the server application creates a worker thread, it waits for server
|
||
|
to send it the incoming client request to process. The <span class="apiname">QsoWaitForIOCompletionPort()</span> function
|
||
|
waits on the supplied IO completion port that was specified by the server.
|
||
|
This call waits until the <span class="apiname">gsk_secure_soc_startInit()</span> is
|
||
|
completed. </li>
|
||
|
<li>As soon as the client request has been received, the <span class="apiname">gsk_attribute_get_numeric_value()</span> function
|
||
|
gets the socket descriptor associated with the secure session.</li>
|
||
|
<li>The <span class="apiname">gsk_secure_soc_read()</span> function receives a message
|
||
|
from the client using the secure session.</li>
|
||
|
<li>The <span class="apiname">gsk_secure_soc_write()</span> function sends the message
|
||
|
to the client using the secure session.</li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
<div class="section"><div class="note"><span class="notetitle">Note:</span> By using the code examples, you agree to the terms of the <a href="codedisclaimer.htm">Code license and disclaimer information</a>.</div>
|
||
|
<pre>/* GSK Asynchronous Server Program using Application Id*/
|
||
|
/* and gsk_secure_soc_startInit() */
|
||
|
|
||
|
/* Assummes that application id is already registered */
|
||
|
/* and a certificate has been associated with the */
|
||
|
/* application id. */
|
||
|
/* No parameters, some comments and many hardcoded */
|
||
|
/* values to keep it short and simple */
|
||
|
|
||
|
/* use following command to create bound program: */
|
||
|
/* CRTBNDC PGM(MYLIB/GSKSERVSI) */
|
||
|
/* SRCFILE(MYLIB/CSRC) */
|
||
|
/* SRCMBR(GSKSERVSI) */
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <gskssl.h>
|
||
|
#include <netinet/in.h>
|
||
|
#include <arpa/inet.h>
|
||
|
#include <errno.h>
|
||
|
#define _MULTI_THREADED
|
||
|
#include "pthread.h"
|
||
|
#include "qsoasync.h"
|
||
|
#define Failure 0
|
||
|
#define Success 1
|
||
|
#define TRUE 1
|
||
|
#define FALSE 0
|
||
|
|
||
|
void *workerThread(void *arg);
|
||
|
/********************************************************************/
|
||
|
/* Descriptive Name: Master thread will establish a client */
|
||
|
/* connection and hand processing responsibility */
|
||
|
/* to a worker thread. */
|
||
|
/* Note: Due to the thread attribute of this program, spawn() must */
|
||
|
/* be used to invoke. */
|
||
|
/********************************************************************/
|
||
|
int main(void)
|
||
|
{
|
||
|
gsk_handle my_env_handle=NULL; /* secure environment handle */
|
||
|
gsk_handle my_session_handle=NULL; /* secure session handle */
|
||
|
|
||
|
struct sockaddr_in address;
|
||
|
int buf_len, on = 1, rc = 0;
|
||
|
int sd = -1, lsd = -1, al, ioCompPort = -1;
|
||
|
int successFlag = FALSE;
|
||
|
pthread_t thr;
|
||
|
void *status;
|
||
|
Qso_OverlappedIO_t ioStruct;
|
||
|
|
||
|
/*********************************************/
|
||
|
/* Issue all of the command in a do/while */
|
||
|
/* loop so that clean up can happen at end */
|
||
|
/*********************************************/
|
||
|
|
||
|
do
|
||
|
{
|
||
|
/*********************************************/
|
||
|
/* Create an I/O completion port for this */
|
||
|
/* process. */
|
||
|
/*********************************************/
|
||
|
if ((ioCompPort = QsoCreateIOCompletionPort()) < 0)
|
||
|
{
|
||
|
perror("QsoCreateIOCompletionPort() failed");
|
||
|
break;
|
||
|
}
|
||
|
/*********************************************/
|
||
|
/* Create a worker thread */
|
||
|
/* to process all client requests. The */
|
||
|
/* worker thread will wait for client */
|
||
|
/* requests to arrive on the I/O completion */
|
||
|
/* port just created. */
|
||
|
/*********************************************/
|
||
|
rc = pthread_create(&thr, NULL, workerThread, &ioCompPort);
|
||
|
if (rc < 0)
|
||
|
{
|
||
|
perror("pthread_create() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* open a gsk environment */
|
||
|
rc = errno = 0;
|
||
|
printf("gsk_environment_open()\n");
|
||
|
rc = gsk_environment_open(&my_env_handle);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_environment_open() failed with rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* set the Application ID to use */
|
||
|
rc = errno = 0;
|
||
|
rc = gsk_attribute_set_buffer(my_env_handle,
|
||
|
GSK_OS400_APPLICATION_ID,
|
||
|
"MY_SERVER_APP",
|
||
|
13);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n"
|
||
|
,rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* set this side as the server */
|
||
|
rc = errno = 0;
|
||
|
rc = gsk_attribute_set_enum(my_env_handle,
|
||
|
GSK_SESSION_TYPE,
|
||
|
GSK_SERVER_SESSION);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* by default SSL_V2, SSL_V3, and TLS_V1 are enabled */
|
||
|
/* We will disable SSL_V2 for this example. */
|
||
|
rc = errno = 0;
|
||
|
rc = gsk_attribute_set_enum(my_env_handle,
|
||
|
GSK_PROTOCOL_SSLV2,
|
||
|
GSK_PROTOCOL_SSLV2_OFF);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_set_enum() failed with rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* set the cipher suite to use. By default our default list */
|
||
|
/* of ciphers is enabled. For this example we will just use one */
|
||
|
rc = errno = 0;
|
||
|
rc = gsk_attribute_set_buffer(my_env_handle,
|
||
|
GSK_V3_CIPHER_SPECS,
|
||
|
"05", /* SSL_RSA_WITH_RC4_128_SHA */
|
||
|
2);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_set_buffer() failed with rc = %d and errno = %d.\n"
|
||
|
,rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Initialize the secure environment */
|
||
|
rc = errno = 0;
|
||
|
printf("gsk_environment_init()\n");
|
||
|
rc = gsk_environment_init(my_env_handle);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_environment_init() failed with rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* initialize a socket to be used for listening */
|
||
|
printf("socket()\n");
|
||
|
lsd = socket(AF_INET, SOCK_STREAM, 0);
|
||
|
if (lsd < 0)
|
||
|
{
|
||
|
perror("socket() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* set socket so can be reused immediately */
|
||
|
rc = setsockopt(lsd, SOL_SOCKET,
|
||
|
SO_REUSEADDR,
|
||
|
(char *)&on,
|
||
|
sizeof(on));
|
||
|
if (rc < 0)
|
||
|
{
|
||
|
perror("setsockopt() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* bind to the local server address */
|
||
|
memset((char *) &address, 0, sizeof(address));
|
||
|
address.sin_family = AF_INET;
|
||
|
address.sin_port = 13333;
|
||
|
address.sin_addr.s_addr = 0;
|
||
|
printf("bind()\n");
|
||
|
rc = bind(lsd, (struct sockaddr *) &address, sizeof(address));
|
||
|
if (rc < 0)
|
||
|
{
|
||
|
perror("bind() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* enable the socket for incoming client connections */
|
||
|
printf("listen()\n");
|
||
|
listen(lsd, 5);
|
||
|
if (rc < 0)
|
||
|
{
|
||
|
perror("listen() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* accept an incoming client connection */
|
||
|
al = sizeof(address);
|
||
|
printf("accept()\n");
|
||
|
sd = accept(lsd, (struct sockaddr *) &address, &al);
|
||
|
if (sd < 0)
|
||
|
{
|
||
|
perror("accept() failed");
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* open a secure session */
|
||
|
rc = errno = 0;
|
||
|
printf("gsk_secure_soc_open()\n");
|
||
|
rc = gsk_secure_soc_open(my_env_handle, &my_session_handle);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_secure_soc_open() failed with rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
/* associate our socket with the secure session */
|
||
|
rc=errno=0;
|
||
|
rc = gsk_attribute_set_numeric_value(my_session_handle,
|
||
|
GSK_FD,
|
||
|
sd);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_set_numeric_value() failed with rc = %d ", rc);
|
||
|
printf("and errno = %d.\n", errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/*********************************************/
|
||
|
/* Issue gsk_secure_soc_startInit() to */
|
||
|
/* process SSL Handshake flow asynchronously */
|
||
|
/*********************************************/
|
||
|
/*********************************************/
|
||
|
/* initialize Qso_OverlappedIO_t structure - */
|
||
|
/* reserved fields must be hex 00's. */
|
||
|
/*********************************************/
|
||
|
memset(&ioStruct, '\0', sizeof(ioStruct));
|
||
|
|
||
|
/*********************************************/
|
||
|
/* Store the session handle in the */
|
||
|
/* Qso_OverlappedIO_t descriptorHandle field.*/
|
||
|
/* This area is used to house information */
|
||
|
/* defining the state of the client */
|
||
|
/* connection. Field descriptorHandle is */
|
||
|
/* defined as a (void *) to allow the server */
|
||
|
/* to address more extensive client */
|
||
|
/* connection state if needed. */
|
||
|
/*********************************************/
|
||
|
ioStruct.descriptorHandle = my_session_handle;
|
||
|
|
||
|
/* initiate the SSL handshake */
|
||
|
rc = errno = 0;
|
||
|
printf("gsk_secure_soc_startInit()\n");
|
||
|
rc = gsk_secure_soc_startInit(my_session_handle, ioCompPort, &ioStruct);
|
||
|
if (rc != GSK_OS400_ASYNCHRONOUS_SOC_INIT)
|
||
|
{
|
||
|
printf("gsk_secure_soc_startInit() rc = %d and errno = %d.\n",rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
printf("gsk_secure_soc_startInit got GSK_OS400_ASYNCHRONOUS_SOC_INIT\n");
|
||
|
|
||
|
/*********************************************/
|
||
|
/* This is where the server can loop back */
|
||
|
/* to accept a new connection. */
|
||
|
/*********************************************/
|
||
|
|
||
|
/*********************************************/
|
||
|
/* Wait for worker thread to finish */
|
||
|
/* processing client connection. */
|
||
|
/*********************************************/
|
||
|
rc = pthread_join(thr, &status);
|
||
|
|
||
|
|
||
|
/* check status of the worker */
|
||
|
if ( rc == 0 && (rc = __INT(status)) == Success)
|
||
|
{
|
||
|
printf("Success.\n");
|
||
|
printf("Success.\n");
|
||
|
successFlag = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
perror("pthread_join() reported failure");
|
||
|
}
|
||
|
} while(FALSE);
|
||
|
|
||
|
/* disable the SSL session */
|
||
|
if (my_session_handle != NULL)
|
||
|
gsk_secure_soc_close(&my_session_handle);
|
||
|
|
||
|
/* disable the SSL environment */
|
||
|
if (my_env_handle != NULL)
|
||
|
gsk_environment_close(&my_env_handle);
|
||
|
|
||
|
/* close the listening socket */
|
||
|
if (lsd > -1)
|
||
|
close(lsd);
|
||
|
/* close the accepted socket */
|
||
|
if (sd > -1)
|
||
|
close(sd);
|
||
|
|
||
|
/* destroy the completion port */
|
||
|
if (ioCompPort > -1)
|
||
|
QsoDestroyIOCompletionPort(ioCompPort);
|
||
|
|
||
|
if (successFlag)
|
||
|
exit(0);
|
||
|
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Function Name: workerThread */
|
||
|
/* */
|
||
|
/* Descriptive Name: Process client connection. */
|
||
|
/* */
|
||
|
/* Note: To make the sample more straight forward the main routine */
|
||
|
/* handles all of the clean up although this function can */
|
||
|
/* be made responsible for the clientfd and session_handle. */
|
||
|
/********************************************************************/
|
||
|
void *workerThread(void *arg)
|
||
|
{
|
||
|
struct timeval waitTime;
|
||
|
int ioCompPort, clientfd;
|
||
|
Qso_OverlappedIO_t ioStruct;
|
||
|
int rc, tID;
|
||
|
int amtWritten, amtRead;
|
||
|
char buff[1024];
|
||
|
gsk_handle client_session_handle;
|
||
|
pthread_t thr;
|
||
|
pthread_id_np_t t_id;
|
||
|
t_id = pthread_getthreadid_np();
|
||
|
tID = t_id.intId.lo;
|
||
|
/*********************************************/
|
||
|
/* I/O completion port is passed to this */
|
||
|
/* routine. */
|
||
|
/*********************************************/
|
||
|
ioCompPort = *(int *)arg;
|
||
|
/*********************************************/
|
||
|
/* Wait on the supplied I/O completion port */
|
||
|
/* for the SSL handshake to complete. */
|
||
|
/*********************************************/
|
||
|
waitTime.tv_sec = 500;
|
||
|
waitTime.tv_usec = 0;
|
||
|
|
||
|
sleep(4);
|
||
|
printf("QsoWaitForIOCompletion()\n");
|
||
|
rc = QsoWaitForIOCompletion(ioCompPort, &ioStruct, &waitTime);
|
||
|
if ((rc == 1) &&
|
||
|
(ioStruct.returnValue == GSK_OK) &&
|
||
|
(ioStruct.operationCompleted == GSKSECURESOCSTARTINIT))
|
||
|
/*********************************************/
|
||
|
/* SSL Handshake has completed. */
|
||
|
/*********************************************/
|
||
|
;
|
||
|
else
|
||
|
{
|
||
|
printf("QsoWaitForIOCompletion()/gsk_secure_soc_startInit() failed.\n");
|
||
|
printf("rc == %d, returnValue - %d, operationCompleted = %d\n",
|
||
|
rc, ioStruct.returnValue, ioStruct.operationCompleted);
|
||
|
perror("QsoWaitForIOCompletion()/gsk_secure_soc_startInit() failed");
|
||
|
return __VOID(Failure);
|
||
|
}
|
||
|
|
||
|
/*********************************************/
|
||
|
/* Obtain the session handle associated */
|
||
|
/* with the client connection. */
|
||
|
/*********************************************/
|
||
|
client_session_handle = ioStruct.descriptorHandle;
|
||
|
|
||
|
/* get the socket associated with the secure session */
|
||
|
rc=errno=0;
|
||
|
printf("gsk_attribute_get_numeric_value()\n");
|
||
|
rc = gsk_attribute_get_numeric_value(client_session_handle,
|
||
|
GSK_FD,
|
||
|
&clientfd);
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_attribute_get_numeric_value() rc = %d and errno = %d.\n",
|
||
|
rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
return __VOID(Failure);
|
||
|
}
|
||
|
/* memset buffer to hex zeros */
|
||
|
memset((char *) buff, 0, sizeof(buff));
|
||
|
amtRead = 0;
|
||
|
/* receive a message from the client using the secure session */
|
||
|
printf("gsk_secure_soc_read()\n");
|
||
|
rc = gsk_secure_soc_read(client_session_handle,
|
||
|
buff,
|
||
|
sizeof(buff),
|
||
|
&amtRead);
|
||
|
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_secure_soc_read() rc = %d and errno = %d.\n",rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* write results to screen */
|
||
|
printf("gsk_secure_soc_read() received %d bytes, here they are ...\n",
|
||
|
amtRead);
|
||
|
printf("%s\n",buff);
|
||
|
|
||
|
|
||
|
/* send the message to the client using the secure session */
|
||
|
amtWritten = 0;
|
||
|
printf("gsk_secure_soc_write()\n");
|
||
|
rc = gsk_secure_soc_write(client_session_handle,
|
||
|
buff,
|
||
|
amtRead,
|
||
|
&amtWritten);
|
||
|
if (amtWritten != amtRead)
|
||
|
{
|
||
|
if (rc != GSK_OK)
|
||
|
{
|
||
|
printf("gsk_secure_soc_write() rc = %d and errno = %d.\n",rc,errno);
|
||
|
printf("rc of %d means %s\n", rc, gsk_strerror(rc));
|
||
|
return __VOID(Failure);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("gsk_secure_soc_write() did not write all data.\n");
|
||
|
return __VOID(Failure);
|
||
|
}
|
||
|
}
|
||
|
/* write results to screen */
|
||
|
printf("gsk_secure_soc_write() wrote %d bytes...\n", amtWritten);
|
||
|
printf("%s\n",buff);
|
||
|
|
||
|
return __VOID(Success);
|
||
|
}
|
||
|
/* end workerThread */</pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="familylinks">
|
||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="x1ssl.htm" title="You can create secure server and clients using either the Global Secure ToolKit (GSKit) APIs or the Secure Sockets Layer (SSL_) APIs.">Examples: Establish secure connections</a></div>
|
||
|
</div>
|
||
|
<div class="relconcepts"><strong>Related concepts</strong><br />
|
||
|
<div><a href="cgskit.htm" title="Global Secure ToolKit (GSKit) is a set of programmable interfaces that allow an application to be SSL enabled.">Global Secure ToolKit (GSKit) APIs</a></div>
|
||
|
</div>
|
||
|
<div class="relref"><strong>Related reference</strong><br />
|
||
|
<div><a href="xgskserver.htm" title="This code example can be used to establish a secure server using Global Secure ToolKit (GSKit) APIs.">Example: GSKit secure server with asynchronous data receive</a></div>
|
||
|
<div><a href="xgskclient.htm" title="This code sample provides an example of a client that uses the GSKit APIs.">Example: Establish a secure client with Global Secure ToolKit (GSKit) APIs</a></div>
|
||
|
</div>
|
||
|
<div class="relinfo"><strong>Related information</strong><br />
|
||
|
<div><a href="../apis/createiocompletionport.htm">QsoCreateIOCompletionPort()</a></div>
|
||
|
<div><a href="../apis/users_14.htm">pthread_create</a></div>
|
||
|
<div><a href="../apis/waitforiocompletion.htm">QsoWaitForIoCompletionPort()</a></div>
|
||
|
<div><a href="../apis/destroyiocompletionport.htm">QsoDestroyIOCompletionPort()</a></div>
|
||
|
<div><a href="../apis/bind.htm">bind()</a></div>
|
||
|
<div><a href="../apis/socket.htm">socket()</a></div>
|
||
|
<div><a href="../apis/listen.htm">listen()</a></div>
|
||
|
<div><a href="../apis/close.htm">close()</a></div>
|
||
|
<div><a href="../apis/accept.htm">accept()</a></div>
|
||
|
<div><a href="../apis/gsk_environment_open.htm">gsk_environment_open()</a></div>
|
||
|
<div><a href="../apis/gsk_attribute_set_buffer.htm">gsk_attribute_set_buffer</a></div>
|
||
|
<div><a href="../apis/gsk_attribute_set_enum.htm">gsk_attribute_set_enum()</a></div>
|
||
|
<div><a href="../apis/gsk_environment_init.htm">gsk_environment_init()</a></div>
|
||
|
<div><a href="../apis/gsk_secure_soc_open.htm">gsk_secure_soc_open()</a></div>
|
||
|
<div><a href="../apis/gsk_attribute_set_numeric_value.htm">gsk_attribute_set_numeric_value()</a></div>
|
||
|
<div><a href="../apis/gsk_secure_soc_init.htm">gsk_secure_soc_init()</a></div>
|
||
|
<div><a href="../apis/users_25.htm">pthread_join</a></div>
|
||
|
<div><a href="../apis/gsk_secure_soc_close.htm">gsk_secure_soc_close()</a></div>
|
||
|
<div><a href="../apis/gsk_environment_close.htm">gsk_environment_close()</a></div>
|
||
|
<div><a href="../apis/gsk_attribute_get_numeric_value.htm">gsk_attribute_get_numeric_value()</a></div>
|
||
|
<div><a href="../apis/gsk_secure_soc_write.htm">gsk_secure_soc_write()</a></div>
|
||
|
<div><a href="../apis/gskstartinit.htm">gsk_secure_soc_startInit()</a></div>
|
||
|
<div><a href="../apis/gsk_secure_soc_read.htm">gsk_secure_soc_read()</a></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|