SSLSock SSL_New(int fd, // IN Bool closeFdOnShutdown) // IN { SSLSock sslSock; sslSock = calloc(1, sizeof *sslSock); ASSERT_MEM_ALLOC(sslSock); sslSock->fd = fd; sslSock->closeFdOnShutdown = closeFdOnShutdown; return sslSock; }
static int SNEForEachCallback(const char *key, // IN: environment variable void *value, // IN: environment value void *clientData) // IN/OUT: DynBuf container (SNEBufs) { DynBuf *nativeEnvironStrings = ((SNEBufs *)clientData)->nativeEnvironStrings; DynBuf *nativeEnvironOffsets = ((SNEBufs *)clientData)->nativeEnvironOffsets; size_t itemSize; char *itemBuf; off_t itemOffset; /* * A NULL value indicates that this variable is not to be set. */ if (value == NULL) { return 0; } /* Determine the length of the new string inc. '=' delimiter and NUL. */ itemSize = strlen(key) + strlen(value) + sizeof "="; itemBuf = Util_SafeMalloc(itemSize); /* Create new "key=value" string. */ snprintf(itemBuf, itemSize, "%s=%s", key, (char *)value); ASSERT_MEM_ALLOC(DynBuf_AppendString(nativeEnvironStrings, itemBuf)); /* * Get the relative offset of our newly added string (relative to the DynBuf's base * address), and then append that to nativeEnvironOffsets. */ itemOffset = DynBuf_GetSize(nativeEnvironStrings) - itemSize; ASSERT_MEM_ALLOC(DynBuf_Append(nativeEnvironOffsets, &itemOffset, sizeof itemOffset)); free(itemBuf); return 0; }
void * UnicodeGetAllocBytesInternal(ConstUnicode ustr, // IN StringEncoding encoding, // IN ssize_t lengthInBytes, // IN size_t *retLength) // OUT: optional { const char *utf8Str = ustr; char *result = NULL; ASSERT(ustr != NULL); encoding = Unicode_ResolveEncoding(encoding); if (lengthInBytes == -1) { lengthInBytes = Unicode_LengthInBytes(ustr, STRING_ENCODING_UTF8); } switch (encoding) { case STRING_ENCODING_US_ASCII: if (!UnicodeSanityCheck(utf8Str, lengthInBytes, encoding)) { break; } // fall through case STRING_ENCODING_UTF8: result = Util_SafeMalloc(lengthInBytes + 1); memcpy(result, utf8Str, lengthInBytes + 1); if (retLength != NULL) { *retLength = lengthInBytes; } break; case STRING_ENCODING_UTF16_LE: if (!CodeSet_Utf8ToUtf16le(utf8Str, lengthInBytes, &result, retLength)) { // input should be valid UTF-8, no conversion error possible ASSERT_MEM_ALLOC(FALSE); } break; default: if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, lengthInBytes, Unicode_EncodingEnumToName(encoding), CSGTG_NORMAL, &result, retLength)) { // XXX can't distinguish error cause ASSERT(result == NULL); } } return result; }
static void MsgSetCatalog(const char *domain, MsgCatalog *catalog) { MsgState *state = MsgGetState(); ASSERT(domain); if (state->domains == NULL) { state->domains = HashTable_Alloc(8, HASH_STRING_KEY | HASH_FLAG_COPYKEY, (HashTableFreeEntryFn) MsgCatalogFree); ASSERT_MEM_ALLOC(state->domains); } HashTable_ReplaceOrInsert(state->domains, domain, catalog); }
static gboolean RpcChannelReset(RpcInData *data) { gchar *msg; RpcChannelInt *chan = data->clientData; if (chan->resetCheck == NULL) { chan->resetCheck = g_idle_source_new(); g_source_set_priority(chan->resetCheck, G_PRIORITY_HIGH); g_source_set_callback(chan->resetCheck, RpcChannelCheckReset, chan, NULL); g_source_attach(chan->resetCheck, chan->mainCtx); } msg = Str_Asprintf(NULL, "ATR %s", chan->appName); ASSERT_MEM_ALLOC(msg); return RPCIN_SETRETVALSF(data, msg, TRUE); }
Bool Unicode_CopyBytes(void *destBuffer, // OUT ConstUnicode srcBuffer, // IN size_t maxLengthInBytes, // IN size_t *retLength, // OUT StringEncoding encoding) // IN { const char *utf8Str = (const char *)srcBuffer; Bool success = FALSE; size_t copyBytes = 0; encoding = Unicode_ResolveEncoding(encoding); switch (encoding) { case STRING_ENCODING_US_ASCII: if (!UnicodeSanityCheck(utf8Str, -1, encoding)) { break; } // fall through case STRING_ENCODING_UTF8: { size_t len = strlen(utf8Str); copyBytes = MIN(len, maxLengthInBytes - 1); memcpy(destBuffer, utf8Str, copyBytes); /* * If we truncated, force a null termination in a UTF-8 safe * manner. */ if (copyBytes >= len) { success = TRUE; } else { if (encoding == STRING_ENCODING_UTF8) { copyBytes = CodeSet_Utf8FindCodePointBoundary(destBuffer, copyBytes); } } ((char*)destBuffer)[copyBytes] = '\0'; } break; case STRING_ENCODING_UTF16_LE: { char *utf16Buf; size_t utf16BufLen; if (!CodeSet_Utf8ToUtf16le(utf8Str, strlen(utf8Str), &utf16Buf, &utf16BufLen)) { // input should be valid UTF-8, no conversion error possible ASSERT_MEM_ALLOC(FALSE); break; } copyBytes = MIN(utf16BufLen, maxLengthInBytes - 2); memcpy(destBuffer, utf16Buf, copyBytes); copyBytes = CodeSet_Utf16FindCodePointBoundary(destBuffer, copyBytes); ((utf16_t*)destBuffer)[copyBytes / 2] = 0; free(utf16Buf); if (copyBytes >= utf16BufLen) { success = TRUE; } break; } default: { char *currentBuf; size_t currentBufSize; if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, strlen(utf8Str), Unicode_EncodingEnumToName(encoding), CSGTG_NORMAL, ¤tBuf, ¤tBufSize)) { // XXX can't distinguish error cause break; } copyBytes = MIN(currentBufSize, maxLengthInBytes - 1); memcpy(destBuffer, currentBuf, copyBytes); free(currentBuf); /* * XXX this isn't quite correct, we still need to truncate on * a code point boundary, based on the current encoding type, * rather than just null terminate blindly. */ ((char*)destBuffer)[copyBytes] = 0; if (copyBytes >= currentBufSize) { success = TRUE; } } break; } if (retLength) { *retLength = copyBytes; } return success; }
static Bool RecordRoutingInfoIPv6(NicInfoV3 *nicInfo) { GPtrArray *routes = NULL; guint i; Bool ret = FALSE; if ((routes = SlashProcNet_GetRoute6()) == NULL) { return FALSE; } for (i = 0; i < routes->len; i++) { struct sockaddr_storage ss; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ss; struct in6_rtmsg *in6_rtmsg; InetCidrRouteEntry *icre; uint32_t ifIndex = -1; /* Check to see if we're going above our limit. See bug 605821. */ if (nicInfo->routes.routes_len == NICINFO_MAX_ROUTES) { g_message("%s: route limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_ROUTES); break; } in6_rtmsg = g_ptr_array_index(routes, i); if ((in6_rtmsg->rtmsg_flags & RTF_UP) == 0 || !GuestInfoGetNicInfoIfIndex(nicInfo, in6_rtmsg->rtmsg_ifindex, &ifIndex)) { continue; } icre = XDRUTIL_ARRAYAPPEND(nicInfo, routes, 1); ASSERT_MEM_ALLOC(icre); /* * Destination. */ sin6->sin6_family = AF_INET6; sin6->sin6_addr = in6_rtmsg->rtmsg_dst; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, &icre->inetCidrRouteDest); icre->inetCidrRoutePfxLen = in6_rtmsg->rtmsg_dst_len; /* * Next hop. */ if (in6_rtmsg->rtmsg_flags & RTF_GATEWAY) { TypedIpAddress *ip = Util_SafeCalloc(1, sizeof *ip); sin6->sin6_addr = in6_rtmsg->rtmsg_gateway; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, ip); icre->inetCidrRouteNextHop = ip; } /* * Interface, metric. */ icre->inetCidrRouteIfIndex = ifIndex; icre->inetCidrRouteMetric = in6_rtmsg->rtmsg_metric; } ret = TRUE; SlashProcNet_FreeRoute6(routes); return ret; }
static Bool RecordRoutingInfoIPv4(NicInfoV3 *nicInfo) { GPtrArray *routes = NULL; guint i; Bool ret = FALSE; if ((routes = SlashProcNet_GetRoute()) == NULL) { return FALSE; } for (i = 0; i < routes->len; i++) { struct rtentry *rtentry; struct sockaddr_in *sin_dst; struct sockaddr_in *sin_gateway; struct sockaddr_in *sin_genmask; InetCidrRouteEntry *icre; uint32_t ifIndex; /* Check to see if we're going above our limit. See bug 605821. */ if (nicInfo->routes.routes_len == NICINFO_MAX_ROUTES) { g_message("%s: route limit (%d) reached, skipping overflow.", __FUNCTION__, NICINFO_MAX_ROUTES); break; } rtentry = g_ptr_array_index(routes, i); if ((rtentry->rt_flags & RTF_UP) == 0 || !GuestInfoGetNicInfoIfIndex(nicInfo, if_nametoindex(rtentry->rt_dev), &ifIndex)) { continue; } icre = XDRUTIL_ARRAYAPPEND(nicInfo, routes, 1); ASSERT_MEM_ALLOC(icre); sin_dst = (struct sockaddr_in *)&rtentry->rt_dst; sin_gateway = (struct sockaddr_in *)&rtentry->rt_gateway; sin_genmask = (struct sockaddr_in *)&rtentry->rt_genmask; GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin_dst, &icre->inetCidrRouteDest); addr_stob((struct sockaddr *)sin_genmask, (uint16_t *)&icre->inetCidrRoutePfxLen); /* * Gateways are optional (ex: one can bind a route to an interface w/o * specifying a next hop address). */ if (rtentry->rt_flags & RTF_GATEWAY) { TypedIpAddress *ip = Util_SafeCalloc(1, sizeof *ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin_gateway, ip); icre->inetCidrRouteNextHop = ip; } /* * Interface, metric. */ icre->inetCidrRouteIfIndex = ifIndex; icre->inetCidrRouteMetric = rtentry->rt_metric; } ret = TRUE; SlashProcNet_FreeRoute(routes); return ret; }
static void RecordResolverNS(DnsConfigInfo *dnsConfigInfo) // IN { int i; #if defined RESOLVER_IPV6_GETSERVERS { union res_sockaddr_union *ns; ns = Util_SafeCalloc(_res.nscount, sizeof *ns); if (res_getservers(&_res, ns, _res.nscount) != _res.nscount) { g_warning("%s: res_getservers failed.\n", __func__); return; } for (i = 0; i < _res.nscount; i++) { struct sockaddr *sa = (struct sockaddr *)&ns[i]; if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress(sa, ip); } } } #else // if defined RESOLVER_IPV6_GETSERVERS { /* * Name servers (IPv4). */ for (i = 0; i < MAXNS; i++) { struct sockaddr_in *sin = &_res.nsaddr_list[i]; if (sin->sin_family == AF_INET) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin, ip); } } # if defined RESOLVER_IPV6_EXT /* * Name servers (IPv6). */ for (i = 0; i < MAXNS; i++) { struct sockaddr_in6 *sin6 = _res._u._ext.nsaddrs[i]; if (sin6) { TypedIpAddress *ip; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->serverList.serverList_len == DNSINFO_MAX_SERVERS) { g_message("%s: dns server limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SERVERS); break; } ip = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, serverList, 1); ASSERT_MEM_ALLOC(ip); GuestInfoSockaddrToTypedIpAddress((struct sockaddr *)sin6, ip); } } # endif // if defined RESOLVER_IPV6_EXT } #endif // if !defined RESOLVER_IPV6_GETSERVERS }
static Bool RecordResolverInfo(NicInfoV3 *nicInfo) // OUT { DnsConfigInfo *dnsConfigInfo = NULL; char namebuf[DNSINFO_MAX_ADDRLEN + 1]; char **s; if (res_init() == -1) { return FALSE; } dnsConfigInfo = Util_SafeCalloc(1, sizeof *dnsConfigInfo); /* * Copy in the host name. not this */ if (!GuestInfoGetFqdn(sizeof namebuf, namebuf)) { goto fail; } dnsConfigInfo->hostName = Util_SafeCalloc(1, sizeof *dnsConfigInfo->hostName); *dnsConfigInfo->hostName = Util_SafeStrdup(namebuf); /* * Repeat with the domain name. not this */ dnsConfigInfo->domainName = Util_SafeCalloc(1, sizeof *dnsConfigInfo->domainName); *dnsConfigInfo->domainName = Util_SafeStrdup(_res.defdname); /* * Name servers. */ RecordResolverNS(dnsConfigInfo); /* * Search suffixes. */ for (s = _res.dnsrch; *s; s++) { DnsHostname *suffix; /* Check to see if we're going above our limit. See bug 605821. */ if (dnsConfigInfo->searchSuffixes.searchSuffixes_len == DNSINFO_MAX_SUFFIXES) { g_message("%s: dns search suffix limit (%d) reached, skipping overflow.", __FUNCTION__, DNSINFO_MAX_SUFFIXES); break; } suffix = XDRUTIL_ARRAYAPPEND(dnsConfigInfo, searchSuffixes, 1); ASSERT_MEM_ALLOC(suffix); *suffix = Util_SafeStrdup("test suffix"); } /* * "Commit" dnsConfigInfo to nicInfo. */ nicInfo->dnsConfigInfo = dnsConfigInfo; return TRUE; fail: VMX_XDR_FREE(xdr_DnsConfigInfo, dnsConfigInfo); free(dnsConfigInfo); return FALSE; }
static MsgCatalog * MsgLoadCatalog(const char *path) { gchar *localPath; GError *err = NULL; GIOChannel *stream; gboolean error = FALSE; MsgCatalog *catalog = NULL; HashTable *dict; ASSERT(path != NULL); localPath = VMTOOLS_GET_FILENAME_LOCAL(path, NULL); ASSERT(localPath != NULL); stream = g_io_channel_new_file(localPath, "r", &err); VMTOOLS_RELEASE_FILENAME_LOCAL(localPath); if (err != NULL) { g_debug("Unable to open '%s': %s\n", path, err->message); g_clear_error(&err); return NULL; } dict = HashTable_Alloc(8, HASH_STRING_KEY | HASH_FLAG_COPYKEY, g_free); ASSERT_MEM_ALLOC(dict); for (;;) { gboolean eof = FALSE; char *name = NULL; char *value = NULL; gchar *line; /* Read the next key / value pair. */ for (;;) { gsize i; gsize len; gsize term; char *unused = NULL; gboolean cont = FALSE; g_io_channel_read_line(stream, &line, &len, &term, &err); if (err != NULL) { g_warning("Unable to read a line from '%s': %s\n", path, err->message); g_clear_error(&err); error = TRUE; g_free(line); break; } if (line == NULL) { eof = TRUE; break; } /* * Fix the line break to always be Unix-style, to make lib/dict * happy. */ if (line[term] == '\r') { line[term] = '\n'; if (len > term) { line[term + 1] = '\0'; } } /* * If currently name is not NULL, then check if this is a continuation * line and, if it is, just append the contents to the current value. */ if (term > 0 && name != NULL && line[term - 1] == '"') { for (i = 0; i < len; i++) { if (line[i] == '"') { /* OK, looks like a continuation line. */ char *tmp; char *unescaped; line[term - 1] = '\0'; unescaped = Escape_Undo('|', line + i + 1, len - i, NULL); tmp = Str_Asprintf(NULL, "%s%s", value, unescaped); free(unescaped); free(value); value = tmp; cont = TRUE; break; } else if (line[i] != ' ' && line[i] != '\t') { break; } } } /* * If not a continuation line and we have a name, break out of the * inner loop to update the dictionaty. */ if (!cont && name != NULL) { g_free(line); break; } /* * Finally, try to parse the string using the dictionary library. */ if (!cont && DictLL_UnmarshalLine(line, len, &unused, &name, &value) == NULL) { g_warning("Couldn't parse line from catalog: %s", line); error = TRUE; } g_free(line); free(unused); } if (error) { break; } if (name != NULL) { ASSERT(value); if (!Unicode_IsBufferValid(name, strlen(name) + 1, STRING_ENCODING_UTF8) || !Unicode_IsBufferValid(value, strlen(value) + 1, STRING_ENCODING_UTF8)) { g_warning("Invalid UTF-8 string in message catalog (key = %s)\n", name); error = TRUE; break; } MsgUnescape(value); HashTable_ReplaceOrInsert(dict, name, g_strdup(value)); free(name); free(value); name = NULL; value = NULL; } if (eof) { break; } } g_io_channel_unref(stream); if (error) { HashTable_Free(dict); dict = NULL; } else { catalog = g_new0(MsgCatalog, 1); catalog->utf8 = dict; } return catalog; }
static const void * MsgGetString(const char *domain, const char *msgid, StringEncoding encoding) { const char *idp; const char *strp; char idBuf[MSG_MAX_ID]; size_t len; HashTable *source = NULL; MsgCatalog *catalog; MsgState *state = MsgGetState(); /* All message strings must be prefixed by the message ID. */ ASSERT(domain != NULL); ASSERT(msgid != NULL); ASSERT(MsgHasMsgID(msgid)); #if defined(_WIN32) ASSERT(encoding == STRING_ENCODING_UTF8 || encoding == STRING_ENCODING_UTF16_LE); #else ASSERT(encoding == STRING_ENCODING_UTF8); #endif /* * Find the beginning of the ID (idp) and the string (strp). * The string should have the correct MSG_MAGIC(...)... form. */ idp = msgid + MSG_MAGIC_LEN + 1; strp = strchr(idp, ')') + 1; len = strp - idp - 1; ASSERT_NOT_IMPLEMENTED(len <= MSG_MAX_ID - 1); memcpy(idBuf, idp, len); idBuf[len] = '\0'; /* * This lock is pretty coarse-grained, but a lot of the code below just runs * in exceptional situations, so it should be OK. */ g_static_mutex_lock(&state->lock); catalog = MsgGetCatalog(domain); if (catalog != NULL) { switch (encoding) { case STRING_ENCODING_UTF8: source = catalog->utf8; break; #if defined(_WIN32) case STRING_ENCODING_UTF16_LE: source = catalog->utf16; break; #endif default: NOT_IMPLEMENTED(); } } #if defined(_WIN32) /* * Lazily create the local and UTF-16 dictionaries. This may require also * registering an empty message catalog for the desired domain. */ if (source == NULL && encoding == STRING_ENCODING_UTF16_LE) { catalog = MsgGetCatalog(domain); if (catalog == NULL) { if (domain == NULL) { g_error("Application did not set up a default text domain."); } catalog = g_new0(MsgCatalog, 1); MsgSetCatalog(domain, catalog); } catalog->utf16 = HashTable_Alloc(8, HASH_STRING_KEY, g_free); ASSERT_MEM_ALLOC(catalog->utf16); source = catalog->utf16; } #endif /* * Look up the localized string, converting to requested encoding as needed. */ if (source != NULL) { const void *retval = NULL; if (HashTable_Lookup(source, idBuf, (void **) &retval)) { strp = retval; #if defined(_WIN32) } else if (encoding == STRING_ENCODING_UTF16_LE) { gchar *converted; Bool success; /* * Look up the string in UTF-8, convert it and cache it. */ retval = MsgGetString(domain, msgid, STRING_ENCODING_UTF8); ASSERT(retval); converted = (gchar *) g_utf8_to_utf16(retval, -1, NULL, NULL, NULL); ASSERT(converted != NULL); success = HashTable_Insert(source, idBuf, converted); ASSERT(success); strp = converted; #endif } } g_static_mutex_unlock(&state->lock); return strp; }