This is the “guts” of the program. Calls server_establish_context() to accept the context, receives the data, unwraps it, verifies it, then generates a MIC to send back to the client. Finally, it deletes the context.
/*
* Function: sign_server
*
* Purpose: Performs the "sign" service.
*
* Arguments:
*
* s (r) a TCP socket on which a connection has been
* accept()ed
* service_name (r) the ASCII name of the GSS-API service to
* establish a context as
*
* Returns: -1 on error
*
* Effects:
*
* sign_server establishes a context, and performs a single sign request.
*
* A sign request is a single GSS-API wrapped token. The token is
* unwrapped and a signature block, produced with gss_get_mic, is returned
* to the sender. The context is the destroyed and the connection
* closed.
*
* If any error occurs, -1 is returned.
*/
int sign_server(s, server_creds)
int s;
gss_cred_id_t server_creds;
{
gss_buffer_desc client_name, xmit_buf, msg_buf;
gss_ctx_id_t context;
OM_uint32 maj_stat, min_stat;
int i, conf_state, ret_flags;
char *cp;
/* Establish a context with the client */
if (server_establish_context(s, server_creds, &context,
&client_name, &ret_flags) < 0)
return(-1);
printf("Accepted connection: \"%.*s\"\n",
(int) client_name.length, (char *) client_name.value);
(void) gss_release_buffer(&min_stat, &client_name);
for (i=0; i < 3; i++)
if (test_import_export_context(&context))
return -1;
/* Receive the wrapped message token */
if (recv_token(s, &xmit_buf) < 0)
return(-1);
if (verbose && log) {
fprintf(log, "Wrapped message token:\n");
print_token(&xmit_buf);
}
maj_stat = gss_unwrap(&min_stat, context, &xmit_buf, &msg_buf,
&conf_state, (gss_qop_t *) NULL);
if (maj_stat != GSS_S_COMPLETE) {
display_status("unwrapping message", maj_stat, min_stat);
return(-1);
} else if (! conf_state) {
fprintf(stderr, "Warning! Message not encrypted.\n");
}
(void) gss_release_buffer(&min_stat, &xmit_buf);
fprintf(log, "Received message: ");
cp = msg_buf.value;
if (isprint(cp[0]) && isprint(cp[1]))
fprintf(log, "\"%s\"\n", cp);
else {
printf("\n");
print_token(&msg_buf);
}
/* Produce a signature block for the message */
maj_stat = gss_get_mic(&min_stat, context, GSS_C_QOP_DEFAULT,
&msg_buf, &xmit_buf);
if (maj_stat != GSS_S_COMPLETE) {
display_status("signing message", maj_stat, min_stat);
return(-1);
}
(void) gss_release_buffer(&min_stat, &msg_buf);
/* Send the signature block to the client */
if (send_token(s, &xmit_buf) < 0)
return(-1);
(void) gss_release_buffer(&min_stat, &xmit_buf);
/* Delete context */
maj_stat = gss_delete_sec_context(&min_stat, &context, NULL);
if (maj_stat != GSS_S_COMPLETE) {
display_status("deleting context", maj_stat, min_stat);
return(-1);
}
fflush(log);
return(0);
}