xcode project update.

This commit is contained in:
Kelvin Sherlock 2020-09-25 21:10:36 -04:00
parent 13d78a94ed
commit 0befba12a5
3 changed files with 446 additions and 4 deletions

View File

@ -90,8 +90,11 @@
B64E15A924EA1D5300E8AD3D /* MachineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B64E15A824EA1D5300E8AD3D /* MachineViewController.m */; };
B66236A924FD9A34006CABD7 /* PreferencesWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */; };
B66236B524FDA527006CABD7 /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B66236B224FDA522006CABD7 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B66236BC24FDA72E006CABD7 /* mame64 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B66236B724FDA686006CABD7 /* mame64 */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
B66236C124FDB7A6006CABD7 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = B66236BF24FDB7A6006CABD7 /* Credits.rtf */; };
B6841BD7251EC926006A5C39 /* vmnet_helper.c in Sources */ = {isa = PBXBuildFile; fileRef = B6841BCA251EC88E006A5C39 /* vmnet_helper.c */; };
B6841BDA251ECB1C006A5C39 /* mame64 in CopyFiles */ = {isa = PBXBuildFile; fileRef = B66236B824FDA698006CABD7 /* mame64 */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
B6841BDC251ECC17006A5C39 /* vmnet_helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = B6841BD0251EC913006A5C39 /* vmnet_helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
B6841BDE251ECC29006A5C39 /* vmnet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6841BDD251ECC29006A5C39 /* vmnet.framework */; };
B6B9EA662506A5550080E70D /* EjectButton.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9EA642506A5550080E70D /* EjectButton.m */; };
B6B9EA672506A5550080E70D /* EjectButton.m in Sources */ = {isa = PBXBuildFile; fileRef = B6B9EA642506A5550080E70D /* EjectButton.m */; };
B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B6BA257F24E99BE9005FB8FF /* AppDelegate.m */; };
@ -203,10 +206,20 @@
dstPath = "";
dstSubfolderSpec = 6;
files = (
B66236BC24FDA72E006CABD7 /* mame64 in CopyFiles */,
B6841BDC251ECC17006A5C39 /* vmnet_helper in CopyFiles */,
B6841BDA251ECB1C006A5C39 /* mame64 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B6841BCE251EC913006A5C39 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
B6E4B5F324FDE2670094A35C /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -304,10 +317,12 @@
B66236A724FD9A34006CABD7 /* PreferencesWindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PreferencesWindowController.h; sourceTree = "<group>"; };
B66236A824FD9A34006CABD7 /* PreferencesWindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PreferencesWindowController.m; sourceTree = "<group>"; };
B66236B224FDA522006CABD7 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = embedded/SDL2.framework; sourceTree = "<group>"; };
B66236B724FDA686006CABD7 /* mame64 */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = mame64; path = embedded/mame64; sourceTree = "<group>"; };
B66236B824FDA698006CABD7 /* mame64 */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = mame64; path = embedded/mame64; sourceTree = "<group>"; };
B66236C024FDB7A6006CABD7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = Base; path = Base.lproj/Credits.rtf; sourceTree = "<group>"; };
B67BD48424EE249D0073E334 /* apple1.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = apple1.plist; sourceTree = "<group>"; };
B6841BCA251EC88E006A5C39 /* vmnet_helper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vmnet_helper.c; sourceTree = "<group>"; };
B6841BD0251EC913006A5C39 /* vmnet_helper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = vmnet_helper; sourceTree = BUILT_PRODUCTS_DIR; };
B6841BDD251ECC29006A5C39 /* vmnet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = vmnet.framework; path = System/Library/Frameworks/vmnet.framework; sourceTree = SDKROOT; };
B6B9EA642506A5550080E70D /* EjectButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EjectButton.m; sourceTree = "<group>"; };
B6B9EA652506A5550080E70D /* EjectButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EjectButton.h; sourceTree = "<group>"; };
B6BA257B24E99BE9005FB8FF /* Ample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Ample.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -339,6 +354,14 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
B6841BCD251EC913006A5C39 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B6841BDE251ECC29006A5C39 /* vmnet.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B6BA257824E99BE9005FB8FF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -427,7 +450,7 @@
B66236B624FDA686006CABD7 /* Frameworks */ = {
isa = PBXGroup;
children = (
B66236B724FDA686006CABD7 /* mame64 */,
B6841BDD251ECC29006A5C39 /* vmnet.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -442,11 +465,20 @@
name = "Embedded Content";
sourceTree = "<group>";
};
B6841BD1251EC913006A5C39 /* vmnet_helper */ = {
isa = PBXGroup;
children = (
B6841BCA251EC88E006A5C39 /* vmnet_helper.c */,
);
path = vmnet_helper;
sourceTree = "<group>";
};
B6BA257224E99BE9005FB8FF = {
isa = PBXGroup;
children = (
B6BA257D24E99BE9005FB8FF /* Ample */,
B66236BD24FDA7EA006CABD7 /* Embedded Content */,
B6841BD1251EC913006A5C39 /* vmnet_helper */,
B6BA257C24E99BE9005FB8FF /* Products */,
B649798C24EEC165008ABD20 /* Recovered References */,
B66236B624FDA686006CABD7 /* Frameworks */,
@ -458,6 +490,7 @@
children = (
B6BA257B24E99BE9005FB8FF /* Ample.app */,
B6E4B5FA24FDE2670094A35C /* Ample Lite.app */,
B6841BD0251EC913006A5C39 /* vmnet_helper */,
);
name = Products;
sourceTree = "<group>";
@ -553,6 +586,23 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
B6841BCF251EC913006A5C39 /* vmnet_helper */ = {
isa = PBXNativeTarget;
buildConfigurationList = B6841BD4251EC913006A5C39 /* Build configuration list for PBXNativeTarget "vmnet_helper" */;
buildPhases = (
B6841BCC251EC913006A5C39 /* Sources */,
B6841BCD251EC913006A5C39 /* Frameworks */,
B6841BCE251EC913006A5C39 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = vmnet_helper;
productName = vmnet_helper;
productReference = B6841BD0251EC913006A5C39 /* vmnet_helper */;
productType = "com.apple.product-type.tool";
};
B6BA257A24E99BE9005FB8FF /* Ample */ = {
isa = PBXNativeTarget;
buildConfigurationList = B6BA258C24E99BEB005FB8FF /* Build configuration list for PBXNativeTarget "Ample" */;
@ -599,6 +649,9 @@
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = "Kelvin Sherlock";
TargetAttributes = {
B6841BCF251EC913006A5C39 = {
CreatedOnToolsVersion = 11.3.1;
};
B6BA257A24E99BE9005FB8FF = {
CreatedOnToolsVersion = 11.3.1;
};
@ -619,6 +672,7 @@
targets = (
B6BA257A24E99BE9005FB8FF /* Ample */,
B6E4B5AE24FDE2670094A35C /* Ample Lite */,
B6841BCF251EC913006A5C39 /* vmnet_helper */,
);
};
/* End PBXProject section */
@ -784,6 +838,14 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
B6841BCC251EC913006A5C39 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B6841BD7251EC926006A5C39 /* vmnet_helper.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B6BA257724E99BE9005FB8FF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -899,6 +961,22 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
B6841BD5251EC913006A5C39 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
B6841BD6251EC913006A5C39 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
B6BA258A24E99BEB005FB8FF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -1083,6 +1161,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
B6841BD4251EC913006A5C39 /* Build configuration list for PBXNativeTarget "vmnet_helper" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B6841BD5251EC913006A5C39 /* Debug */,
B6841BD6251EC913006A5C39 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B6BA257624E99BE9005FB8FF /* Build configuration list for PBXProject "Ample" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -24,6 +24,11 @@
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>vmnet_helper.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
</dict>
</plist>

350
vmnet_helper/vmnet_helper.c Normal file
View File

@ -0,0 +1,350 @@
/* vmnet helper */
/* because it needs root permissions ... sigh */
/*
* basicly... run as root, read messages from stdin, write to stdout.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <vmnet/vmnet.h>
#include <errno.h>
#include <err.h>
static interface_ref interface;
static uint8_t interface_mac[6];
static long interface_mtu;
static long interface_packet_size;
static vmnet_return_t interface_status;
static size_t buffer_size = 0;
static uint8_t *buffer = NULL;
enum {
MSG_QUIT,
MSG_STATUS,
MSG_READ,
MSG_WRITE
};
#define MAKE_MSG(msg, extra) (msg | ((extra) << 8))
ssize_t safe_read(void *buffer, size_t nbyte) {
ssize_t rv;
for(;;) {
rv = read(STDIN_FILENO, buffer, nbyte);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "read");
}
break;
}
return rv;
}
ssize_t safe_readv(const struct iovec *iov, int iovcnt) {
ssize_t rv;
for(;;) {
rv = readv(STDIN_FILENO, iov, iovcnt);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "readv");
}
break;
}
return rv;
}
ssize_t safe_write(const void *buffer, size_t nbyte) {
ssize_t rv;
for(;;) {
rv = write(STDOUT_FILENO, buffer, nbyte);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "write");
}
break;
}
return rv;
}
ssize_t safe_writev(const struct iovec *iov, int iovcnt) {
ssize_t rv;
for(;;) {
rv = writev(STDOUT_FILENO, iov, iovcnt);
if (rv < 0) {
if (errno == EINTR) continue;
err(1, "writev");
}
break;
}
return rv;
}
void msg_status(uint32_t size) {
struct iovec iov[4];
uint32_t msg = MAKE_MSG(MSG_STATUS, 6 + 4 + 4);
iov[0].iov_len = 4;
iov[0].iov_base = &msg;
iov[1].iov_len = 6;
iov[1].iov_base = interface_mac;
iov[2].iov_len = 4;
iov[2].iov_base = &interface_mtu;
iov[3].iov_len = 4;
iov[3].iov_base = &interface_packet_size;
safe_writev(iov, 4);
}
int classify_mac(uint8_t *mac) {
if ((mac[0] & 0x01) == 0) return 1; /* unicast */
if (memcmp(mac, "\xff\xff\xff\xff\xff\xff", 6) == 0) return 0xff; /* broadcast */
return 2; /* multicast */
}
void msg_read(uint32_t flags) {
/* flag to block broadcast, multicast, etc? */
int count = 1;
int xfer;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov[2];
uint32_t msg;
for(;;) {
int type;
iov[0].iov_base = buffer;
iov[0].iov_len = interface_packet_size;
v.vm_pkt_size = interface_packet_size;
v.vm_pkt_iov = iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
count = 1;
st = vmnet_read(interface, &v, &count);
if (st != VMNET_SUCCESS) errx(1, "vmnet_read");
if (count < 1) break;
/* todo -- skip multicast messages based on flag? */
type = classify_mac(buffer);
if (type == 2) continue; /* multicast */
break;
}
xfer = count == 1 ? (int)v.vm_pkt_size : 0;
msg = MAKE_MSG(MSG_READ, xfer);
iov[0].iov_len = 4;
iov[0].iov_base = &msg;
iov[1].iov_len = xfer;
iov[1].iov_base = buffer;
safe_writev(iov, count == 1 ? 2 : 1);
}
void msg_write(uint32_t size) {
ssize_t ok;
int count = 1;
vmnet_return_t st;
struct vmpktdesc v;
struct iovec iov;
uint32_t msg;
if (size > interface_packet_size) errx(1, "packet too big");
for(;;) {
ok = safe_read(buffer, size);
if (ok < 0) err(1,"read");
if (ok != size) errx(1,"message truncated");
break;
}
iov.iov_base = buffer;
iov.iov_len = size;
v.vm_pkt_size = size;
v.vm_pkt_iov = &iov;
v.vm_pkt_iovcnt = 1;
v.vm_flags = 0;
st = vmnet_write(interface, &v, &count);
if (st != VMNET_SUCCESS) errx(1, "vmnet_write");
msg = MAKE_MSG(MSG_WRITE, size);
iov.iov_len = 4;
iov.iov_base = &msg;
safe_writev(&iov, 1);
}
/*
* Drop privileges according to the CERT Secure C Coding Standard section
* POS36-C
* https://www.securecoding.cert.org/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges
*/
static int drop_privileges(void) {
// If we are not effectively root, don't drop privileges
if (geteuid() != 0 && getegid() != 0) {
return 0;
}
if (setgid(getgid()) == -1) {
return -1;
}
if (setuid(getuid()) == -1) {
return -1;
}
return 0;
}
void vm_startup(void) {
xpc_object_t dict;
dispatch_queue_t q;
dispatch_semaphore_t sem;
memset(interface_mac, 0, sizeof(interface_mac));
interface_status = 0;
interface_mtu = 0;
interface_packet_size = 0;
dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_uint64(dict, vmnet_operation_mode_key, VMNET_SHARED_MODE);
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
interface = vmnet_start_interface(dict, q, ^(vmnet_return_t status, xpc_object_t params){
interface_status = status;
if (status == VMNET_SUCCESS) {
const char *cp;
cp = xpc_dictionary_get_string(params, vmnet_mac_address_key);
fprintf(stderr, "vmnet mac: %s\n", cp);
sscanf(cp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
&interface_mac[0],
&interface_mac[1],
&interface_mac[2],
&interface_mac[3],
&interface_mac[4],
&interface_mac[5]
);
interface_mtu = xpc_dictionary_get_uint64(params, vmnet_mtu_key);
interface_packet_size = xpc_dictionary_get_uint64(params, vmnet_max_packet_size_key);
fprintf(stderr, "vmnet mtu: %u\n", (unsigned)interface_mtu);
fprintf(stderr, "vmnet packet size: %u\n", (unsigned)interface_packet_size);
}
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
if (interface_status == VMNET_SUCCESS) {
buffer_size = (interface_packet_size * 2 + 1023) & ~1023;
buffer = (uint8_t *)malloc(buffer_size);
} else {
if (interface) {
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
interface = NULL;
}
errx(1,"vmnet_start_interface failed");
}
dispatch_release(sem);
xpc_release(dict);
drop_privileges();
}
void vm_shutdown(void) {
dispatch_queue_t q;
dispatch_semaphore_t sem;
if (interface) {
sem = dispatch_semaphore_create(0);
q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
vmnet_stop_interface(interface, q, ^(vmnet_return_t status){
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_release(sem);
interface = NULL;
interface_status = 0;
}
free(buffer);
buffer = NULL;
buffer_size = 0;
}
int main(int argc, char **argv) {
uint32_t msg;
uint32_t extra;
ssize_t ok;
vm_startup();
for(;;) {
ok = safe_read(&msg, 4);
if (ok == 0) break;
if (ok != 4) errx(1,"read msg");
extra = msg >> 8;
msg = msg & 0xff;
switch(msg) {
case MSG_STATUS:
msg_status(extra);
break;
case MSG_QUIT:
vm_shutdown();
exit(0);
case MSG_READ:
msg_read(extra);
break;
case MSG_WRITE:
msg_write(extra);
break;
}
}
vm_shutdown();
exit(0);
}