Back to index

nordugrid-arc-nox  1.1.0~rc6
PayloadGSIStream.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #ifdef WIN32 
00008 #include <arc/win32.h>
00009 #define _NO_OLDNAMES 
00010 #endif
00011 
00012 #include <arc/globusutils/GSSCredential.h>
00013 
00014 #include "PayloadGSIStream.h"
00015 
00016 namespace Arc {
00017 
00018   PayloadGSIStream::PayloadGSIStream(PayloadStreamInterface *stream,
00019                                      gss_ctx_id_t& ctx,
00020                                      Logger& logger,
00021                                      bool client)
00022     : timeout(60),
00023       stream(stream),
00024       buffer(NULL),
00025       bufferpos(0),
00026       bufferlen(0),
00027       ctx(ctx),
00028       logger(logger),
00029       client(client) {}
00030 
00031   PayloadGSIStream::~PayloadGSIStream() {
00032     if(buffer) delete[] buffer;
00033   }
00034 
00035   bool PayloadGSIStream::Get(char *buf, int& size) {
00036 
00037     if (!buffer) {
00038       gss_buffer_desc input_tok = GSS_C_EMPTY_BUFFER;
00039       gss_buffer_desc output_tok = GSS_C_EMPTY_BUFFER;
00040 
00041       int len = 5;
00042       char readbuf[5];
00043       stream->Get(&readbuf[0], len);
00044 
00045       input_tok.length = (unsigned char)readbuf[3] * 256 +
00046                          (unsigned char)readbuf[4] + 5;
00047       // While allocating buffer with malloc it will be freed using 
00048       // gssapi's gss_release_buffer()
00049       input_tok.value = malloc(input_tok.length);
00050       memcpy(input_tok.value, readbuf, 5);
00051 
00052       logger.msg(VERBOSE, "input token length: %i", input_tok.length);
00053 
00054       int pos = len;
00055       while (input_tok.length > pos) {
00056         len = input_tok.length - pos;
00057         stream->Get(&((char*)input_tok.value)[pos], len);
00058         pos += len;
00059       }
00060 
00061       OM_uint32 majstat, minstat;
00062 
00063       if (client) {
00064         majstat = gss_unwrap(&minstat,
00065                              ctx,
00066                              &input_tok,
00067                              &output_tok,
00068                              NULL,
00069                              GSS_C_QOP_DEFAULT);
00070 
00071         logger.msg(INFO, "GSS unwrap: %i/%i", majstat, minstat);
00072       }
00073       else {
00074         majstat = gss_wrap(&minstat,
00075                            ctx,
00076                            0,
00077                            GSS_C_QOP_DEFAULT,
00078                            &input_tok,
00079                            NULL,
00080                            &output_tok);
00081         logger.msg(INFO, "GSS wrap: %i/%i", majstat, minstat);
00082       }
00083       if (GSS_ERROR(majstat)) {
00084         logger.msg(ERROR, "GSS wrap/unwrap failed: %i/%i%s", majstat, minstat, GSSCredential::ErrorStr(majstat, minstat));
00085         majstat = gss_release_buffer(&minstat, &input_tok);
00086         majstat = gss_release_buffer(&minstat, &output_tok);
00087         return false;
00088       }
00089 
00090       logger.msg(VERBOSE, "Output token length: %i", output_tok.length);
00091 
00092       bufferlen = output_tok.length;
00093       bufferpos = 0;
00094       buffer = new char[bufferlen];
00095       memcpy(buffer, output_tok.value, bufferlen);
00096 
00097       majstat = gss_release_buffer(&minstat, &input_tok);
00098       majstat = gss_release_buffer(&minstat, &output_tok);
00099     }
00100 
00101     if (size > bufferlen - bufferpos)
00102       size = bufferlen - bufferpos;
00103 
00104     memcpy(buf, &buffer[bufferpos], size);
00105     bufferpos += size;
00106     if (bufferpos == bufferlen) {
00107       delete[] buffer;
00108       buffer = NULL;
00109     }
00110 
00111     return true;
00112   }
00113 
00114   bool PayloadGSIStream::Get(std::string& buf) {
00115     char tbuf[1024];
00116     int l = sizeof(tbuf);
00117     bool result = Get(tbuf, l);
00118     buf.assign(tbuf, l);
00119     return result;
00120   }
00121 
00122 } // namespace Arc