Private
Public Access
1
0

Add 'server/' from commit '800090542d91beae40bc81fc41b67ba61c47da77'

git-subtree-dir: server
git-subtree-mainline: 6a4054c15a
git-subtree-split: 800090542d
This commit is contained in:
2025-09-06 19:36:27 -07:00
77 changed files with 13705 additions and 0 deletions

202
server/kordophone/main.m Normal file
View File

@@ -0,0 +1,202 @@
//
// main.m
// kordophone
//
// Created by James Magahern on 11/12/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MBIMBridge.h"
void printUsage()
{
fprintf(stderr, "Usage: kordophoned [-h] [-s | -c (certificate.p12)] [-a (access control file)\n");
fprintf(stderr, "\t-h \t Show this help message\n");
fprintf(stderr, "\t-s \t Use SSL (requires -c option)\n");
fprintf(stderr, "\t-c \t SSL certificate path encoded as pkcs12\n");
fprintf(stderr, "\t-a \t Optional access control file\n");
fprintf(stderr, "\t-p \t Specify port number (default: 5738)\n");
}
BOOL acquireCredentials(bool encrypted, const char *accessFile, NSString **out_username, NSString **out_password)
{
BOOL success = NO;
NSString *asString = nil;
NSError *launchError = nil;
NSString *accessFilePath = [NSString stringWithUTF8String:accessFile];
if (encrypted) {
NSPipe *stdoutPipe = [NSPipe pipe];
NSPipe *stderrPipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/local/bin/gpg";
task.arguments = @[ @"-q", @"-d", accessFilePath ];
task.standardOutput = stdoutPipe;
task.standardError = stderrPipe;
success = [task launchAndReturnError:&launchError];
[task waitUntilExit];
if (success) {
NSFileHandle *stdoutFile = stdoutPipe.fileHandleForReading;
NSData *data = [stdoutFile readDataToEndOfFile]; // blocks
[stdoutFile closeFile];
if ([task terminationStatus] != 0) {
NSData *stderrData = [[stderrPipe fileHandleForReading] readDataToEndOfFile];
MBIMLogFatal(@"GPG error when decrypting access file: %@", [[NSString alloc] initWithData:stderrData encoding:NSUTF8StringEncoding]);
return NO;
}
asString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
} else {
NSError *fileReadError = nil;
asString = [NSString stringWithContentsOfFile:accessFilePath
encoding:NSASCIIStringEncoding
error:&fileReadError];
if (fileReadError != nil) {
MBIMLogFatal(@"File open error when opening access file: %@", fileReadError.localizedDescription);
return NO;
}
success = (asString.length > 0);
}
if (success) {
NSScanner *scanner = [NSScanner scannerWithString:asString];
BOOL scannerSuccess = NO;
NSString *username = nil;
scannerSuccess = [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:&username];
if (!scannerSuccess) {
MBIMLogFatal(@"Error parsing username from access file");
return NO;
}
NSString *password = nil;
scannerSuccess = [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:&password];
if (!scannerSuccess) {
MBIMLogFatal(@"Error parsing password from access file");
return NO;
}
if ([username length] && [password length]) {
*out_username = username;
*out_password = password;
} else {
MBIMLogFatal(@"Error parsing username or password from access file");
return NO;
}
} else {
MBIMLogFatal(@"Unable to launch GPG executable to decrypt access file: %@", [launchError localizedDescription]);
return NO;
}
return YES;
}
int main(int argc, char *const argv[]) {
@autoreleasepool {
BOOL usesSSL = NO;
BOOL showHelp = NO;
BOOL usesAccessControl = NO;
long portNumber = -1;
const char *certPath = NULL;
const char *accessFilePath = NULL;
int c = -1;
while ( (c = getopt(argc, argv, "hsc:a:p:")) != -1 ) {
switch (c) {
case 's':
usesSSL = YES;
break;
case 'c':
certPath = optarg;
break;
case 'a':
usesAccessControl = YES;
accessFilePath = optarg;
break;
case 'p':
portNumber = strtol(optarg, NULL, 10);
break;
case 'h':
showHelp = YES;
break;
case '?':
if (optopt == 'c') {
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
} else if (isprint(optopt)) {
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
} else {
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
return 1;
}
default:
abort ();
}
}
if (showHelp) {
printUsage();
return 1;
}
if (usesSSL && certPath == NULL) {
fprintf(stderr, "Error: wants SSL (-s) but no ssl certificate path (-c) provided\n");
return 1;
}
MBIMBridge *bridge = [MBIMBridge sharedInstance];
if (usesAccessControl) {
NSString *username = nil;
NSString *password = nil;
BOOL success = acquireCredentials(false, accessFilePath, &username, &password);
if (!success) {
MBIMLogInfo(
@"Access file must be a GPG encrypted file (encrypted with your private key, to your pub key) "
"with the follwing format: \n"
"(username)\n"
"(password)"
);
return 1;
} else {
const ssize_t ast_len = 55;
const unichar asterisks[ast_len] = u"*******************************************************";
NSString *obscuredPassword = [NSString stringWithCharacters:asterisks
length:MIN([password length], ast_len)];
MBIMLogNotify(@"Using access control credentials: username(%@) password(%@)", username, obscuredPassword);
bridge.usesAccessControl = YES;
bridge.authUsername = username;
bridge.authPassword = password;
}
}
if (usesSSL && certPath != NULL) {
bridge.usesSSL = YES;
bridge.sslCertPath = [NSString stringWithCString:certPath encoding:NSASCIIStringEncoding];
}
if (portNumber > 0) {
bridge.port = portNumber;
}
[bridge connect];
BOOL running = YES;
while (running) {
[[NSRunLoop currentRunLoop] run];
}
}
return 0;
}