예제 #1
0
static struct oc_text_buf *get_qs(char **str)
{
	struct oc_text_buf *res;
	int escaped = 0;
	char *p = *str;

	if (*p != '\"')
		return NULL;

	res = buf_alloc();

	while (*++p) {
		if (!escaped && *p == '\"') {
			*str = p+1;
			if (buf_error(res))
				break;
			return res;
		}
		if (escaped)
			escaped = 0;
		else if (*p == '\\')
			escaped = 1;
		buf_append_bytes(res, p, 1);
	}
	buf_free(res);
	return NULL;
}
예제 #2
0
static SSL_SESSION *generate_dtls_session(struct openconnect_info *vpninfo,
					  int dtlsver, const SSL_CIPHER *cipher)
{
	struct oc_text_buf *buf = buf_alloc();
	SSL_SESSION *dtls_session;
	const unsigned char *asn;
	uint16_t cid;

	buf_append_bytes(buf, "\x30\x80", 2); // SEQUENCE, indeterminate length
	buf_append_INTEGER(buf, 1 /* SSL_SESSION_ASN1_VERSION */);
	buf_append_INTEGER(buf, dtlsver);
	store_be16(&cid, SSL_CIPHER_get_id(cipher) & 0xffff);
	buf_append_OCTET_STRING(buf, &cid, 2);
	buf_append_OCTET_STRING(buf, vpninfo->dtls_session_id,
				sizeof(vpninfo->dtls_session_id));
	buf_append_OCTET_STRING(buf, vpninfo->dtls_secret,
				sizeof(vpninfo->dtls_secret));
	/* If the length actually fits in one byte (which it should), do
	 * it that way.  Else, leave it indeterminate and add two
	 * end-of-contents octets to mark the end of the SEQUENCE. */
	if (!buf_error(buf) && buf->pos <= 0x80)
		buf->data[1] = buf->pos - 2;
	else
		buf_append_bytes(buf, "\0\0", 2);

	if (buf_error(buf)) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to create SSL_SESSION ASN.1 for OpenSSL: %s\n"),
			     strerror(buf_error(buf)));
		buf_free(buf);
		return NULL;
	}

	asn = (void *)buf->data;
	dtls_session = d2i_SSL_SESSION(NULL, &asn, buf->pos);
	buf_free(buf);
	if (!dtls_session) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("OpenSSL failed to parse SSL_SESSION ASN.1\n"));
		openconnect_report_ssl_errors(vpninfo);
		return NULL;
	}

	return dtls_session;
}
예제 #3
0
static void buf_append_unq(struct oc_text_buf *buf, const char *str)
{
	while (*str) {
		if (*str == '\"' || *str == '\\')
			buf_append(buf, "\\");
		buf_append_bytes(buf, str, 1);
		str++;
	}
}
예제 #4
0
static wchar_t *create_script_env(struct openconnect_info *vpninfo)
{
	struct oc_vpn_option *opt;
	struct oc_text_buf *envbuf;
	wchar_t **oldenv, **p, *newenv = NULL;
	int nr_envs = 0, i;

	/* _wenviron is NULL until we call _wgetenv() */
	(void)_wgetenv(L"PATH");

	/* Take a copy of _wenviron (but not of its strings) */
	for (p = _wenviron; *p; p++)
		nr_envs++;

	oldenv = malloc(nr_envs * sizeof(*oldenv));
	if (!oldenv)
		return NULL;
	memcpy(oldenv, _wenviron, nr_envs * sizeof(*oldenv));

	envbuf = buf_alloc();

	/* Add the script environment variables, prodding out any members of
	   oldenv which are obsoleted by them. */
	for (opt = vpninfo->script_env; opt && !buf_error(envbuf); opt = opt->next) {
		struct oc_text_buf *buf;

		buf = buf_alloc();
		buf_append_utf16le(buf, opt->option);
		buf_append_utf16le(buf, "=");

		if (buf_error(buf)) {
			buf_free(buf);
			goto err;
		}

		/* See if we can find it in the existing environment */
		for (i = 0; i < nr_envs; i++) {
			if (oldenv[i] &&
			    !wcsncmp((wchar_t *)buf->data, oldenv[i], buf->pos / 2)) {
				oldenv[i] = NULL;
				break;
			}
		}

		if (opt->value) {
			buf_append_bytes(envbuf, buf->data, buf->pos);
			buf_append_utf16le(envbuf, opt->value);
			buf_append_bytes(envbuf, "\0\0", 2);
		}

		buf_free(buf);
	}

	for (i = 0; i < nr_envs && !buf_error(envbuf); i++) {
		if (oldenv[i])
			buf_append_bytes(envbuf, oldenv[i],
					 (wcslen(oldenv[i]) + 1) * sizeof(wchar_t));
	}

	buf_append_bytes(envbuf, "\0\0", 2);

	if (!buf_error(envbuf)) {
		newenv = (wchar_t *)envbuf->data;
		envbuf->data = NULL;
	}

 err:
	free(oldenv);
	buf_free(envbuf);
	return newenv;
}