Пример #1
0
const char *soap_xsd__duration2s(struct soap *soap, LONG64 a)
{ LONG64 d;
  int k, h, m, s, f;
  if (a < 0)
  { soap_strcpy(soap->tmpbuf, sizeof(soap->tmpbuf), "-P");
    k = 2;
    a = -a;
  }
  else
  { soap_strcpy(soap->tmpbuf, sizeof(soap->tmpbuf), "P");
    k = 1;
  }
  f = a % 1000;
  a /= 1000;
  s = a % 60;
  a /= 60;
  m = a % 60;
  a /= 60;
  h = a % 24;
  d = a / 24;
  if (d)
    (SOAP_SNPRINTF(soap->tmpbuf + k, sizeof(soap->tmpbuf) - k, 21), SOAP_LONG_FORMAT "D", d);
  if (h || m || s || f)
  { if (d)
      k = strlen(soap->tmpbuf);
    if (f)
      (SOAP_SNPRINTF(soap->tmpbuf + k, sizeof(soap->tmpbuf) - k, 14), "T%02dH%02dM%02d.%03dS", h, m, s, f);
    else
      (SOAP_SNPRINTF(soap->tmpbuf + k, sizeof(soap->tmpbuf) - k, 10), "T%02dH%02dM%02dS", h, m, s);
  }
  else if (!d)
    soap_strcpy(soap->tmpbuf + k, sizeof(soap->tmpbuf) - k, "T0S");
  return soap->tmpbuf;
}
Пример #2
0
const char *soap_decimal2s(struct soap *soap, long double n)
{
#if !defined(WITH_C_LOCALE) || !defined(HAVE_SPRINTF_L)
  char *s;
#endif
  if (soap_isnan(n))
    return "NaN";
  if (soap_ispinfd(n))
    return "INF";
  if (soap_isninfd(n))
    return "-INF";
#if defined(WITH_C_LOCALE) && defined(HAVE_SPRINTF_L)
# ifdef WIN32
  _sprintf_s_l(soap->tmpbuf, _countof(soap->tmpbuf), "%.*Lg", SOAP_LOCALE(soap), LDBL_DIG, n);
# else
  sprintf_l(soap->tmpbuf, SOAP_LOCALE(soap), "%.*Lg", LDBL_DIG, n);
# endif
#else
  (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), LDBL_DIG + 8), "%.*Lg", LDBL_DIG, n);
  s = strchr(soap->tmpbuf, ',');	/* convert decimal comma to DP */
  if (s)
    *s = '.';
#endif
  return soap->tmpbuf;
}
Пример #3
0
const char *soap_xsd__dateTime2s(struct soap *soap, const struct timeval a)
{ size_t n;
  soap_dateTime2s(soap, a.tv_sec); /* assuming result is in tmpbuf! */
  n = strlen(soap->tmpbuf);
  if (soap->tmpbuf[n-1] == 'Z')
    n--;
  (SOAP_SNPRINTF(soap->tmpbuf + n, sizeof(soap->tmpbuf) - n, 10), ".%.6dZ", a.tv_usec);
  return soap->tmpbuf;
}
Пример #4
0
static int 
out_element(struct soap *soap, const struct soap_dom_element *node, const char *prefix, const char *name)
{ if (node->head && soap_send(soap, node->head))
    return soap->error;
  if (node->type && node->node)
  { if (prefix && *prefix)
    { size_t l = strlen(prefix) + strlen(name);
      char *s = (char*)SOAP_MALLOC(soap, l + 2);
      if (!s)
        return soap->error = SOAP_EOM;
      (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, name);
      soap_putelement(soap, node->node, s, 0, node->type);
      SOAP_FREE(soap, s);
    }
    else
      return soap_putelement(soap, node->node, name, 0, node->type);
  }
  else if (prefix && *prefix)
  { size_t l = strlen(prefix) + strlen(name);
    char *s;
    if (l + 1 < sizeof(soap->msgbuf))
      s = soap->msgbuf;
    else
    { s = (char*)SOAP_MALLOC(soap, l + 2);
      if (!s)
        return soap->error = SOAP_EOM;
    }
    (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, name);
    soap_element(soap, s, 0, NULL); /* element() */
    if (s != soap->msgbuf)
      SOAP_FREE(soap, s);
  }
  else if (*name != '-')
  { soap_mode m = soap->mode;
    if ((soap->mode & SOAP_DOM_ASIS))
      soap->mode &= ~SOAP_XML_INDENT;
    soap_element(soap, name, 0, NULL); /* element() */
    soap->mode = m;
  }
  return soap->error;
}
Пример #5
0
int calcService::pow(double a, double b, double *result)
{
	printf("pow ... \n");

	*result = ::pow(a, b);
	if (soap_errno == EDOM)	/* soap_errno is like errno, but compatible with Win32 */
	{ char *s = (char*)soap_malloc(this, 1024);
		(SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't take power of %f to %f</error>", a, b);
		return soap_senderfault("Power function domain error", s);
	}
	return SOAP_OK;
}
Пример #6
0
int calcService::div(double a, double b, double *result)
{
	printf("div ... \n");

	if (b)
		*result = a / b;
	else
	{ char *s = (char*)soap_malloc(this, 1024);
		(SOAP_SNPRINTF(s, 1024, 100), "<error xmlns=\"http://tempuri.org/\">Can't divide %f by %f</error>", a, b);
		return soap_senderfault("Division by zero", s);
	}
	return SOAP_OK;
} 
Пример #7
0
static const char *
soap_push_ns_prefix(struct soap *soap, const char *id, const char *ns, int flag)
{ struct soap_nlist *np;
  if (!id)
  { struct Namespace *n;
    for (n = soap->local_namespaces; n && n->id; n++)
    { if (n->ns && !strcmp(n->ns, ns))
      { id = n->id;
        break;
      }
    }
    if (!id)
    { (SOAP_SNPRINTF(soap->tag, sizeof(soap->tag), sizeof(SOAP_DOMID_FORMAT) + 20), SOAP_DOMID_FORMAT, soap->idnum++);
      id = soap->tag;
    }
  }
  /* fix advance generation of xmlns, when element (level) is not output yet */
  if (flag)
    soap->level++;
  np = soap_push_namespace(soap, id, ns);
  if (flag)
    soap->level--;
  if (!np)
    return NULL;
  if (!np->ns)
  { np->ns = soap->local_namespaces[np->index].out;
    if (!np->ns)
      np->ns = soap->local_namespaces[np->index].ns;
  }
  np->index = 0; /* for C14N utilized mark */
  if (*np->id)
  { (SOAP_SNPRINTF(soap->msgbuf, sizeof(soap->msgbuf), strlen(np->id) + 6), "xmlns:%s", np->id);
    out_attribute(soap, NULL, soap->msgbuf, ns, NULL, flag);
  }
  else
    out_attribute(soap, NULL, "xmlns", ns, NULL, flag);
  return np->id;
}
Пример #8
0
const char * soap_xsd__integer2s(struct soap *soap, __int128_t a)
{
  char *s = soap->tmpbuf;
  /* INT128_MIN = -170141183460469231731687303715884105728 */
  __int128_t min128 = -(((__int128_t)UINT64_MAX + 1) * 0x7FFFFFFFFFFFFFFFULL + 0xFFFFFFFFFFFFFFFFULL) - 1;
  if (a < 0)
  {
    if (a == min128)
      return "-170141183460469231731687303715884105728";
    *s++ = '-';
    a = -a;
  }
  if (a > UINT64_MAX)
  {
    __int128_t l = a / 10000000000000000000ULL; /* leading digits */
    uint64_t   t = a % 10000000000000000000ULL; /* trailing 19 digits */
    if (l > UINT64_MAX)
    {
      uint64_t ll = l / 10000000000000000000ULL;
      uint64_t tl = l % 10000000000000000000ULL;
      (SOAP_SNPRINTF(s, (s - soap->tmpbuf) + sizeof(soap->tmpbuf), 20), "%" PRIu64, ll);
      s += strlen(s);
      (SOAP_SNPRINTF(s, (s - soap->tmpbuf) + sizeof(soap->tmpbuf), 20), "%0.19" PRIu64, tl);
    }
    else
    {
      (SOAP_SNPRINTF(s, (s - soap->tmpbuf) + sizeof(soap->tmpbuf), 20), "%" PRIu64, (uint64_t)l);
    }
    s += strlen(s);
    (SOAP_SNPRINTF(s, (s - soap->tmpbuf) + sizeof(soap->tmpbuf), 20), "%0.19" PRIu64, t);
  }
  else
  {
    (SOAP_SNPRINTF(s, sizeof(soap->tmpbuf) - 1, 20), "%" PRIu64, (uint64_t)a);
  }
  return soap->tmpbuf;
}
Пример #9
0
static int
out_attribute(struct soap *soap, const char *prefix, const char *name, const char *data, const wchar_t *wide, int flag)
{ char *s;
  const char *t;
  size_t l;
  int err;
  if (wide)
    data = soap_wchar2s(soap, wide);
  if (!prefix || !*prefix)
  { if (wide)
      return soap_set_attr(soap, name, data, 2);
    if (flag)
      return soap_set_attr(soap, name, data, 1);
    return soap_attribute(soap, name, data);
  }
  t = strchr(name, ':');
  if (t)
    t++;
  else
    t = name;
  l = strlen(prefix) + strlen(t);
  if (l + 1 < sizeof(soap->msgbuf))
    s = soap->msgbuf;
  else
  { s = (char*)SOAP_MALLOC(soap, l + 2);
    if (!s)
      return soap->error = SOAP_EOM;
  } 
  (SOAP_SNPRINTF(s, l + 2, l + 1), "%s:%s", prefix, t);
  if (wide)
    err = soap_set_attr(soap, s, data, 2);
  else if (flag)
    err = soap_set_attr(soap, s, data, 1);
  else
    err = soap_attribute(soap, s, data);
  if (s != soap->msgbuf)
    SOAP_FREE(soap, s);
  return err;
}
Пример #10
0
static int jsstrout(struct soap *soap, const char *s)
{ int c;
  char buf[8];
  if (soap_send_raw(soap, "\"", 1))
    return soap->error;
  while ((c = *s++))
  { switch (c)
    { case '"':
      case '\\':
        buf[0] = '\\';
        buf[1]  = c;
        if (soap_send_raw(soap, buf, 2))
          return soap->error;
        break;
      default:
        if (c < 32 && c > 0)
        { switch (c)
          { case '\b':
              c = 'b';
              break;
            case '\f':
              c = 'f';
              break;
            case '\n':
              c = 'n';
              break;
            case '\r':
              c = 'r';
              break;
            case '\t':
              c = 't';
              break;
          }
          if (c > 32)
          { buf[0] = '\\';
            buf[1]  = c;
            if (soap_send_raw(soap, buf, 2))
              return soap->error;
          }
          else
	  { (SOAP_SNPRINTF(buf, sizeof(buf), 7), "\\u%4x", c);
            if (soap_send_raw(soap, buf, 6))
              return soap->error;
          }
        }
        else if ((c & 0x80) && (soap->omode & SOAP_ENC_LATIN) && (soap->omode & SOAP_C_UTFSTRING)) // utf8 to ISO 8859-1
        { if (c < 0xE0 && (c & 0x1F) <= 0x03)
            buf[0] = ((c & 0x1F) << 6) | (*s++ & 0x3F);
          else
            buf[0] = '?';
          if (soap_send_raw(soap, buf, 1))
            return soap->error;
        }
        else if ((c & 0x80) && !(soap->omode & SOAP_ENC_LATIN) && !(soap->omode & SOAP_C_UTFSTRING)) // ISO 8859-1 to utf8
        { buf[0] = (char)(0xC0 | ((c >> 6) & 0x1F));
          buf[1] = (char)(0x80 | (c & 0x3F));
          if (soap_send_raw(soap, buf, 2))
            return soap->error;
        }
        else
        { buf[0] = c;
          if (soap_send_raw(soap, buf, 1))
            return soap->error;
        }
    }
Пример #11
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)
{ (void)id; (void)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)
      { soap_strncpy(soap->tag, sizeof(soap->tag), tag, colon - 1);
        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)
      { soap_mode m = soap->mode;
        soap->mode &= ~SOAP_XML_INDENT;
	if (*tag != '-' && soap_element_start_end_out(soap, tag))
          return soap->error;
        soap->mode = m;
      }
      else
      { if (*tag != '-' && soap_element_start_end_out(soap, NULL))
          return soap->error;
        if (*tag != '-' && node->data)
        { if (soap_string_out(soap, node->data, 0))
            return soap->error;
        }
        else if (node->data)
        { if (soap_send(soap, node->data))
            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, NULL, 0, elt, NULL))
            return soap->error;
        }
        if (node->tail && soap_send(soap, node->tail))
          return soap->error;
        if (!prefix || !*prefix)
        { soap_mode m = soap->mode;
	  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
          if ((soap->mode & SOAP_DOM_ASIS))
	    soap->mode &= ~SOAP_XML_INDENT;
          if (soap_element_end_out(soap, tag + colon))
            return soap->error;
	  soap->mode = m;
        }
        else
        { char *s;
	  size_t l = strlen(prefix) + strlen(tag + colon);
          if (l + 1 < sizeof(soap->msgbuf))
	    s = soap->msgbuf;
	  else
	  { s = (char*)SOAP_MALLOC(soap, l + 2);
            if (!s)
              return soap->error = SOAP_EOM;
	  }
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag));
	  (SOAP_SNPRINTF(s, l + 2, l + 1), "%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;
}
Пример #12
0
static int http_da_post_header(struct soap *soap, const char *key, const char *val)
{
  struct http_da_data *data = (struct http_da_data*)soap_lookup_plugin(soap, http_da_id);

  if (!data)
    return SOAP_PLUGIN_ERROR;

  /* client's HTTP Authorization request */
  if (key && (!strcmp(key, "Authorization") || !strcmp(key, "Proxy-Authorization")))
  {
    char HA1hex[65], entityHAhex[65], response[65], responseHA[32];
    char cnonce[HTTP_DA_NONCELEN];
    char ncount[9];
    const char *qop, *method;
    const char *userid = (*key == 'A' ? soap->userid : soap->proxy_userid);
    const char *passwd = (*key == 'A' ? soap->passwd : soap->proxy_passwd);
    size_t smd_len = 16;

    if (data->alg && !soap_tag_cmp(data->alg, "SHA-256*"))
      smd_len = 32;

    if (soap_smd_final(soap, &data->smd_data, data->digest, NULL))
      return soap->error;

    if (!userid || !passwd || !soap->authrealm || !data->nonce)
    {
#ifdef SOAP_DEBUG
      fprintf(stderr, "Debug message: authentication header construction failed, missing some of the authentication data!\n");
#endif
      return SOAP_OK;
    }

    http_da_calc_nonce(soap, cnonce);

    if (http_da_calc_HA1(soap, &data->smd_data, data->alg, userid, soap->authrealm, passwd, data->nonce, cnonce, HA1hex))
      return soap->error;

    if (soap->status != SOAP_GET && soap->status != SOAP_CONNECT && data->qop && !soap_tag_cmp(data->qop, "*auth-int*"))
    {
      qop = "auth-int";
      (void)soap_s2hex(soap, (unsigned char*)data->digest, entityHAhex, smd_len);
    }
    else if (data->qop)
      qop = "auth";
    else
      qop = NULL;

    if (soap->status == SOAP_GET)
      method = "GET";
    else if (soap->status == SOAP_CONNECT)
      method = "CONNECT";
    else
      method = "POST";

    (SOAP_SNPRINTF(ncount, sizeof(ncount), 8), "%8.8lx", data->nc++);

    if (http_da_calc_response(soap, &data->smd_data, data->alg, HA1hex, data->nonce, ncount, cnonce, qop, method, soap->path, entityHAhex, response, responseHA))
      return soap->error;

    (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(userid) + strlen(data->nonce) + strlen(soap->path) + strlen(ncount) + strlen(cnonce) + strlen(response) + 75), "Digest algorithm=%s, realm=\"%s\", username=\"%s\", nonce=\"%s\", uri=\"%s\", nc=%s, cnonce=\"%s\", response=\"%s\"", data->alg ? data->alg : "MD5", soap->authrealm, userid, data->nonce, soap->path, ncount, cnonce, response);

    if (data->opaque)
    { size_t l = strlen(soap->tmpbuf);
      (SOAP_SNPRINTF(soap->tmpbuf + l, sizeof(soap->tmpbuf) - l, strlen(data->opaque) + 11), ", opaque=\"%s\"", data->opaque);
    }

    if (qop)
    { size_t l = strlen(soap->tmpbuf);
      (SOAP_SNPRINTF(soap->tmpbuf + l, sizeof(soap->tmpbuf) - l, strlen(qop) + 8), ", qop=\"%s\"", qop);
    }

    return data->fposthdr(soap, key, soap->tmpbuf);
  }

  /* server's HTTP Authorization challenge/response */
  if (key && (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")))
  {
    static const char *algos[] = { "MD5", "MD5-sess", "SHA-256", "SHA-256-sess", "SHA-512-256", "SHA-512-256-sess" };
    const char *alg = algos[data->option];
    char nonce[HTTP_DA_NONCELEN];
    char opaque[HTTP_DA_OPAQUELEN];

    http_da_calc_nonce(soap, nonce);
    http_da_calc_opaque(soap, opaque);

    http_da_session_start(soap->authrealm, nonce, opaque);

    if (data->option > 0)
    {
      (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(nonce) + strlen(opaque) + 59), "Digest algorithm=%s, realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", alg, soap->authrealm, nonce, opaque);
      if (data->fposthdr(soap, key, soap->tmpbuf))
        return soap->error;
    }
    (SOAP_SNPRINTF(soap->tmpbuf, sizeof(soap->tmpbuf), strlen(soap->authrealm) + strlen(nonce) + strlen(opaque) + 59), "Digest algorithm=MD5, realm=\"%s\", qop=\"auth,auth-int\", nonce=\"%s\", opaque=\"%s\"", soap->authrealm, nonce, opaque);
    return data->fposthdr(soap, key, soap->tmpbuf);
  }

  return data->fposthdr(soap, key, val);
}
Пример #13
0
static void http_da_calc_opaque(struct soap *soap, char opaque[HTTP_DA_OPAQUELEN])
{
  (void)soap;
  (SOAP_SNPRINTF(opaque, HTTP_DA_OPAQUELEN, 8), "%8.8x", soap_random);
}
Пример #14
0
static void http_da_calc_nonce(struct soap *soap, char nonce[HTTP_DA_NONCELEN])
{
  static short count = 0xCA53;
  (void)soap;
  (SOAP_SNPRINTF(nonce, HTTP_DA_NONCELEN, 20), "%8.8x%4.4hx%8.8x", (int)time(NULL), count++, soap_random);
}
Пример #15
0
int main(int argc, char **argv)
{ struct soap *soap;
  int server = 0;
  int text = 0;
  int port = 0;
  FILE *fd;
  double result;
  char *user;
  int runs = 1;
  /* create context */
  soap = soap_new();
  /* register wsse plugin */
  soap_register_plugin_arg(soap, soap_wsse, (void*)token_handler);
  /* options */
  if (argc >= 2)
  { if (strchr(argv[1], 'c'))
      soap_set_omode(soap, SOAP_IO_CHUNK);
    else if (strchr(argv[1], 'y'))
      soap_set_omode(soap, SOAP_IO_STORE);
    if (strchr(argv[1], 'i'))
      soap_set_omode(soap, SOAP_XML_INDENT);
    if (strchr(argv[1], 'n'))
      soap_set_omode(soap, SOAP_XML_CANONICAL);
    if (strchr(argv[1], 'a'))
      aes = 1;
    if (strchr(argv[1], 'o'))
      oaep = 1;
    if (strchr(argv[1], 'd'))
      sym = 1;
    if (strchr(argv[1], 'e'))
      enc = 1;
    if (strchr(argv[1], 'f'))
      addenc = 1;
    /* if (strchr(argv[1], 'F'))
      addenca = 1; */
    if (strchr(argv[1], 'h'))
      hmac = 1;
    if (strchr(argv[1], 'k'))
      nokey = 1;
    if (strchr(argv[1], 's'))
      server = 1;
    if (strchr(argv[1], 't'))
      text = 1;
    if (strchr(argv[1], 'g'))
      addsig = 1;
    if (strchr(argv[1], 'b'))
      nobody = 1;
    if (strchr(argv[1], 'x'))
      nohttp = 1;
    if (strchr(argv[1], 'z'))
      soap_set_mode(soap, SOAP_ENC_ZLIB);
    if (isdigit(argv[1][strlen(argv[1])-1]))
    { runs = argv[1][strlen(argv[1])-1] - '0';
      soap_set_mode(soap, SOAP_IO_KEEPALIVE);
    }
  }
  /* soap->actor = "..."; */ /* set only when required */
  user = getenv("USER");
  if (!user)
    user = "******";
  /* read RSA private key for signing */
  if ((fd = fopen("server.pem", "r")))
  { rsa_privk = PEM_read_PrivateKey(fd, NULL, NULL, (void*)"password");
    fclose(fd);
    if (!rsa_privk)
    { fprintf(stderr, "Could not read private RSA key from server.pem\n");
      exit(1);
    }
  }
  else
    fprintf(stderr, "Could not read server.pem\n");
  /* read certificate (more efficient is to keep certificate in memory)
     to obtain public key for encryption and signature verification */
  if ((fd = fopen("servercert.pem", "r")))
  { cert = PEM_read_X509(fd, NULL, NULL, NULL);
    fclose(fd);
    if (!cert)
    { fprintf(stderr, "Could not read certificate from servercert.pem\n");
      exit(1);
    }
  }
  else
    fprintf(stderr, "Could not read server.pem\n");
  rsa_pubk = X509_get_pubkey(cert);
  if (!rsa_pubk)
  { fprintf(stderr, "Could not get public key from certificate\n");
    exit(1);
  }
  /* port argument */
  if (argc >= 3)
    port = atoi(argv[2]);
  /* need cacert to verify certificates with CA (cacert.pem for testing and
     cacerts.pem for production, which contains the trusted CA certificates) */
  soap->cafile = "cacert.pem";
  /* server or client/ */
  if (server)
  { if (port)
    { /* stand-alone server serving messages over port */
      if (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))
      { soap_print_fault(soap, stderr);
        exit(1);
      }
      printf("Server started at port %d\n", port);
      while (soap_valid_socket(soap_accept(soap)))
      { if (hmac)
          soap_wsse_verify_auto(soap, SOAP_SMD_HMAC_SHA1, hmac_key, sizeof(hmac_key));
        else if (nokey)
          soap_wsse_verify_auto(soap, SOAP_SMD_VRFY_RSA_SHA1, rsa_pubk, 0);
        else
          soap_wsse_verify_auto(soap, SOAP_SMD_NONE, NULL, 0);
        if (sym)
        { if (aes)
            soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_AES256_CBC, aes_key, sizeof(aes_key));
	  else
	    soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_DES_CBC, des_key, sizeof(des_key));
        }
        else if (enc)
          soap_wsse_decrypt_auto(soap, SOAP_MEC_ENV_DEC_DES_CBC, rsa_privk, 0);
        if (soap_serve(soap))
        { soap_wsse_delete_Security(soap);
          soap_print_fault(soap, stderr);
          soap_print_fault_location(soap, stderr);
        }
	soap_destroy(soap);
	soap_end(soap);
      }
      soap_print_fault(soap, stderr);
      exit(1);
    }
    else
    { /* CGI-style server serving messages over stdin/out */
      if (hmac)
        soap_wsse_verify_auto(soap, SOAP_SMD_HMAC_SHA1, hmac_key, sizeof(hmac_key));
      else if (nokey)
        soap_wsse_verify_auto(soap, SOAP_SMD_VRFY_RSA_SHA1, rsa_pubk, 0);
      else
        soap_wsse_verify_auto(soap, SOAP_SMD_NONE, NULL, 0);
      if (sym)
      { if (aes)
          soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_AES256_CBC, aes_key, sizeof(aes_key));
	else
	  soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_DES_CBC, des_key, sizeof(des_key));
      }
      else if (enc)
        soap_wsse_decrypt_auto(soap, SOAP_MEC_ENV_DEC_DES_CBC, rsa_privk, 0);
      if (soap_serve(soap))
      { soap_wsse_delete_Security(soap);
        soap_print_fault(soap, stderr);
        soap_print_fault_location(soap, stderr);
      }
      soap_destroy(soap);
      soap_end(soap);
    }
  }
  else /* client */
  { int run;
    char endpoint[80];
    /* ns1:test data */
    struct ns1__add a;
    struct ns1__sub b;
    a.a = 123;
    a.b = 456;
    b.a = 789;
    b.b = -99999;
    /* client sending messages to stdout or over port */
    if (port)
      (SOAP_SNPRINTF(endpoint, sizeof(endpoint), 37), "http://localhost:%d", port);
    else if (nohttp)
      soap_strcpy(endpoint, sizeof(endpoint), "");
    else
      soap_strcpy(endpoint, sizeof(endpoint), "http://");

    for (run = 0; run < runs; run++)
    {

    /* message lifetime of 60 seconds */
    soap_wsse_add_Timestamp(soap, "Time", 60);
    /* add user name with text or digest password */
    if (text)
      soap_wsse_add_UsernameTokenText(soap, "User", user, "userPass");
    else
      soap_wsse_add_UsernameTokenDigest(soap, "User", user, "userPass");
    if (sym)
    { if (aes)
      { /* symmetric encryption with AES */
        soap_wsse_add_EncryptedData_KeyInfo_KeyName(soap, "My AES Key");
        if (soap_wsse_encrypt_body(soap, SOAP_MEC_ENC_AES256_CBC, aes_key, sizeof(aes_key)))
          soap_print_fault(soap, stderr);
        soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_AES256_CBC, aes_key, sizeof(aes_key));
      }
      else
      { /* symmetric encryption with DES */
        soap_wsse_add_EncryptedData_KeyInfo_KeyName(soap, "My DES Key");
        if (soap_wsse_encrypt_body(soap, SOAP_MEC_ENC_DES_CBC, des_key, sizeof(des_key)))
          soap_print_fault(soap, stderr);
        soap_wsse_decrypt_auto(soap, SOAP_MEC_DEC_DES_CBC, des_key, sizeof(des_key));
      }
    }
    else if (addenc || addenca)
    { /* RSA encryption of the <ns1:add> element */
      const char *SubjectKeyId = NULL; /* set to non-NULL to use SubjectKeyIdentifier in Header rather than a full cert key */
      /* MUST set wsu:Id of the elements to encrypt */
      if (addenc) /* encrypt element <ns1:add> */
      { soap_wsse_set_wsu_id(soap, "ns1:add");
        if (soap_wsse_add_EncryptedKey_encrypt_only(soap, SOAP_MEC_ENV_ENC_DES_CBC, "Cert", cert, SubjectKeyId, NULL, NULL, "ns1:add"))
          soap_print_fault(soap, stderr);
      }
      else /* encrypt element <a> */
      { soap_wsse_set_wsu_id(soap, "a");
        if (soap_wsse_add_EncryptedKey_encrypt_only(soap, SOAP_MEC_ENV_ENC_DES_CBC, "Cert", cert, SubjectKeyId, NULL, NULL, "a"))
          soap_print_fault(soap, stderr);
      }
      soap_wsse_decrypt_auto(soap, SOAP_MEC_ENV_DEC_DES_CBC, rsa_privk, 0);
    }
    else if (enc)
    { /* RSA encryption of the SOAP Body */
      const char *SubjectKeyId = NULL; /* set to non-NULL to use SubjectKeyIdentifier in Header rather than a full cert key */
      if (oaep)
      { if (soap_wsse_add_EncryptedKey(soap, SOAP_MEC_ENV_ENC_AES256_CBC | SOAP_MEC_OAEP, "Cert", cert, SubjectKeyId, NULL, NULL))
          soap_print_fault(soap, stderr);
      }
      else if (aes)
      { if (soap_wsse_add_EncryptedKey(soap, SOAP_MEC_ENV_ENC_AES256_CBC, "Cert", cert, SubjectKeyId, NULL, NULL))
          soap_print_fault(soap, stderr);
      }
      else
      { if (soap_wsse_add_EncryptedKey(soap, SOAP_MEC_ENV_ENC_DES_CBC, "Cert", cert, SubjectKeyId, NULL, NULL))
          soap_print_fault(soap, stderr);
      }
      soap_wsse_decrypt_auto(soap, SOAP_MEC_ENV_DEC_DES_CBC, rsa_privk, 0);
    }
    if (hmac)
    { /* symmetric signature */
      if (nobody)
        soap_wsse_sign(soap, SOAP_SMD_HMAC_SHA1, hmac_key, sizeof(hmac_key));
      else
        soap_wsse_sign_body(soap, SOAP_SMD_HMAC_SHA1, hmac_key, sizeof(hmac_key));
      /* WS-SecureConversation contect token */
      soap_wsse_add_SecurityContextToken(soap, "SCT", contextId);
    }
    else
    { if (nokey)
        soap_wsse_add_KeyInfo_KeyName(soap, "MyKey");
      else
      { soap_wsse_add_BinarySecurityTokenX509(soap, "X509Token", cert);
        soap_wsse_add_KeyInfo_SecurityTokenReferenceX509(soap, "#X509Token");
      }
      if (nobody || addsig) /* do not sign body */
        soap_wsse_sign(soap, SOAP_SMD_SIGN_RSA_SHA1, rsa_privk, 0);
      else
        soap_wsse_sign_body(soap, SOAP_SMD_SIGN_RSA_SHA256, rsa_privk, 0);
    }
    /* enable automatic signature verification of server responses */
    if (hmac)
      soap_wsse_verify_auto(soap, SOAP_SMD_HMAC_SHA1, hmac_key, sizeof(hmac_key));
    else if (nokey)
      soap_wsse_verify_auto(soap, SOAP_SMD_VRFY_RSA_SHA1, rsa_pubk, 0);
    else
      soap_wsse_verify_auto(soap, SOAP_SMD_NONE, NULL, 0);
    /* sign the response message in unsigned body? If so, set wsu:Id */
    if (addsig)
    { soap_wsse_set_wsu_id(soap, "ns1:add");
      soap_wsse_sign_only(soap, "User ns1:add");
    }
    /* invoke the server. You can choose add, sub, mul, or div operations
     * that show different security aspects (intentional message rejections)
     * for demonstration purposes (see server operations below) */
    if (!soap_call_ns1__add(soap, endpoint, NULL, 1.0, 2.0, &result))
    { if (!soap_wsse_verify_Timestamp(soap))
      { const char *servername = soap_wsse_get_Username(soap);
        if (servername
	 && !strcmp(servername, "server")
         && !soap_wsse_verify_Password(soap, "serverPass"))
          printf("Result = %g\n", result);
        else
	{ fprintf(stderr, "Server authentication failed\n");
          soap_print_fault(soap, stderr);
        }
      }
      else
      { fprintf(stderr, "Server response expired\n");
        soap_print_fault(soap, stderr);
      }
    }
    else
    { soap_print_fault(soap, stderr);
      soap_print_fault_location(soap, stderr);
    }
    /* clean up security header */
    soap_wsse_delete_Security(soap);
    /* disable soap_wsse_verify_auto */
    soap_wsse_verify_done(soap);

  } /* run */

  }
  /* clean up keys */
  if (rsa_privk)
    EVP_PKEY_free(rsa_privk);
  if (rsa_pubk)
    EVP_PKEY_free(rsa_pubk);
  if (cert)
    X509_free(cert);
  /* clean up gSOAP engine */
  soap_destroy(soap);
  soap_end(soap);
  soap_done(soap);
  free(soap);
  /* done */
  return 0;
}