コード例 #1
0
ファイル: smdevp.c プロジェクト: allenway/onvif
/**
@fn int soap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len)
@brief Updates (signed) digest computation with message part.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains message part
@param[in] len of message part
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len)
{ int ok = 1;
  if (!data->ctx)
    return soap_set_receiver_error(soap, "soap_smd_update() failed", "No context", SOAP_SSL_ERROR);
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Update alg=%x n=%lu (%p) --\n", data->alg, (unsigned long)len, data->ctx));
  switch (data->alg & SOAP_SMD_ALGO)
  { case SOAP_SMD_HMAC:
      HMAC_Update((HMAC_CTX*)data->ctx, (const unsigned char*)buf, len);
      break;
    case SOAP_SMD_DGST:
      EVP_DigestUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
    case SOAP_SMD_SIGN:
      ok = EVP_SignUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
    case SOAP_SMD_VRFY:
      ok = EVP_VerifyUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
  }
  DBGMSG(TEST, buf, len);
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
  /* check and return */
  return soap_smd_check(soap, data, ok, "soap_smd_update() failed");
}
コード例 #2
0
/* plugin registration */
int
wininet_plugin(
    struct soap *           soap,
    struct soap_plugin *    a_pPluginData,
    void *                  a_dwRequestFlags )
{
    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: plugin registration\n", soap ));

    a_pPluginData->id        = wininet_id;
    a_pPluginData->fcopy     = wininet_copy;
    a_pPluginData->fdelete   = wininet_delete;
    a_pPluginData->data      = (void*) malloc( sizeof(struct wininet_data) );
    if ( !a_pPluginData->data )
    {
        return SOAP_EOM;
    }
    if ( !wininet_init( soap,
        (struct wininet_data *) a_pPluginData->data,
        (DWORD) (size_t) a_dwRequestFlags ) )
    {
        free( a_pPluginData->data );
        return SOAP_EOM;
    }

#ifdef SOAP_DEBUG
    if ( (soap->omode & SOAP_IO) == SOAP_IO_STORE )
    {
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: use of SOAP_IO_STORE is not recommended\n", soap ));
    }
#endif

    return SOAP_OK;
}
コード例 #3
0
/* deallocate of our private structure */
static void
wininet_delete(
    struct soap *           soap,
    struct soap_plugin *    a_pPluginData )
{
    struct wininet_data * pData =
        (struct wininet_data *) a_pPluginData->data;

    UNUSED_ARG( soap );

    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: delete private data\n", soap ));

    /* force a disconnect of any existing connection */
    pData->bDisconnect = TRUE;
    wininet_have_connection( soap, pData );

    /* close down the internet */
    if ( pData->hInternet )
    {
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: closing internet handle\n", soap));
        InternetCloseHandle( pData->hInternet );
        pData->hInternet = NULL;
    }

    /* free our data */
    wininet_free_error_message( pData );
    free( a_pPluginData->data );
}
コード例 #4
0
ファイル: soapC.c プロジェクト: millken/zhuxianB30
SOAP_FMAC3 int SOAP_FMAC4 soap_ignore_element(struct soap *soap)
{
	if (!soap_peek_element(soap))
	{	int t;
		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unexpected element '%s' in input (level=%u, %d)\n", soap->tag, soap->level, soap->body));
		if (soap->mustUnderstand && !soap->other)
			return soap->error = SOAP_MUSTUNDERSTAND;
		if (((soap->mode & SOAP_XML_STRICT) && soap->part != SOAP_IN_HEADER) || !soap_match_tag(soap, soap->tag, "SOAP-ENV:"))
		{	DBGLOG(TEST, SOAP_MESSAGE(fdebug, "REJECTING element '%s'\n", soap->tag));
			return soap->error = SOAP_TAG_MISMATCH;
		}
		if (!*soap->id || !soap_getelement(soap, &t))
		{	soap->peeked = 0;
			if (soap->fignore)
				soap->error = soap->fignore(soap, soap->tag);
			else
				soap->error = SOAP_OK;
			DBGLOG(TEST, if (!soap->error) SOAP_MESSAGE(fdebug, "IGNORING element '%s'\n", soap->tag));
			if (!soap->error && soap->body)
			{	soap->level++;
				while (!soap_ignore_element(soap))
					;
				if (soap->error == SOAP_NO_TAG)
					soap->error = soap_element_end_in(soap, NULL);
			}
		}
コード例 #5
0
/**
@fn int soap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len)
@brief Updates (signed) digest computation with message part.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains message part
@param[in] len of message part
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_update(struct soap *soap, struct soap_smd_data *data, const char *buf, size_t len)
{ int err = 1;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Update alg=%d n=%lu (%p) --\n", data->alg, (unsigned long)len, data->ctx));
  switch (data->alg & (SOAP_SMD_PASSTHRU-1))
  { case SOAP_SMD_DGST_MD5:
    case SOAP_SMD_DGST_SHA1:
      EVP_DigestUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
    case SOAP_SMD_HMAC_SHA1:
      HMAC_Update((HMAC_CTX*)data->ctx, (const unsigned char*)buf, len);
      break;
    case SOAP_SMD_SIGN_DSA_SHA1:
    case SOAP_SMD_SIGN_RSA_SHA1:
      err = EVP_SignUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
    case SOAP_SMD_VRFY_DSA_SHA1:
    case SOAP_SMD_VRFY_RSA_SHA1:
      err = EVP_VerifyUpdate((EVP_MD_CTX*)data->ctx, (const void*)buf, (unsigned int)len);
      break;
  }
  DBGMSG(TEST, buf, len);
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_update() failed");
}
コード例 #6
0
/* gsoap documentation:
    Called for all receive operations to fill buffer s of maximum length n.
    Should return the number of bytes read or 0 in case of an error, e.g. EOF.
    Built-in gSOAP function: frecv
 */
static size_t
wininet_frecv(
    struct soap *   soap,
    char *          a_pBuffer,
    size_t          a_uiBufferLen )
{
    HINTERNET   hHttpRequest = (HINTERNET) soap->socket;
    DWORD       dwBytesRead = 0;
    size_t      uiTotalBytesRead = 0;
    BOOL        bResult;

    soap->error = SOAP_OK;

    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: frecv, available buffer len = %lu\n",
        soap, a_uiBufferLen ));

    /*
        NOTE: we do not check here that our connection hasn't been
        disconnected because in HTTP/1.0 connections, it will always have been
        disconnected by now. This is because the response is checked by the
        wininet_fsend function to ensure that we didn't need any special
        authentication. At that time the connection would have been
        disconnected. This is okay however as we can still read the response
        from the request handle.
     */

    do
    {
        /* read from the connection up to our maximum amount of data */
        _ASSERTE( a_uiBufferLen <= ULONG_MAX );
        bResult = InternetReadFile(
            hHttpRequest,
            &a_pBuffer[uiTotalBytesRead],
            (DWORD) a_uiBufferLen - uiTotalBytesRead,
            &dwBytesRead );
        if ( bResult )
        {
            uiTotalBytesRead += dwBytesRead;
        }
        else
        {
            soap->error = GetLastError();
            DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                "wininet %p: frecv, error %d (%s) in InternetReadFile\n",
                soap, soap->error, wininet_error_message(soap,soap->error) ));
        }
    }
    while ( bResult && dwBytesRead && uiTotalBytesRead < a_uiBufferLen );

    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: recv, received %lu bytes\n", soap, uiTotalBytesRead ));

    return uiTotalBytesRead;
}
コード例 #7
0
ファイル: mecevp.c プロジェクト: haohd/bananaPiCam
/**
@fn int soap_mec_begin(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
@brief Initialize the mecevp engine data and begin encryption or decryption
message sequence using a private/public key or symmetric secret key.
@param soap context
@param[in,out] data mecevp engine context
@param[in] alg encryption/decryption algorithm
@param[in] pkey public/private key or NULL
@param[in,out] key secret key or encrypted ephemeral secret key set with envelope encryption, or NULL
@param[in,out] keylen secret key length
@return SOAP_OK or error code
*/
int
soap_mec_begin(struct soap *soap, struct soap_mec_data *data, int alg, SOAP_MEC_KEY_TYPE *pkey, unsigned char *key, int *keylen)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MEC Begin alg=%x\n", alg));
  /* save and set the engine's 'data' field to pass data to the callbacks */
  soap->data[1] = (void*)data;
  data->ctx = NULL;
  data->type = EVP_enc_null();
  data->pkey = NULL;
  data->key = NULL;
  data->buf = NULL;
  /* save the mode flag */
  data->mode = soap->mode;
  if (alg & SOAP_MEC_ENC)
  { /* clear the IO flags and DOM flag */
    soap->mode &= ~(SOAP_IO | SOAP_IO_LENGTH | SOAP_ENC_ZLIB | SOAP_XML_DOM);
    /* clear the XML attribute store */
    soap_clr_attr(soap);
    /* load the local XML namespaces store */
    soap_set_local_namespaces(soap);
    if (soap->mode & SOAP_XML_CANONICAL)
      soap->ns = 0; /* for in c14n, we must have all xmlns bindings available */
  }
  else
  { /* save and override the callbacks */
    data->ffilterrecv = soap->ffilterrecv;
    soap->ffilterrecv = soap_mec_filterrecv;
  }
  /* init the soap_mec engine */
  return soap_mec_init(soap, data, alg, pkey, key, keylen);
}
コード例 #8
0
static DWORD
wininet_set_timeout(
    struct soap *           soap,
    struct wininet_data *   a_pData,
    const char *            a_pszTimeout,
    DWORD                   a_dwOption,
    int                     a_nTimeout )
{
    UNUSED_ARG( soap );
    UNUSED_ARG( a_pszTimeout );

    if ( a_nTimeout > 0 )
    {
        DWORD dwTimeout = a_nTimeout * 1000;
        if ( !InternetSetOption( a_pData->hInternet,
            a_dwOption, &dwTimeout, sizeof(DWORD) ) )
        {
            DWORD dwErrorCode = GetLastError();
            DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                "wininet %p: failed to set %s timeout, error %d (%s)\n",
                soap, a_pszTimeout, dwErrorCode,
                wininet_error_message(soap,dwErrorCode) ));
            return dwErrorCode;
        }
    }
    return 0;
}
コード例 #9
0
ファイル: smdevp.c プロジェクト: abidinz/Stormee
/**
@fn int soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
@brief Finalizes (signed) digest computation and returns digest or signature.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains signature for verification (SOAP_SMD_VRFY algorithms)
@param[out] buf is populated with the digest or signature
@param[in] len points to length of signature to verify (SOAP_SMD_VRFY algorithms)
@param[out] len points to length of stored digest or signature (pass NULL if you are not interested in this value)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
{ unsigned int n = 0;
  int err = 1;
  if (buf)
  { /* finalize the digest or signature computation */
    switch (data->alg & (SOAP_SMD_PASSTHRU-1))
    { case SOAP_SMD_DGST_MD5:
      case SOAP_SMD_DGST_SHA1:
      case SOAP_SMD_DGST_SHA256:
        EVP_DigestFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_HMAC_SHA1:
        HMAC_Final((HMAC_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_SIGN_DSA_SHA1:
      case SOAP_SMD_SIGN_RSA_SHA1:
      case SOAP_SMD_SIGN_RSA_SHA256:
        err = EVP_SignFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n, (EVP_PKEY*)data->key);
        break;
      case SOAP_SMD_VRFY_DSA_SHA1:
      case SOAP_SMD_VRFY_RSA_SHA1:
        if (len)
        { n = (unsigned int)*len;
          err = EVP_VerifyFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, n, (EVP_PKEY*)data->key);
        }
        else
          err = 0;
        break;
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Final alg=%d (%p) %d bytes--\n", data->alg, data->ctx, n));
    DBGHEX(TEST, buf, n);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
    /* return length of digest or signature produced */
    if (len)
      *len = (int)n;
  }
  /* cleanup and free the HMAC or EVP_MD context */
  if ((data->alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
    HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
  else
    EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
  SOAP_FREE(soap, data->ctx);
  data->ctx = NULL;
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_final() failed");
}
コード例 #10
0
ファイル: smdevp.c プロジェクト: abidinz/Stormee
/**
@fn int soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
@brief Initiates a (signed) digest computation.
@param soap context
@param[in,out] data smdevp engine context
@param[in] alg is algorithm to use
@param[in] key is key to use or NULL for digests
@param[in] keylen is length of HMAC key (when provided)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_init(struct soap *soap, struct soap_smd_data *data, int alg, const void *key, int keylen)
{ static int done = 0;
  int err = 1;
#ifdef WITH_OPENSSL
  /* OpenSSL: make sure we have the digest algorithms, need to call just once */
  if (!done)
  { done = 1;
    OpenSSL_add_all_digests();
    OpenSSL_add_all_algorithms();
  }
#endif
  /* the algorithm to use */
  data->alg = alg;
  /* the key to use */
  data->key = key;
  /* allocate and init the OpenSSL HMAC or EVP_MD context */
  if ((alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(HMAC_CTX));
    HMAC_CTX_init((HMAC_CTX*)data->ctx);
  }
  else
  { data->ctx = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
    EVP_MD_CTX_init((EVP_MD_CTX*)data->ctx);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Init alg=%d (%p) --\n", alg, data->ctx));
  /* init the digest or signature computations */
  switch (alg & (SOAP_SMD_PASSTHRU-1))
  { case SOAP_SMD_DGST_MD5:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_md5());
      break;
    case SOAP_SMD_DGST_SHA1:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_DGST_SHA256:
      EVP_DigestInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_HMAC_SHA1:
      HMAC_Init((HMAC_CTX*)data->ctx, key, keylen, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_DSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA1:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
    case SOAP_SMD_SIGN_RSA_SHA256:
      err = EVP_SignInit((EVP_MD_CTX*)data->ctx, EVP_sha256());
      break;
    case SOAP_SMD_VRFY_DSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_dss1());
      break;
    case SOAP_SMD_VRFY_RSA_SHA1:
      err = EVP_VerifyInit((EVP_MD_CTX*)data->ctx, EVP_sha1());
      break;
  }
  /* check and return */
  return soap_smd_check(soap, data, err, "soap_smd_init() failed");
}
コード例 #11
0
/* initialize private data */
static BOOL
wininet_init(
    struct soap *           soap,
    struct wininet_data *   a_pData,
    DWORD                   a_dwRequestFlags )
{
    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: init private data\n", soap ));

    memset( a_pData, 0, sizeof(struct wininet_data) );
    a_pData->dwRequestFlags = a_dwRequestFlags;

    /* start our internet session */
    a_pData->hInternet = InternetOpenA(
        "gSOAP", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
    if ( !a_pData->hInternet )
    {
        soap->error = GetLastError();
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: init, error %d (%s) in InternetOpen\n",
            soap, soap->error, wininet_error_message(soap,soap->error) ));
        wininet_free_error_message( a_pData );
        return FALSE;
    }

    /* set the timeouts, if any of these fail the error isn't fatal */
    wininet_set_timeout( soap, a_pData, "connect",
        INTERNET_OPTION_CONNECT_TIMEOUT, soap->connect_timeout );
    wininet_set_timeout( soap, a_pData, "receive",
        INTERNET_OPTION_RECEIVE_TIMEOUT, soap->recv_timeout );
    wininet_set_timeout( soap, a_pData, "send",
        INTERNET_OPTION_SEND_TIMEOUT, soap->send_timeout );

    /* set up the callback function so we get notifications */
    InternetSetStatusCallback( a_pData->hInternet, wininet_callback );

    /* set all of our callbacks */
    soap->fopen    = wininet_connect;
    soap->fposthdr = wininet_post_header;
    soap->fsend    = wininet_fsend;
    soap->frecv    = wininet_frecv;
    soap->fclose   = wininet_disconnect;

    return TRUE;
}
コード例 #12
0
ファイル: md5evp.c プロジェクト: JammyWei/ver30
    int md5_handler(struct soap *soap, void **context, enum md5_action action, char *buf, size_t len)
    {
        EVP_MD_CTX *ctx;
        unsigned char hash[EVP_MAX_MD_SIZE];
        unsigned int size;
        switch (action)
        {
        case MD5_INIT:
#ifdef WITH_OPENSSL
            OpenSSL_add_all_digests();
#endif
            if (!*context)
            {
                *context = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
                EVP_MD_CTX_init((EVP_MD_CTX*)*context);
            }
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Init %p\n", ctx));
            EVP_DigestInit(ctx, EVP_md5());
            break;
        case MD5_UPDATE:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Update %p --\n", ctx));
            DBGMSG(TEST, buf, len);
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
            EVP_DigestUpdate(ctx, (const void*)buf, (unsigned int)len);
            break;
        case MD5_FINAL:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Final %p --\n", ctx));
            EVP_DigestFinal(ctx, (unsigned char*)hash, &size);
            memcpy(buf, hash, 16);
            break;
        case MD5_DELETE:
            ctx = (EVP_MD_CTX*)*context;
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Delete %p --\n", ctx));
            if (ctx)
            {
                EVP_MD_CTX_cleanup(ctx);
                SOAP_FREE(soap, ctx);
            }
            *context = NULL;
        }
        return SOAP_OK;
    }
コード例 #13
0
ファイル: smdevp.c プロジェクト: allenway/onvif
/**
@fn int soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
@brief Finalizes (signed) digest computation and returns digest or signature.
@param soap context
@param[in,out] data smdevp engine context
@param[in] buf contains signature for verification (SOAP_SMD_VRFY algorithms)
@param[out] buf is populated with the digest or signature
@param[in] len points to length of signature to verify (SOAP_SMD_VRFY algorithms)
@param[out] len points to length of stored digest or signature (pass NULL if you are not interested in this value)
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_smd_final(struct soap *soap, struct soap_smd_data *data, char *buf, int *len)
{ unsigned int n = 0;
  int ok = 1;
  if (!data->ctx)
    return soap_set_receiver_error(soap, "soap_smd_final() failed", "No context", SOAP_SSL_ERROR);
  if (buf)
  { /* finalize the digest or signature computation */
    switch (data->alg & SOAP_SMD_ALGO)
    { case SOAP_SMD_HMAC:
        HMAC_Final((HMAC_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_DGST:
        EVP_DigestFinal_ex((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n);
        break;
      case SOAP_SMD_SIGN:
        ok = EVP_SignFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, &n, (EVP_PKEY*)data->key);
        break;
      case SOAP_SMD_VRFY:
        if (len)
        { n = (unsigned int)*len;
          ok = EVP_VerifyFinal((EVP_MD_CTX*)data->ctx, (unsigned char*)buf, n, (EVP_PKEY*)data->key);
        }
        else
          ok = 0;
        break;
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Final alg=%x (%p) %d bytes--\n", data->alg, data->ctx, n));
    DBGHEX(TEST, buf, n);
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
    /* pass back length of digest or signature produced */
    if (len)
      *len = (int)n;
  }
  /* cleanup */
  if ((data->alg & SOAP_SMD_ALGO) == SOAP_SMD_HMAC)
    HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
  else
    EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
  SOAP_FREE(soap, data->ctx);
  data->ctx = NULL;
  /* check and return */
  return soap_smd_check(soap, data, ok, "soap_smd_final() failed");
}
コード例 #14
0
ファイル: httppost.c プロジェクト: DemofiloVizuete/gSOAP
static http_handler_t http_lookup_handler(struct soap *soap, const char *type, struct http_post_data *data)
{ struct http_post_handlers *p;
  for (p = data->handlers; p && p->type; p++)
  { if (!soap_tag_cmp(type, p->type))
    { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Found HTTP POST plugin handler for '%s'\n", type));
      return p->handler;
    }
  }
  return NULL;
}
コード例 #15
0
ファイル: mecevp.c プロジェクト: haohd/bananaPiCam
/**
@fn int soap_mec_final(struct soap *soap, struct soap_mec_data *data, const char **s, size_t *n)
@brief Ends mecevp engine state: encrypt/decrypt remainder from buffers.
@param soap context
@param[in,out] data mecevp engine context
@param[out] s afterwards points to converted remaining data in streaming mode, or entire converted data in buffer mode (SOAP_MEC_STORE option)
@param[out] n afterwards size of remaining data
@return SOAP_OK or SOAP_SSL_ERROR
*/
int
soap_mec_final(struct soap *soap, struct soap_mec_data *data, const char **s, size_t *n)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_final()\n"));
  *n = 0;
  if (!data->ctx)
    return SOAP_OK;
  if (soap_mec_upd(soap, data, s, n, 1))
    return soap->error;
  return SOAP_OK;
}
コード例 #16
0
/*
    check to ensure that our connection hasn't been disconnected
    and disconnect remaining handles if necessary.
 */
static BOOL
wininet_have_connection(
    struct soap *           soap,
    struct wininet_data *   a_pData )
{
    /* close the http request if we don't have a connection */
    BOOL bCloseRequest = a_pData->bDisconnect || !a_pData->hConnection;
    if ( bCloseRequest && soap->socket != SOAP_INVALID_SOCKET )
    {
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: closing request\n", soap));

        InternetCloseHandle( (HINTERNET) soap->socket );
        soap->socket = SOAP_INVALID_SOCKET;
    }

    /* close the connection if we don't have a request */
    if ( soap->socket == SOAP_INVALID_SOCKET && a_pData->hConnection )
    {
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: closing connection\n", soap));

        InternetCloseHandle( a_pData->hConnection );
        a_pData->hConnection = NULL;
    }
    a_pData->bDisconnect = FALSE;

    /* clean up the send details if we don't have a request */
    if ( soap->socket == SOAP_INVALID_SOCKET )
    {
        if ( a_pData->pBuffer )
        {
            free( a_pData->pBuffer );
            a_pData->pBuffer = 0;
        }
        a_pData->uiBufferLen = 0;
        a_pData->uiBufferLenMax = INVALID_BUFFER_LENGTH;
    }

    /* we now either still have both request and connection, or neither */
    return (a_pData->hConnection != NULL);
}
コード例 #17
0
void
wininet_set_rse_callback(
    struct soap *           soap,
    wininet_rse_callback    a_pRsecallback)
{
    struct wininet_data * pData = (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );

    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: resolve_send_error callback = '%p'\n", soap, a_pRsecallback ));

    pData->pRseCallback = a_pRsecallback;
}
コード例 #18
0
ファイル: mecevp.c プロジェクト: haohd/bananaPiCam
/**
@fn int soap_mec_end(struct soap *soap, struct soap_mec_data *data)
@brief Ends encryption or decryption of a sequence of message parts that began
with soap_mec_begin.
@param soap context
@param[in,out] data mecevp engine context
@return SOAP_OK or error code
*/
int
soap_mec_end(struct soap *soap, struct soap_mec_data *data)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MEC End alg=%x\n", data->alg));
  /* reset callbacks */
  if (soap->ffiltersend == soap_mec_filtersend)
    soap->ffiltersend = data->ffiltersend;
  if (soap->ffilterrecv == soap_mec_filterrecv)
    soap->ffilterrecv = data->ffilterrecv;
  /* restore the mode flag */
  soap->mode = data->mode;
  /* cleanup and reset mecevp engine */
  soap_mec_cleanup(soap, data);
  soap->data[1] = NULL;
  return SOAP_OK;
}
コード例 #19
0
ファイル: mecevp.c プロジェクト: haohd/bananaPiCam
/**
@fn void soap_mec_cleanup(struct soap *soap, struct soap_mec_data *data)
@brief Clean up mecevp engine and deallocate cipher context and buffers.
@param soap context
@param[in,out] data mecevp engine context
@return SOAP_OK or SOAP_SSL_ERROR
*/
void
soap_mec_cleanup(struct soap *soap, struct soap_mec_data *data)
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "soap_mec_cleanup()\n"));
  if (data->ctx)
  { EVP_CIPHER_CTX_cleanup(data->ctx);
    SOAP_FREE(soap, data->ctx);
    data->ctx = NULL;
  }
  if (data->buf)
  { SOAP_FREE(soap, data->buf);
    data->buf = NULL;
  }
  if (data->rest)
  { SOAP_FREE(soap, data->rest);
    data->rest = NULL;
  }
}
コード例 #20
0
/* gsoap documentation:
    Called by client proxy multiple times, to close a socket connection before
    a new socket connection is established and at the end of communications
    when the SOAP_IO_KEEPALIVE flag is not set and soap.keep_alive = 0
    (indicating that the other party supports keep alive). Should return
    SOAP_OK, or a gSOAP error code. Built-in gSOAP function: tcp_disconnect
 */
static int
wininet_disconnect(
    struct soap *   soap )
{
    struct wininet_data * pData =
        (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );

    soap->error = SOAP_OK;

    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "wininet %p: disconnect\n", soap ));

    /* force a disconnect by setting the disconnect flag to TRUE */
    pData->bDisconnect = TRUE;
    wininet_have_connection( soap, pData );

    return SOAP_OK;
}
コード例 #21
0
ファイル: dom.c プロジェクト: Wellsen/OnvifOperation
SOAP_FMAC2
soap_in_xsd__anyAttribute(struct soap *soap, const char *tag, struct soap_dom_attribute *node, const char *type)
{ struct soap_attribute *tp;
  struct soap_dom_attribute *tmp = node;
  struct soap_dom_attribute *att = node;
  (void)tag; (void)type;
  for (tp = soap->attributes; tp; tp = tp->next)
  { if (tp->visible)
    { if (!att)
      { att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
        if (tmp)
	  tmp->next = att;
	else
	  node = att;
        tmp = att;
      }
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s'\n", tp->name));
      if (!att)
      { soap->error = SOAP_EOM;
        return NULL;
      }
      att->next = NULL;
      att->nstr = soap_current_namespace(soap, tp->name);
      if ((soap->mode & SOAP_DOM_ASIS) || !strncmp(tp->name, "xml", 3))
        att->name = soap_strdup(soap, tp->name);
      else
      { char *s = strchr(tp->name, ':');
        if (s)
          att->name = soap_strdup(soap, s+1);
	else
          att->name = soap_strdup(soap, tp->name);
      }
      if (tp->visible == 2)
        att->data = soap_strdup(soap, tp->value);
      else
        att->data = NULL;
      att->wide = NULL;
      att->soap = soap;
      att = NULL;
    }
  }
  return node;
}
コード例 #22
0
/**
@fn int soap_smd_check(struct soap *soap, struct soap_smd_data *data, int err, const char *msg)
@brief Check result of init/update/final smdevp engine operations.
@param soap context
@param[in,out] data smdevp engine context
@param[in] err EVP error value
@param[in] msg error message
@return SOAP_OK or SOAP_SSL_ERROR
*/
static int
soap_smd_check(struct soap *soap, struct soap_smd_data *data, int err, const char *msg)
{ if (err <= 0)
  { unsigned long r;
    while ((r = ERR_get_error()))
    { ERR_error_string_n(r, soap->msgbuf, sizeof(soap->msgbuf));
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- SMD Error (%d) %s: %s\n", err, msg, soap->msgbuf));
    }
    if (data->ctx)
    { if ((data->alg & (SOAP_SMD_PASSTHRU-1)) == SOAP_SMD_HMAC_SHA1)
        HMAC_CTX_cleanup((HMAC_CTX*)data->ctx);
      else
        EVP_MD_CTX_cleanup((EVP_MD_CTX*)data->ctx);
      SOAP_FREE(soap, data->ctx);
      data->ctx = NULL;
    }
    return soap_set_receiver_error(soap, msg, soap->msgbuf, SOAP_SSL_ERROR);
  }
  return SOAP_OK;
}
コード例 #23
0
ファイル: mecevp.c プロジェクト: haohd/bananaPiCam
/**
@fn int soap_mec_stop(struct soap *soap)
@brief Stops encryption or decryption of current message. Use after
soap_mec_start.
@param soap context
@return SOAP_OK or error code
*/
int
soap_mec_stop(struct soap *soap)
{ struct soap_mec_data *data;
  int err = SOAP_OK;
  const char *s = NULL;
  size_t n = 0;
  data = (struct soap_mec_data*)soap->data[1];
  if (!data)
    return soap->error = SOAP_USER_ERROR;
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MEC Stop alg=%x\n", data->alg));
  err = soap_mec_final(soap, data, &s, &n);
  if (data->alg & SOAP_MEC_ENC)
  { /* reset callbacks */
    if (soap->ffiltersend == soap_mec_filtersend)
      soap->ffiltersend = data->ffiltersend;
    /* send remaining cipher data */
    if (!err && n)
      if (soap_send_raw(soap, s, n))
        return soap->error;
  }
  return err;
}
コード例 #24
0
ファイル: md5evp.c プロジェクト: haohd/bananaPiCam
int md5_handler(struct soap *soap, void **context, enum md5_action action, char *buf, size_t len)
{ EVP_MD_CTX *ctx;
  unsigned char hash[EVP_MAX_MD_SIZE];
  unsigned int size;
  switch (action)
  { case MD5_INIT:
      soap_ssl_init();
      if (!*context)
      { *context = (void*)SOAP_MALLOC(soap, sizeof(EVP_MD_CTX));
        EVP_MD_CTX_init((EVP_MD_CTX*)*context);
      }
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Init %p\n", ctx));
      EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
      break;
    case MD5_UPDATE:
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Update %p (%lu) --\n", ctx, (unsigned long)len));
      DBGMSG(TEST, buf, len);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
      EVP_DigestUpdate(ctx, (const void*)buf, (unsigned int)len);
      break;
    case MD5_FINAL:
      ctx = (EVP_MD_CTX*)*context;
      EVP_DigestFinal_ex(ctx, (unsigned char*)hash, &size);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Final %p --\n", ctx));
      DBGHEX(TEST, hash, size);
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n--"));
      soap_memcpy((void*)buf, 16, (const void*)hash, 16);
      break;
    case MD5_DELETE:
      ctx = (EVP_MD_CTX*)*context;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "-- MD5 Delete %p --\n", ctx));
      if (ctx)
      { EVP_MD_CTX_cleanup(ctx);
        SOAP_FREE(soap, ctx);
      }
      *context = NULL;
  }
  return SOAP_OK;
}
コード例 #25
0
/* gsoap documentation:
    Called by http_post and http_response (through the callbacks). Emits HTTP
    key: val header entries. Should return SOAP_OK, or a gSOAP error code.
    Built-in gSOAP function: http_post_header.
 */
static int
wininet_post_header(
    struct soap *   soap,
    const char *    a_pszKey,
    const char *    a_pszValue )
{
    HINTERNET hHttpRequest = (HINTERNET) soap->socket;
    char      szHeader[4096];
    int       nLen;
    BOOL      bResult = FALSE;
    struct wininet_data * pData =
        (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );

    soap->error = SOAP_OK;

    /* ensure that our connection hasn't been disconnected */
    if ( !wininet_have_connection( soap, pData ) )
    {
        return SOAP_EOF;
    }

    /* if this is the initial POST header then we initialize our send buffer */
    if ( a_pszKey && !a_pszValue )
    {
        _ASSERTE( !pData->pBuffer );
        pData->uiBufferLenMax = INVALID_BUFFER_LENGTH;
        pData->uiBufferLen    = 0;

        /* if we are using chunk output then we start with a chunk size */
        pData->bIsChunkSize = ( (soap->omode & SOAP_IO) == SOAP_IO_CHUNK );
    }
    else if ( a_pszValue )
    {
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: post_header, adding '%s: %s'\n",
            soap, a_pszKey, a_pszValue ));

        /* determine the maximum length of this message so that we can
           correctly determine when we have completed the send */
        if ( !strcmp( a_pszKey, "Content-Length" ) )
        {
            _ASSERTE( pData->uiBufferLenMax == INVALID_BUFFER_LENGTH );
            pData->uiBufferLenMax = strtoul( a_pszValue, NULL, 10 );
        }

        nLen = _snprintf(
            szHeader, 4096, "%s: %s\r\n", a_pszKey, a_pszValue );
        if ( nLen < 0 )
        {
            return SOAP_EOM;
        }
        bResult = HttpAddRequestHeadersA( hHttpRequest, szHeader, nLen,
            HTTP_ADDREQ_FLAG_ADD_IF_NEW );
#ifdef SOAP_DEBUG
        /*
            we don't return an error if this fails because it isn't
            (or shouldn't be) critical.
         */
        if ( !bResult )
        {
            DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                "wininet %p: post_header, error %d (%s) in HttpAddRequestHeaders\n",
                soap, soap->error, wininet_error_message(soap,GetLastError()) ));
        }
#endif
    }
    return SOAP_OK;
}
コード例 #26
0
int soap_fresponse(struct soap *soap, int status, size_t count)
{
  //int err;
  //std::cout << "DEBUG soap_fresponse" << std::endl;

  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Origin", "*")))
  //    return err;
  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, CONNECT")))
  //    return err;
  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Headers", "X-Requested-With, Content-Type")))
  //    return err;
  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Credentials", "true")))
  //    return err;
   
  //int ret = old_freponse(soap, soap_error_code, count);

  //return ret;
  std::cout << "debug status=" << status << std::endl;
  status = 200;

register int err;
#ifdef WMW_RPM_IO
  if (soap->rpmreqid)
    httpOutputEnable(soap->rpmreqid);
#endif
  if (strlen(soap->http_version) > 4)
    return soap->error = SOAP_EOM;
  if (!status || status == SOAP_HTML || status == SOAP_FILE)
  { const char *s;
    if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
      s = "200 OK";
    else
      s = "202 ACCEPTED";
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s));
#ifdef WMW_RPM_IO
    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
#else
    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application (socket) or CGI (stdin/out)? */
#endif
    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
        return err;
    }
    else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI header */
      return err;
  }
  else if (status >= 200 && status < 600)
  { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status));
    if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
      return err;
#ifndef WITH_LEAN 
    if (status == 401)
    { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", (soap->authrealm && strlen(soap->authrealm) < sizeof(soap->tmpbuf) - 14) ? soap->authrealm : "gSOAP Web Service");
      if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf)))
        return err;
    }
    else if ((status >= 301 && status <= 303) || status == 307)
    { if ((err = soap->fposthdr(soap, "Location", soap->endpoint)))
        return err;
    }
#endif
  }
else
  { const char *s = *soap_faultcode(soap);
    //std::cout << "DEBUG status=" << status << std::endl;
    //std::cout << "DEBUG SOAP_GET_METHOD=" << SOAP_GET_METHOD << std::endl;
    //std::cout << "DEBUG SOAP_HTTP_METHOD=" << SOAP_HTTP_METHOD << std::endl;
    if (status >= SOAP_GET_METHOD && status <= SOAP_HTTP_METHOD)
      s = "405 Method Not Allowed";
    else if (soap->version == 2 && (!s || !strcmp(s, "SOAP-ENV:Sender")))
      s = "400 Bad Request";
    else
      s = "500 Internal Server Error";
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status));
#ifdef WMW_RPM_IO
    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
#else
    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
#endif
    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
        return err;
    }
    else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */
      return err;
  }
  if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7"))
   || (err = soap_puthttphdr(soap, status, count)))
    return err;
#ifdef WITH_COOKIES
  if (soap_putsetcookies(soap))
    return soap->error;
#endif

  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Origin", "*")))
  //    return err;

  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Credentials", "true")))
  //    return err;


  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Headers", "origin,x-requested-with,access-control-request-headers,content-type,access-control-request-method,accept")))
  //    return err;

  //if ((err = soap->fposthdr(soap, "Access-Control-Allow-Methods", "POST,HEAD,GET,PUT,DELETE,OPTIONS")))
  //    return err;

  //if ((err = soap->fposthdr(soap, "Allow", "HEAD,GET,PUT,DELETE,OPTIONS")))
  //    return err;

  return soap->fposthdr(soap, NULL, NULL);


}
コード例 #27
0
SOAP_FMAC2
soap_in_xsd__anyType(struct soap *soap, const char *tag, struct soap_dom_element *node, const char *type)
{ register struct soap_attribute *tp;
  register struct soap_dom_attribute **att;
  if (soap_peek_element(soap))
  { if (soap->error != SOAP_NO_TAG)
      return NULL;
    if (!node)
    { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
      { soap->error = SOAP_EOM;
        return NULL;
      }
    }
    soap_default_xsd__anyType(soap, node);
    if (!(node->data = soap_string_in(soap, 1, -1, -1)) || !*node->data)
      return NULL;
    soap->error = SOAP_OK;
    return node;
  }
  if (!node)
  { if (!(node = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element))))
    { soap->error = SOAP_EOM;
      return NULL;
    }
  }
  soap_default_xsd__anyType(soap, node);
  node->nstr = soap_current_namespace(soap, soap->tag);
  if ((soap->mode & SOAP_DOM_ASIS))
    node->name = soap_strdup(soap, soap->tag);
  else
  { char *s = strchr(soap->tag, ':');
    if (s)
      node->name = soap_strdup(soap, s+1);
    else
      node->name = soap_strdup(soap, soap->tag);
  }
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' parsed in namespace '%s'\n", node->name, node->nstr?node->nstr:""));
  if ((soap->mode & SOAP_DOM_NODE) || (!(soap->mode & SOAP_DOM_TREE) && *soap->id))
  { if ((node->node = soap_getelement(soap, &node->type)))
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node contains type %d from xsi:type\n", node->type));
      return node;
    }
    if (soap->error == SOAP_TAG_MISMATCH)
      soap->error = SOAP_OK;
    else
      return NULL;
  }
  att = &node->atts;
  for (tp = soap->attributes; tp; tp = tp->next)
  { if (tp->visible)
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node attribute='%s' parsed\n", tp->name));
      *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
      if (!*att)
      { soap->error = SOAP_EOM;
        return NULL;
      }
      (*att)->next = NULL;
      (*att)->nstr = soap_current_namespace(soap, tp->name);
      if ((soap->mode & SOAP_DOM_ASIS) || !strncmp(tp->name, "xml", 3))
        (*att)->name = soap_strdup(soap, tp->name);
      else
      { char *s = strchr(tp->name, ':');
        if (s)
          (*att)->name = soap_strdup(soap, s+1);
        else
          (*att)->name = soap_strdup(soap, tp->name);
      }
      if (tp->visible == 2)
        (*att)->data = soap_strdup(soap, tp->value);
      else
        (*att)->data = NULL;
      (*att)->wide = NULL;
      (*att)->soap = soap;
      att = &(*att)->next;
      tp->visible = 0;
    }
  }
  soap_element_begin_in(soap, NULL, 1, NULL);
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' pulled\n", node->name));
  if (soap->body)
  { if (!soap_peek_element(soap))
    { struct soap_dom_element **elt;
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has subelements\n", node->name));
      elt = &node->elts;
      for (;;)
      { if (!(*elt = soap_in_xsd__anyType(soap, NULL, NULL, NULL)))
        { if (soap->error != SOAP_NO_TAG)
            return NULL;
          soap->error = SOAP_OK;
          break;
        }
	(*elt)->prnt = node;
        elt = &(*elt)->next;
      }
    }
    else if (soap->error == SOAP_NO_TAG)
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' has cdata\n", node->name));
      if ((soap->mode & SOAP_C_UTFSTRING) || (soap->mode & SOAP_C_MBSTRING))
      { if (!(node->data = soap_string_in(soap, 1, -1, -1)))
          return NULL;
      }
      else if (!(node->wide = soap_wstring_in(soap, 1, -1, -1)))
        return NULL;
    }
    else
      return NULL;
    if (soap_element_end_in(soap, node->name))
      return NULL;
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", node->name));
  }
  return node;
}
コード例 #28
0
SOAP_FMAC1
int
SOAP_FMAC2
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
{ if (node)
  { const char *prefix; /* namespace prefix, if namespace is present */
    size_t colon;
    if (!(soap->mode & SOAP_DOM_ASIS))
    { const struct soap_dom_attribute *att;
      for (att = node->atts; att; att = att->next)
      { if (att->name && att->data && !strncmp(att->name, "xmlns:", 6))
	{ if (soap_push_namespace(soap, att->name + 6, att->data) == NULL)
            return soap->error;
	}
        else if (att->name && att->data && !strcmp(att->name, "xmlns"))
	{ if (soap_push_namespace(soap, "", att->data) == NULL)
            return soap->error;
	}
      }
    }
    if (node->name)
      tag = node->name;
    else if (!tag)
      tag = "-";
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' output at level %u\n", tag, soap->level));
    if ((prefix = strchr(tag, ':')))
    { colon = prefix - tag + 1;
      if (colon > sizeof(soap->tag))
        colon = sizeof(soap->tag);
    }
    else
      colon = 0;
    prefix = NULL;
    if (node->nstr && *node->nstr && !(soap->mode & SOAP_DOM_ASIS))
    { if (colon)
      { strncpy(soap->tag, tag, colon - 1);
        soap->tag[colon - 1] = '\0';
        if ((prefix = soap_push_ns_prefix(soap, soap->tag, node->nstr, 1)) == NULL
         || out_element(soap, node, prefix, tag + colon))
          return soap->error;
      }
      else
      { if ((prefix = soap_lookup_ns_prefix(soap, node->nstr)))
        { if (out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
        else
	{ if ((prefix = soap_push_ns_prefix(soap, NULL, node->nstr, 1)) == NULL
           || out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
      }
    }
    else
    { colon = 0;
      if (out_element(soap, node, NULL, tag))
        return soap->error;
    }
    if (!node->type || !node->node)
    { struct soap_dom_attribute *att;
      struct soap_dom_element *elt;
      for (att = node->atts; att; att = att->next)
      { if (att->name)
        { if (att->nstr && !(soap->mode & SOAP_DOM_ASIS))
          { const char *p;
            if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
	    { if (out_attribute(soap, prefix, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if ((p = soap_lookup_ns_prefix(soap, att->nstr)))
	    { if (out_attribute(soap, p, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if (!strncmp(att->name, "xml", 3))
	    { if (out_attribute(soap, NULL, att->name, att->data, att->wide, 0))
                return soap->error;
	    }
	    else if ((p = soap_push_ns_prefix(soap, NULL, att->nstr, 0)) == NULL
	          || out_attribute(soap, p, att->name, att->data, att->wide, 0))
              return soap->error;
          }
	  else if (soap_attribute(soap, att->name, att->wide ? soap_wchar2s(soap, att->wide) : att->data))
            return soap->error;
        }
      }
      if ((soap->mode & SOAP_DOM_ASIS) && !node->data && !node->wide && !node->elts && !node->tail)
      { if (*tag != '-' && soap_element_start_end_out(soap, tag))
          return soap->error;
      }
      else
      { if (*tag != '-' && soap_element_start_end_out(soap, NULL))
          return soap->error;
        if (node->data)
        { if (soap_string_out(soap, node->data, 0))
            return soap->error;
        }
        else if (node->wide)
        { if (soap_wstring_out(soap, node->wide, 0))
            return soap->error;
        }
        for (elt = node->elts; elt; elt = elt->next)
        { if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
            return soap->error;
        }
        if (node->tail && soap_send(soap, node->tail))
          return soap->error;
        if (!prefix || !*prefix)
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
          if (soap_element_end_out(soap, tag + colon))
            return soap->error;
        }
        else
        { char *s;
          if (strlen(prefix) + strlen(tag + colon) < sizeof(soap->msgbuf))
	    s = soap->msgbuf;
	  else
	  { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(tag + colon) + 2);
            if (!s)
              return soap->error = SOAP_EOM;
	  }
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag));
	  sprintf(s, "%s:%s", prefix, tag + colon);
	  soap_pop_namespace(soap);
          if (soap_element_end_out(soap, s))
            return soap->error;
          if (s != soap->msgbuf)
	    SOAP_FREE(soap, s);
        }
      }
    }
  }
  return SOAP_OK;
}
コード例 #29
0
/* gsoap documentation:
    Called for all send operations to emit contents of s of length n.
    Should return SOAP_OK, or a gSOAP error code. Built-in gSOAP
    function: fsend

   Notes:
    I do a heap of buffering here because we need the entire message available
    in a single buffer in order to iterate through the sending loop. I had
    hoped that the SOAP_IO_STORE flag would have worked to do the same, however
    this still breaks the messages up into blocks. Although there were a number
    of ways this could've been implemented, this works and supports all of the
    possible SOAP_IO flags, even though the entire message is still buffered
    the same as if SOAP_IO_STORE was used.
*/
static int
wininet_fsend(
    struct soap *   soap,
    const char *    a_pBuffer,
    size_t          a_uiBufferLen )
{
    HINTERNET   hHttpRequest = (HINTERNET) soap->socket;
    BOOL        bResult;
    BOOL        bRetryPost;
    DWORD       dwStatusCode;
    DWORD       dwStatusCodeLen;
    int         nResult = SOAP_OK;
    struct wininet_data * pData =
        (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );

    soap->error = SOAP_OK;

    DBGLOG(TEST, SOAP_MESSAGE(fdebug,
        "wininet %p: fsend, data len = %lu bytes\n", soap, a_uiBufferLen ));

    /* allow the request to be sent with a NULL buffer */
    if (a_uiBufferLen == 0)
    {
        pData->uiBufferLenMax = 0;
    }

    /* ensure that our connection hasn't been disconnected */
    if ( !wininet_have_connection( soap, pData ) )
    {
        return SOAP_EOF;
    }

    /* initialize on our first time through. pData->pBuffer will always be
       non-null if this is not the first call. */
    if ( !pData->pBuffer )
    {
        /*
            If we are using chunked sending, then we don't know how big the
            buffer will need to be. So we start with a 0 length buffer and
            grow it later to ensure that it is always large enough.

                uiBufferLenMax = length of the allocated memory
                uiBufferLen    = length of the data in the buffer
         */
        if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK )
        {
            /* we make the initial allocation large enough for this chunksize
               buffer, plus the next chunk of actual data, and a few extra
               bytes for the final "0" chunksize block. */
            size_t uiChunkSize = strtoul( a_pBuffer, NULL, 16 );
            pData->uiBufferLenMax = uiChunkSize + a_uiBufferLen + 16;
        }
        else if ( a_uiBufferLen == pData->uiBufferLenMax )
        {
            /*
                If the currently supplied buffer from gsoap holds the entire
                message then we just use their buffer and avoid any memory
                allocation. This will only be true when (1) we are not using
                chunked send (so uiBufferLenMax has been previously set to
                the Content-Length header length), and (2) gsoap is sending
                the entire message at one time.
             */
            pData->pBuffer     = (char *) a_pBuffer;
            pData->uiBufferLen = a_uiBufferLen;
        }

        _ASSERTE( pData->uiBufferLenMax != INVALID_BUFFER_LENGTH );
    }

    /*
        If we can't use the gsoap buffer, then we need to allocate our own
        buffer for the entire message. This is because authentication may
        require the entire message to be sent multiple times. Since this send
        is only a part of the message, we need to buffer until we have the
        entire message.
    */
    if ( pData->pBuffer != a_pBuffer )
    {
        /*
            We already have a buffer pointer, this means that it isn't the
            first time we have been called. We have allocated a buffer and
            are current filling it.

            If we don't have enough room in the our buffer to add this new
            data, then we need to reallocate. This case will only occur with
            chunked sends.
         */
        size_t uiNewBufferLen = pData->uiBufferLen + a_uiBufferLen;
        if ( !pData->pBuffer || uiNewBufferLen > pData->uiBufferLenMax )
        {
            while ( uiNewBufferLen > pData->uiBufferLenMax )
            {
                pData->uiBufferLenMax = pData->uiBufferLenMax * 2;
            }
            pData->pBuffer = (char *) realloc( pData->pBuffer, pData->uiBufferLenMax );
            if ( !pData->pBuffer )
            {
                return SOAP_EOM;
            }
        }
        memcpy( pData->pBuffer + pData->uiBufferLen,
            a_pBuffer, a_uiBufferLen );
        pData->uiBufferLen = uiNewBufferLen;

        /* if we are doing chunked transfers, and this is a chunk size block,
           and it is "0", then this is the last block in the transfer and we
           can set the maximum size now to continue to the actual send. */
        if ( (soap->mode & SOAP_IO) == SOAP_IO_CHUNK
             && pData->bIsChunkSize
             && a_pBuffer[2] == '0' && !isalnum(a_pBuffer[3]) )
        {
            pData->uiBufferLenMax = pData->uiBufferLen;
        }
    }

    /* if we haven't got the entire length of the message yet, then
       we return to gsoap and let it continue */
    if ( pData->uiBufferLen < pData->uiBufferLenMax )
    {
        /* toggle our chunk size marker if we are chunking */
        pData->bIsChunkSize =
            ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
            && !pData->bIsChunkSize;
        return SOAP_OK;
    }
    _ASSERTE( pData->uiBufferLen == pData->uiBufferLenMax );

    /* we've now got the entire message, now we can enter our sending loop */
    bRetryPost = TRUE;
    while ( bRetryPost )
    {
        bRetryPost = FALSE;

        bResult = HttpSendRequestA(
            hHttpRequest, NULL, 0, pData->pBuffer, (DWORD)pData->uiBufferLen );
        if ( !bResult )
        {
            soap->error = GetLastError();
            DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                "wininet %p: fsend, error %d (%s) in HttpSendRequest\n",
                soap, soap->error, wininet_error_message(soap,soap->error) ));

            /* see if we can handle this error, see the MSDN documentation
               for InternetErrorDlg for details */
            switch ( soap->error )
            {
            case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
            case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
            case ERROR_INTERNET_INCORRECT_PASSWORD:
            case ERROR_INTERNET_INVALID_CA:
            case ERROR_INTERNET_POST_IS_NON_SECURE:
            case ERROR_INTERNET_SEC_CERT_CN_INVALID:
            case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
            case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
                {
                wininet_rseReturn errorResolved = rseDisplayDlg;
                if (pData->pRseCallback)
                {
                    errorResolved = pData->pRseCallback(hHttpRequest, soap->error);
                }
                if (errorResolved == rseDisplayDlg)
                {
                    errorResolved = (wininet_rseReturn)
                        wininet_resolve_send_error( hHttpRequest, soap->error );
                    if ( errorResolved == rseTrue )
                    {
                        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                            "wininet %p: fsend, error %d has been resolved\n",
                            soap, soap->error ));
                        bRetryPost = TRUE;

                        /*
                            we would have been disconnected by the error. Since we
                            are going to try again, we will automatically be
                            reconnected. Therefore we want to disregard any
                            previous disconnection messages.
                        */
                        pData->bDisconnect = FALSE;
                        continue;
                    }
                }
                }
                break;
            }

            /* if the error wasn't handled then we exit */
            nResult = SOAP_HTTP_ERROR;
            break;
        }

        /* get the status code from the response to determine if we need
           to authorize */
        dwStatusCodeLen = sizeof(dwStatusCode);
        bResult = HttpQueryInfo(
            hHttpRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
            &dwStatusCode, &dwStatusCodeLen, NULL);
        if ( !bResult )
        {
            soap->error = GetLastError();
            DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                "wininet %p: fsend, error %d (%s) in HttpQueryInfo\n",
                soap, soap->error, wininet_error_message(soap,soap->error) ));
            nResult = SOAP_HTTP_ERROR;
            break;
        }

        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: fsend, HTTP status code = %lu\n",
            soap, dwStatusCode));

        /*
            if we need authentication, then request the user for the
            appropriate data. Their reply is saved into the request so
            that we can use it later.
         */
        switch ( dwStatusCode )
        {
        case HTTP_STATUS_DENIED:
        case HTTP_STATUS_PROXY_AUTH_REQ:
            {
            wininet_rseReturn errorResolved = rseDisplayDlg;
                DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                    "wininet %p: fsend, user authenication required\n",
                    soap ));
            if (pData->pRseCallback)
            {
                errorResolved = pData->pRseCallback(hHttpRequest, dwStatusCode);
            }
            if (errorResolved == rseDisplayDlg)
            {
                errorResolved = (wininet_rseReturn)
                    wininet_resolve_send_error( hHttpRequest, ERROR_INTERNET_INCORRECT_PASSWORD );
            }
            if ( errorResolved == rseTrue )
            {
                DBGLOG(TEST, SOAP_MESSAGE(fdebug,
                    "wininet %p: fsend, authentication has been provided\n",
                    soap ));

                /*
                    we may have been disconnected by the error. Since we
                    are going to try again, we will automatically be
                    reconnected. Therefore we want to disregard any previous
                    disconnection messages.
                    */
                pData->bDisconnect = FALSE;
                bRetryPost = TRUE;
                continue;
            }
            }
            break;
        }
    }

    /* if we have an allocated buffer then we can deallocate it now */
    if ( pData->pBuffer != a_pBuffer )
    {
        free( pData->pBuffer );
    }

    pData->pBuffer     = 0;
    pData->uiBufferLen = 0;
    pData->uiBufferLenMax = INVALID_BUFFER_LENGTH;

    return nResult;
}
コード例 #30
0
/* this is mostly for debug tracing */
void CALLBACK
wininet_callback(
    HINTERNET   hInternet,
    DWORD_PTR   dwContext,
    DWORD       dwInternetStatus,
    LPVOID      lpvStatusInformation,
    DWORD       dwStatusInformationLength )
{
    struct soap * soap = (struct soap *) dwContext;

    UNUSED_ARG( hInternet );
    UNUSED_ARG( lpvStatusInformation );
    UNUSED_ARG( dwStatusInformationLength );

    switch ( dwInternetStatus )
    {
    case INTERNET_STATUS_RESOLVING_NAME:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_RESOLVING_NAME\n", soap ));
        break;
    case INTERNET_STATUS_NAME_RESOLVED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_NAME_RESOLVED\n", soap ));
        break;
    case INTERNET_STATUS_CONNECTING_TO_SERVER:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_CONNECTING_TO_SERVER\n", soap));
        break;
    case INTERNET_STATUS_CONNECTED_TO_SERVER:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_CONNECTED_TO_SERVER\n", soap));
        break;
    case INTERNET_STATUS_SENDING_REQUEST:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_SENDING_REQUEST\n", soap));
        break;
    case INTERNET_STATUS_REQUEST_SENT:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_REQUEST_SENT, bytes sent = %lu\n",
            soap, *(DWORD *)lpvStatusInformation ));
        break;
    case INTERNET_STATUS_RECEIVING_RESPONSE:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_RECEIVING_RESPONSE\n", soap));
        break;
    case INTERNET_STATUS_RESPONSE_RECEIVED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_RESPONSE_RECEIVED, bytes received = %lu\n",
            soap, *(DWORD *)lpvStatusInformation ));
        break;
    case INTERNET_STATUS_CTL_RESPONSE_RECEIVED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_CTL_RESPONSE_RECEIVED\n", soap));
        break;
    case INTERNET_STATUS_PREFETCH:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_PREFETCH\n", soap));
        break;
    case INTERNET_STATUS_CLOSING_CONNECTION:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_CLOSING_CONNECTION\n", soap));
        break;
    case INTERNET_STATUS_CONNECTION_CLOSED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_CONNECTION_CLOSED\n", soap));
        {
            /* the connection has been closed, so we close the handle here */
            struct wininet_data * pData =
                (struct wininet_data *) soap_lookup_plugin( soap, wininet_id );
            if ( pData->hConnection )
            {
                /*
                    we only mark this for disconnection otherwise we get
                    errors when reading the data from the handle. In every
                    function that we use the connection we will check first to
                    see if it has been disconnected.
                 */
                pData->bDisconnect = TRUE;
            }
        }
        break;
    case INTERNET_STATUS_HANDLE_CREATED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_HANDLE_CREATED\n", soap));
        break;
    case INTERNET_STATUS_HANDLE_CLOSING:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_HANDLE_CLOSING\n", soap));
        break;
#ifdef INTERNET_STATUS_DETECTING_PROXY
    case INTERNET_STATUS_DETECTING_PROXY:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_DETECTING_PROXY\n", soap));
        break;
#endif
    case INTERNET_STATUS_REQUEST_COMPLETE:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_REQUEST_COMPLETE\n", soap));
        break;
    case INTERNET_STATUS_REDIRECT:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_REDIRECT, new url = %s\n",
            soap, (char*) lpvStatusInformation ));
        break;
    case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_INTERMEDIATE_RESPONSE\n", soap));
        break;
#ifdef INTERNET_STATUS_USER_INPUT_REQUIRED
    case INTERNET_STATUS_USER_INPUT_REQUIRED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_USER_INPUT_REQUIRED\n", soap));
        break;
#endif
    case INTERNET_STATUS_STATE_CHANGE:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_STATE_CHANGE\n", soap));
        break;
#ifdef INTERNET_STATUS_COOKIE_SENT
    case INTERNET_STATUS_COOKIE_SENT:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_COOKIE_SENT\n", soap));
        break;
#endif
#ifdef INTERNET_STATUS_COOKIE_RECEIVED
    case INTERNET_STATUS_COOKIE_RECEIVED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_COOKIE_RECEIVED\n", soap));
        break;
#endif
#ifdef INTERNET_STATUS_PRIVACY_IMPACTED
    case INTERNET_STATUS_PRIVACY_IMPACTED:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_PRIVACY_IMPACTED\n", soap));
        break;
#endif
#ifdef INTERNET_STATUS_P3P_HEADER
    case INTERNET_STATUS_P3P_HEADER:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_P3P_HEADER\n", soap));
        break;
#endif
#ifdef INTERNET_STATUS_P3P_POLICYREF
    case INTERNET_STATUS_P3P_POLICYREF:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_P3P_POLICYREF\n", soap));
        break;
#endif
#ifdef INTERNET_STATUS_COOKIE_HISTORY
    case INTERNET_STATUS_COOKIE_HISTORY:
        DBGLOG(TEST, SOAP_MESSAGE(fdebug,
            "wininet %p: INTERNET_STATUS_COOKIE_HISTORY\n", soap));
        break;
#endif
    }
}