static bool tls_crypt_v2_verify_metadata(const struct tls_wrap_ctx *ctx, const struct tls_options *opt) { bool ret = false; struct gc_arena gc = gc_new(); const char *tmp_file = NULL; struct buffer metadata = ctx->tls_crypt_v2_metadata; int metadata_type = buf_read_u8(&metadata); if (metadata_type < 0) { msg(M_WARN, "ERROR: no metadata type"); goto cleanup; } tmp_file = platform_create_temp_file(opt->tmp_dir, "tls_crypt_v2_metadata_", &gc); if (!tmp_file || !buffer_write_file(tmp_file, &metadata)) { msg(M_WARN, "ERROR: could not write metadata to file"); goto cleanup; } char metadata_type_str[4] = { 0 }; /* Max value: 255 */ openvpn_snprintf(metadata_type_str, sizeof(metadata_type_str), "%i", metadata_type); struct env_set *es = env_set_create(NULL); setenv_str(es, "script_type", "tls-crypt-v2-verify"); setenv_str(es, "metadata_type", metadata_type_str); setenv_str(es, "metadata_file", tmp_file); struct argv argv = argv_new(); argv_parse_cmd(&argv, opt->tls_crypt_v2_verify_script); argv_msg_prefix(D_TLS_DEBUG, &argv, "Executing tls-crypt-v2-verify"); ret = openvpn_run_script(&argv, es, 0, "--tls-crypt-v2-verify"); argv_reset(&argv); env_set_destroy(es); if (!platform_unlink(tmp_file)) { msg(M_WARN, "WARNING: failed to remove temp file '%s", tmp_file); } if (ret) { msg(D_HANDSHAKE, "TLS CRYPT V2 VERIFY SCRIPT OK"); } else { msg(D_HANDSHAKE, "TLS CRYPT V2 VERIFY SCRIPT ERROR"); } cleanup: gc_free(&gc); return ret; }
void setenv_unsigned (struct env_set *es, const char *name, unsigned int value) { char buf[64]; openvpn_snprintf (buf, sizeof(buf), "%u", value); setenv_str (es, name, buf); }
void setenv_long_long(struct env_set *es, const char *name, long long value) { char buf[64]; openvpn_snprintf(buf, sizeof(buf), "%"PRIi64, (int64_t)value); setenv_str(es, name, buf); }
void set_win_sys_path (const char *newpath, struct env_set *es) { free (win_sys_path); win_sys_path = string_alloc (newpath, NULL); setenv_str (es, SYS_PATH_ENV_VAR_NAME, win_sys_path); /* route.exe needs this */ }
void setenv_int(struct env_set *es, const char *name, int value) { char buf[64]; openvpn_snprintf(buf, sizeof(buf), "%d", value); setenv_str(es, name, buf); }
void setenv_counter(struct env_set *es, const char *name, counter_type value) { char buf[64]; openvpn_snprintf(buf, sizeof(buf), counter_format, value); setenv_str(es, name, buf); }
void setenv_str_i(struct env_set *es, const char *name, const char *value, const int i) { struct gc_arena gc = gc_new(); const char *name_str = setenv_format_indexed_name(name, i, &gc); setenv_str(es, name_str, value); gc_free(&gc); }
void setenv_str_safe (struct env_set *es, const char *name, const char *value) { uint8_t b[64]; struct buffer buf; buf_set_write (&buf, b, sizeof (b)); if (buf_printf (&buf, "OPENVPN_%s", name)) setenv_str (es, BSTR(&buf), value); else msg (M_WARN, "setenv_str_safe: name overflow"); }
/* worker method for setenv_x509_track */ static void do_setenv_x509 (struct env_set *es, const char *name, char *value, int depth) { char *name_expand; size_t name_expand_size; string_mod (value, CC_ANY, CC_CRLF, '?'); msg (D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth); name_expand_size = 64 + strlen (name); name_expand = (char *) malloc (name_expand_size); check_malloc_return (name_expand); openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", depth, name); setenv_str (es, name_expand, value); free (name_expand); }
/* * Save X509 fields to environment, using the naming convention: * * X509_{cert_depth}_{name}={value} */ void x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert) { int i; unsigned char c; const x509_name *name; char s[128]; name = &cert->subject; memset( s, 0, sizeof( s ) ); while( name != NULL ) { char name_expand[64+8]; const char *shortname; if( 0 == oid_get_attr_short_name(&name->oid, &shortname) ) { openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s", cert_depth, shortname); } else { openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", cert_depth); } for( i = 0; i < name->val.len; i++ ) { if( i >= (int) sizeof( s ) - 1 ) break; c = name->val.p[i]; if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) s[i] = '?'; else s[i] = c; } s[i] = '\0'; /* Check both strings, set environment variable */ string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); string_mod ((char*)s, CC_PRINT, CC_CRLF, '_'); setenv_str (es, name_expand, (char*)s); name = name->next; } }
/* * Save X509 fields to environment, using the naming convention: * * X509_{cert_depth}_{name}={value} */ void x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert) { int i, n; int fn_nid; ASN1_OBJECT *fn; ASN1_STRING *val; X509_NAME_ENTRY *ent; const char *objbuf; unsigned char *buf; char *name_expand; size_t name_expand_size; X509_NAME *x509 = X509_get_subject_name (peer_cert); n = X509_NAME_entry_count (x509); for (i = 0; i < n; ++i) { ent = X509_NAME_get_entry (x509, i); if (!ent) continue; fn = X509_NAME_ENTRY_get_object (ent); if (!fn) continue; val = X509_NAME_ENTRY_get_data (ent); if (!val) continue; fn_nid = OBJ_obj2nid (fn); if (fn_nid == NID_undef) continue; objbuf = OBJ_nid2sn (fn_nid); if (!objbuf) continue; buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ if (ASN1_STRING_to_UTF8 (&buf, val) <= 0) continue; name_expand_size = 64 + strlen (objbuf); name_expand = (char *) malloc (name_expand_size); check_malloc_return (name_expand); openvpn_snprintf (name_expand, name_expand_size, "X509_%d_%s", cert_depth, objbuf); string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); string_mod ((char*)buf, CC_PRINT, CC_CRLF, '_'); setenv_str (es, name_expand, (char*)buf); free (name_expand); OPENSSL_free (buf); } }
void pf_init_context(struct context *c) { struct gc_arena gc = gc_new(); #ifdef PLUGIN_PF if (plugin_defined(c->plugins, OPENVPN_PLUGIN_ENABLE_PF)) { const char *pf_file = create_temp_file(c->options.tmp_dir, "pf", &gc); if (pf_file) { setenv_str(c->c2.es, "pf_file", pf_file); if (plugin_call(c->plugins, OPENVPN_PLUGIN_ENABLE_PF, NULL, NULL, c->c2.es) == OPENVPN_PLUGIN_FUNC_SUCCESS) { event_timeout_init(&c->c2.pf.reload, 1, now); c->c2.pf.filename = string_alloc(pf_file, &c->c2.gc); c->c2.pf.enabled = true; #ifdef ENABLE_DEBUG if (check_debug_level(D_PF_DEBUG)) { pf_context_print(&c->c2.pf, "pf_init_context#1", D_PF_DEBUG); } #endif } else { msg(M_WARN, "WARNING: OPENVPN_PLUGIN_ENABLE_PF disabled"); } } } #endif /* ifdef PLUGIN_PF */ #ifdef MANAGEMENT_PF if (!c->c2.pf.enabled && management_enable_pf(management)) { c->c2.pf.enabled = true; #ifdef ENABLE_DEBUG if (check_debug_level(D_PF_DEBUG)) { pf_context_print(&c->c2.pf, "pf_init_context#2", D_PF_DEBUG); } #endif } #endif gc_free(&gc); }
void setenv_str_incr(struct env_set *es, const char *name, const char *value) { unsigned int counter = 1; const size_t tmpname_len = strlen(name) + 5; /* 3 digits counter max */ char *tmpname = gc_malloc(tmpname_len, true, NULL); strcpy(tmpname, name); while (NULL != env_set_get(es, tmpname) && counter < 1000) { ASSERT(openvpn_snprintf(tmpname, tmpname_len, "%s_%u", name, counter)); counter++; } if (counter < 1000) { setenv_str(es, tmpname, value); } else { msg(D_TLS_DEBUG_MED, "Too many same-name env variables, ignoring: %s", name); } free(tmpname); }
void env_set_add_to_environment (const struct env_set *es) { if (es) { struct gc_arena gc = gc_new (); const struct env_item *e; e = es->list; while (e) { const char *name; const char *value; if (deconstruct_name_value (e->string, &name, &value, &gc)) setenv_str (NULL, name, value); e = e->next; } gc_free (&gc); } }
/* * GuizmOVPN_updown (const char *command, const struct plugin_list *plugins, int plugin_type, const char *arg, const char *dev_type, int tun_mtu, int link_mtu, const char *ifconfig_local, const char* ifconfig_remote, const char *context, const char *signal_text, const char *script_type, struct env_set *es) : * Run external script */ void GuizmOVPN_updown (const char *command, const struct plugin_list *plugins, int plugin_type, const char *arg, const char *dev_type, int tun_mtu, int link_mtu, const char *ifconfig_local, const char* ifconfig_remote, const char *context, const char *signal_text, const char *script_type, struct env_set *es) { if (signal_text) setenv_str (es, "signal", signal_text); setenv_str (es, "script_context", context); setenv_int (es, "tun_mtu", tun_mtu); setenv_int (es, "link_mtu", link_mtu); setenv_str (es, "dev", arg); if (!ifconfig_local) ifconfig_local = ""; if (!ifconfig_remote) { ifconfig_remote = ""; } setenv_str (es, "InfosGateway", tapemu_ip_to_string(tapemu_get_remote_ip())); if (!context) context = ""; static struct argv guizmovpn_argv; argv_reset(&guizmovpn_argv); guizmovpn_argv = argv_new (); ASSERT (arg); setenv_str (es, "script_type", script_type); char szTemp[32]; szTemp[0]='\0'; GuizmOVPN_ReadPrefs("DNSPush",szTemp); if(strcmp(szTemp,"NO") != 0) { setenv_str (es, "DNSPush", "Y"); } GuizmOVPN_ReadPrefs("DNSKeep",szTemp); if(strcmp(szTemp,"NO") != 0) { setenv_str (es, "DNSKeep", "Y"); } szTemp[0]='\0'; GuizmOVPN_ReadPrefs("Multicast",szTemp); if(dev_type!=NULL && !strcmp(dev_type,"tap") && strcmp(szTemp,"NO") != 0) { setenv_str (es, "Multicast", "Y"); } /* if(client_proxy_infos.active) { setenv_str (es, "ClientProxyIP", client_proxy_infos.server_ip); setenv_int (es, "ClientProxyPort", client_proxy_infos.port); }*/ argv_printf (&guizmovpn_argv, "%sc %s %d %d %s %s %s", GUIZMOVPN_COMMAND, arg, tun_mtu, link_mtu, ifconfig_local, ifconfig_remote, context); openvpn_execve (&guizmovpn_argv, es, 0); }
/* * Pass tunnel endpoint and MTU parms to a user-supplied script. * Used to execute the up/down script/plugins. */ void run_up_down (const char *command, const struct plugin_list *plugins, int plugin_type, const char *arg, const char *dev_type, int tun_mtu, int link_mtu, const char *ifconfig_local, const char* ifconfig_remote, const char *context, const char *signal_text, const char *script_type, struct env_set *es) { struct gc_arena gc = gc_new (); if (signal_text) setenv_str (es, "signal", signal_text); setenv_str (es, "script_context", context); setenv_int (es, "tun_mtu", tun_mtu); setenv_int (es, "link_mtu", link_mtu); setenv_str (es, "dev", arg); if (dev_type) setenv_str (es, "dev_type", dev_type); if (!ifconfig_local) ifconfig_local = ""; if (!ifconfig_remote) ifconfig_remote = ""; if (!context) context = ""; if (plugin_defined (plugins, plugin_type)) { struct argv argv = argv_new (); ASSERT (arg); argv_printf (&argv, "%s %d %d %s %s %s", arg, tun_mtu, link_mtu, ifconfig_local, ifconfig_remote, context); if (plugin_call (plugins, plugin_type, &argv, NULL, es) != OPENVPN_PLUGIN_FUNC_SUCCESS) msg (M_FATAL, "ERROR: up/down plugin call failed"); argv_reset (&argv); } if (command) { struct argv argv = argv_new (); ASSERT (arg); setenv_str (es, "script_type", script_type); argv_printf (&argv, "%sc %s %d %d %s %s %s", command, arg, tun_mtu, link_mtu, ifconfig_local, ifconfig_remote, context); argv_msg (M_INFO, &argv); openvpn_run_script (&argv, es, S_FATAL, "--up/--down"); argv_reset (&argv); } gc_free (&gc); }
void setenv_del(struct env_set *es, const char *name) { ASSERT(name); setenv_str(es, name, NULL); }
/* * Save X509 fields to environment, using the naming convention: * * X509_{cert_depth}_{name}={value} */ void x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert) { int i; unsigned char c; const x509_name *name; char s[128]; name = &cert->subject; memset( s, 0, sizeof( s ) ); while( name != NULL ) { char name_expand[64+8]; if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 ) { switch( name->oid.p[2] ) { case X520_COMMON_NAME: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN", cert_depth); break; case X520_COUNTRY: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C", cert_depth); break; case X520_LOCALITY: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L", cert_depth); break; case X520_STATE: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST", cert_depth); break; case X520_ORGANIZATION: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O", cert_depth); break; case X520_ORG_UNIT: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU", cert_depth); break; default: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_0x%02X", cert_depth, name->oid.p[2]); break; } } else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 ) { switch( name->oid.p[8] ) { case PKCS9_EMAIL: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_emailAddress", cert_depth); break; default: openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_0x%02X", cert_depth, name->oid.p[8]); break; } } else { openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?", cert_depth); } for( i = 0; i < name->val.len; i++ ) { if( i >= (int) sizeof( s ) - 1 ) break; c = name->val.p[i]; if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) s[i] = '?'; else s[i] = c; } s[i] = '\0'; /* Check both strings, set environment variable */ string_mod (name_expand, CC_PRINT, CC_CRLF, '_'); string_mod ((char*)s, CC_PRINT, CC_CRLF, '_'); setenv_str (es, name_expand, (char*)s); name = name->next; } }