mirror of https://github.com/cy384/ssheven.git
save and load preferences
This commit is contained in:
parent
e97e30d3fc
commit
7b2112f107
|
@ -70,6 +70,23 @@ void check_cursor(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert Quickdraw colors into vterm's ANSI color indexes
|
||||||
|
int qd2idx(int qdc)
|
||||||
|
{
|
||||||
|
switch (qdc)
|
||||||
|
{
|
||||||
|
case blackColor: return 0;
|
||||||
|
case redColor: return 1;
|
||||||
|
case greenColor: return 2;
|
||||||
|
case yellowColor: return 3;
|
||||||
|
case blueColor: return 4;
|
||||||
|
case magentaColor: return 5;
|
||||||
|
case cyanColor: return 6;
|
||||||
|
case whiteColor: return 7;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convert vterm's ANSI color indexes into Quickdraw colors
|
// convert vterm's ANSI color indexes into Quickdraw colors
|
||||||
inline int idx2qd(VTermColor c)
|
inline int idx2qd(VTermColor c)
|
||||||
{
|
{
|
||||||
|
@ -142,8 +159,8 @@ void draw_screen(Rect* r)
|
||||||
TextFont(kFontIDMonaco);
|
TextFont(kFontIDMonaco);
|
||||||
TextSize(9);
|
TextSize(9);
|
||||||
TextFace(normal);
|
TextFace(normal);
|
||||||
qd.thePort->bkColor = whiteColor;
|
qd.thePort->bkColor = prefs.bg_color;
|
||||||
qd.thePort->fgColor = blackColor;
|
qd.thePort->fgColor = prefs.fg_color;
|
||||||
|
|
||||||
EraseRect(r);
|
EraseRect(r);
|
||||||
|
|
||||||
|
@ -443,10 +460,10 @@ void console_setup(void)
|
||||||
vterm_state_reset(vtermstate, 1);
|
vterm_state_reset(vtermstate, 1);
|
||||||
|
|
||||||
VTermColor fg = { .type = VTERM_COLOR_INDEXED };
|
VTermColor fg = { .type = VTERM_COLOR_INDEXED };
|
||||||
fg.indexed.idx = 0; // ANSI black
|
fg.indexed.idx = qd2idx(prefs.fg_color);
|
||||||
|
|
||||||
VTermColor bg = { .type = VTERM_COLOR_INDEXED };
|
VTermColor bg = { .type = VTERM_COLOR_INDEXED };
|
||||||
bg.indexed.idx = 7; // ANSI white
|
bg.indexed.idx = qd2idx(prefs.bg_color);
|
||||||
|
|
||||||
vterm_state_set_default_colors(vtermstate, &fg, &bg);
|
vterm_state_set_default_colors(vtermstate, &fg, &bg);
|
||||||
|
|
||||||
|
|
347
ssheven.c
347
ssheven.c
|
@ -18,19 +18,170 @@
|
||||||
// sinful globals
|
// sinful globals
|
||||||
struct ssheven_console con = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 1, NULL, NULL };
|
struct ssheven_console con = { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 1, NULL, NULL };
|
||||||
struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
|
struct ssheven_ssh_connection ssh_con = { NULL, NULL, kOTInvalidEndpointRef, NULL, NULL };
|
||||||
|
struct preferences prefs;
|
||||||
|
|
||||||
enum { WAIT, READ, EXIT } read_thread_command = WAIT;
|
enum { WAIT, READ, EXIT } read_thread_command = WAIT;
|
||||||
enum { UNINTIALIZED, OPEN, CLEANUP, DONE } read_thread_state = UNINTIALIZED;
|
enum { UNINTIALIZED, OPEN, CLEANUP, DONE } read_thread_state = UNINTIALIZED;
|
||||||
enum { KEY_LOGIN, PASSWORD_LOGIN } login_type = PASSWORD_LOGIN;
|
|
||||||
|
|
||||||
// pascal strings
|
int save_prefs(void)
|
||||||
char hostname[512] = {0};
|
{
|
||||||
char username[256] = {0};
|
int ok = 1;
|
||||||
char password[256] = {0};
|
short foundVRefNum = 0;
|
||||||
|
long foundDirID = 0;
|
||||||
|
FSSpec pref_file;
|
||||||
|
//int create_new = 0;
|
||||||
|
short prefRefNum = 0;
|
||||||
|
|
||||||
// malloc'd c strings
|
OSType pref_type = 'SH7p';
|
||||||
char* pubkey_path = NULL;
|
OSType creator_type = 'SSH7';
|
||||||
char* privkey_path = NULL;
|
|
||||||
|
// find the preferences folder on the system disk, create folder if needed
|
||||||
|
OSErr e = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &foundVRefNum, &foundDirID);
|
||||||
|
if (e != noErr) ok = 0;
|
||||||
|
|
||||||
|
// make an FSSpec for the new file we want to make
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
e = FSMakeFSSpec(foundVRefNum, foundDirID, PREFERENCES_FILENAME, &pref_file);
|
||||||
|
if (e == fnfErr) // file doesn't exist, but is a valid path
|
||||||
|
{
|
||||||
|
// so make the file
|
||||||
|
e = FSpCreate(&pref_file, creator_type, pref_type, smSystemScript);
|
||||||
|
if (e != noErr) ok = 0;
|
||||||
|
}
|
||||||
|
else if (e != noErr) ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open the file
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
e = FSpOpenDF(&pref_file, fsRdWrPerm, &prefRefNum);
|
||||||
|
if (e != noErr) ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write prefs to the file
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
// TODO: choose buffer size more effectively
|
||||||
|
size_t write_length = 8192;
|
||||||
|
|
||||||
|
char* output_buffer = malloc(write_length);
|
||||||
|
memset(output_buffer, 0, write_length);
|
||||||
|
|
||||||
|
long int i = snprintf(output_buffer, write_length, "%d\n%d\n", prefs.major_version, prefs.minor_version);
|
||||||
|
i += snprintf(output_buffer+i, write_length-i, "%d\n%d\n%d\n%d\n", (int)prefs.auth_type, (int)prefs.display_mode, (int)prefs.fg_color, (int)prefs.bg_color);
|
||||||
|
|
||||||
|
snprintf(output_buffer+i, prefs.hostname[0]+1, "%s", prefs.hostname+1); i += prefs.hostname[0];
|
||||||
|
i += snprintf(output_buffer+i, write_length-i, "\n");
|
||||||
|
|
||||||
|
snprintf(output_buffer+i, prefs.username[0]+1, "%s", prefs.username+1); i += prefs.username[0];
|
||||||
|
i += snprintf(output_buffer+i, write_length-i, "\n");
|
||||||
|
|
||||||
|
snprintf(output_buffer+i, prefs.port[0]+1, "%s", prefs.port+1); i += prefs.port[0];
|
||||||
|
i += snprintf(output_buffer+i, write_length-i, "\n");
|
||||||
|
|
||||||
|
i += snprintf(output_buffer+i, write_length-i, "%s\n%s\n", prefs.privkey_path, prefs.pubkey_path);
|
||||||
|
|
||||||
|
// tell it to write all bytes
|
||||||
|
long int bytes = i;
|
||||||
|
e = FSWrite(prefRefNum, &bytes, output_buffer);
|
||||||
|
// FSWrite sets bytes to the actual number of bytes written
|
||||||
|
|
||||||
|
if (e != noErr || (bytes != i)) ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the file
|
||||||
|
if (prefRefNum != 0)
|
||||||
|
{
|
||||||
|
e = FSClose(prefRefNum);
|
||||||
|
if (e != noErr) ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_prefs(void)
|
||||||
|
{
|
||||||
|
// initialize everything to a safe default
|
||||||
|
prefs.major_version = SSHEVEN_VERSION_MAJOR;
|
||||||
|
prefs.minor_version = SSHEVEN_VERSION_MINOR;
|
||||||
|
|
||||||
|
memset(&(prefs.hostname), 0, 512);
|
||||||
|
memset(&(prefs.username), 0, 256);
|
||||||
|
memset(&(prefs.password), 0, 256);
|
||||||
|
memset(&(prefs.port), 0, 256);
|
||||||
|
|
||||||
|
// default port: 22
|
||||||
|
prefs.port[0] = 2;
|
||||||
|
prefs.port[1] = '2';
|
||||||
|
prefs.port[2] = '2';
|
||||||
|
|
||||||
|
prefs.pubkey_path = "";
|
||||||
|
prefs.privkey_path = "";
|
||||||
|
prefs.terminal_string = SSHEVEN_TERMINAL_TYPE;
|
||||||
|
prefs.auth_type = USE_PASSWORD;
|
||||||
|
prefs.display_mode = COLOR;
|
||||||
|
prefs.fg_color = blackColor;
|
||||||
|
prefs.bg_color = whiteColor;
|
||||||
|
|
||||||
|
prefs.loaded_from_file = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_prefs(void)
|
||||||
|
{
|
||||||
|
// now try to load preferences from the file
|
||||||
|
short foundVRefNum = 0;
|
||||||
|
long foundDirID = 0;
|
||||||
|
FSSpec pref_file;
|
||||||
|
short prefRefNum = 0;
|
||||||
|
|
||||||
|
// find the preferences folder on the system disk
|
||||||
|
OSErr e = FindFolder(kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder, &foundVRefNum, &foundDirID);
|
||||||
|
if (e != noErr) return;
|
||||||
|
|
||||||
|
// make an FSSpec for the preferences file location and check if it exists
|
||||||
|
// TODO: if I just put PREFERENCES_FILENAME it doesn't work, wtf
|
||||||
|
e = FSMakeFSSpec(foundVRefNum, foundDirID, "\pssheven Preferences", &pref_file);
|
||||||
|
|
||||||
|
if (e == fnfErr) // file not found, nothing to load
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (e != noErr) return;
|
||||||
|
|
||||||
|
e = FSpOpenDF(&pref_file, fsCurPerm, &prefRefNum);
|
||||||
|
if (e != noErr) return;
|
||||||
|
|
||||||
|
// actually read and parse the file
|
||||||
|
long int buffer_size = 8192;
|
||||||
|
char* buffer = NULL;
|
||||||
|
buffer = malloc(buffer_size);
|
||||||
|
prefs.privkey_path = malloc(2048);
|
||||||
|
prefs.pubkey_path = malloc(2048);
|
||||||
|
prefs.pubkey_path[0] = '\0';
|
||||||
|
prefs.privkey_path[0] = '\0';
|
||||||
|
|
||||||
|
e = FSRead(prefRefNum, &buffer_size, buffer);
|
||||||
|
e = FSClose(prefRefNum);
|
||||||
|
|
||||||
|
// check the version (first two numbers)
|
||||||
|
int items_got = sscanf(buffer, "%d\n%d", &prefs.major_version, &prefs.minor_version);
|
||||||
|
if (items_got != 2) return;
|
||||||
|
|
||||||
|
// only load a prefs file if the saved version number matches ours
|
||||||
|
if ((prefs.major_version == SSHEVEN_VERSION_MAJOR) && (prefs.minor_version == SSHEVEN_VERSION_MINOR))
|
||||||
|
{
|
||||||
|
prefs.loaded_from_file = 1;
|
||||||
|
items_got = sscanf(buffer, "%d\n%d\n%d\n%d\n%d\n%d\n%255[^\n]\n%255[^\n]\n%255[^\n]\n%[^\n]\n%[^\n]", &prefs.major_version, &prefs.minor_version, (int*)&prefs.auth_type, (int*)&prefs.display_mode, &prefs.fg_color, &prefs.bg_color, prefs.hostname+1, prefs.username+1, prefs.port+1, prefs.privkey_path, prefs.pubkey_path);
|
||||||
|
|
||||||
|
// add the size for the pascal strings
|
||||||
|
prefs.hostname[0] = (unsigned char)strlen(prefs.hostname+1);
|
||||||
|
prefs.username[0] = (unsigned char)strlen(prefs.username+1);
|
||||||
|
prefs.port[0] = (unsigned char)strlen(prefs.port+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer) free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
// borrowed from Retro68 sample code
|
// borrowed from Retro68 sample code
|
||||||
// draws the "default" indicator around a button
|
// draws the "default" indicator around a button
|
||||||
|
@ -470,7 +621,7 @@ int ssh_setup_terminal(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
SSH_CHECK(libssh2_channel_request_pty_ex(ssh_con.channel, SSHEVEN_TERMINAL_TYPE, (strlen(SSHEVEN_TERMINAL_TYPE)), NULL, 0, con.size_x, con.size_y, 0, 0));
|
SSH_CHECK(libssh2_channel_request_pty_ex(ssh_con.channel, prefs.terminal_string, (strlen(prefs.terminal_string)), NULL, 0, con.size_x, con.size_y, 0, 0));
|
||||||
SSH_CHECK(libssh2_channel_shell(ssh_con.channel));
|
SSH_CHECK(libssh2_channel_shell(ssh_con.channel));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -572,8 +723,8 @@ int password_dialog(int dialog_resource)
|
||||||
|
|
||||||
// read out of the hidden text box
|
// read out of the hidden text box
|
||||||
GetDialogItem(dlog, 5, &type, &itemH, &box);
|
GetDialogItem(dlog, 5, &type, &itemH, &box);
|
||||||
GetDialogItemText(itemH, (unsigned char*)password);
|
GetDialogItemText(itemH, (unsigned char*)prefs.password);
|
||||||
login_type = PASSWORD_LOGIN;
|
prefs.auth_type = USE_PASSWORD;
|
||||||
|
|
||||||
DisposeDialog(dlog);
|
DisposeDialog(dlog);
|
||||||
|
|
||||||
|
@ -689,41 +840,47 @@ int key_dialog(void)
|
||||||
Handle full_path = NULL;
|
Handle full_path = NULL;
|
||||||
int path_length = 0;
|
int path_length = 0;
|
||||||
|
|
||||||
// get public key path
|
// if we don't have a saved pubkey path, ask for one
|
||||||
NoteAlert(ALRT_PUBKEY, nil);
|
if (prefs.pubkey_path == NULL || prefs.pubkey_path[0] == '\0')
|
||||||
StandardFileReply pubkey;
|
{
|
||||||
StandardGetFile(NULL, 0, NULL, &pubkey);
|
NoteAlert(ALRT_PUBKEY, nil);
|
||||||
FSpPathFromLocation(&pubkey.sfFile, &path_length, &full_path);
|
StandardFileReply pubkey;
|
||||||
pubkey_path = malloc(path_length+1);
|
StandardGetFile(NULL, 0, NULL, &pubkey);
|
||||||
strncpy(pubkey_path, (char*)(*full_path), path_length+1);
|
FSpPathFromLocation(&pubkey.sfFile, &path_length, &full_path);
|
||||||
DisposeHandle(full_path);
|
prefs.pubkey_path = malloc(path_length+1);
|
||||||
|
strncpy(prefs.pubkey_path, (char*)(*full_path), path_length+1);
|
||||||
|
DisposeHandle(full_path);
|
||||||
|
|
||||||
|
// if the user hit cancel, 0
|
||||||
|
if (!pubkey.sfGood) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
path_length = 0;
|
path_length = 0;
|
||||||
full_path = NULL;
|
full_path = NULL;
|
||||||
|
|
||||||
// if the user hit cancel, 0
|
// if we don't have a saved privkey path, ask for one
|
||||||
if (!pubkey.sfGood) return 0;
|
if (prefs.privkey_path == NULL || prefs.privkey_path[0] == '\0')
|
||||||
|
{
|
||||||
|
NoteAlert(ALRT_PRIVKEY, nil);
|
||||||
|
StandardFileReply privkey;
|
||||||
|
StandardGetFile(NULL, 0, NULL, &privkey);
|
||||||
|
FSpPathFromLocation(&privkey.sfFile, &path_length, &full_path);
|
||||||
|
prefs.privkey_path = malloc(path_length+1);
|
||||||
|
strncpy(prefs.privkey_path, (char*)(*full_path), path_length+1);
|
||||||
|
DisposeHandle(full_path);
|
||||||
|
|
||||||
// get private key path
|
// if the user hit cancel, 0
|
||||||
NoteAlert(ALRT_PRIVKEY, nil);
|
if (!privkey.sfGood) return 0;
|
||||||
StandardFileReply privkey;
|
}
|
||||||
StandardGetFile(NULL, 0, NULL, &privkey);
|
|
||||||
FSpPathFromLocation(&privkey.sfFile, &path_length, &full_path);
|
|
||||||
privkey_path = malloc(path_length+1);
|
|
||||||
strncpy(privkey_path, (char*)(*full_path), path_length+1);
|
|
||||||
DisposeHandle(full_path);
|
|
||||||
|
|
||||||
// if the user hit cancel, 0
|
|
||||||
if (!privkey.sfGood) return 0;
|
|
||||||
|
|
||||||
// get the key decryption password
|
// get the key decryption password
|
||||||
if (!password_dialog(DLOG_KEY_PASSWORD)) return 0;
|
if (!password_dialog(DLOG_KEY_PASSWORD)) return 0;
|
||||||
|
|
||||||
login_type = KEY_LOGIN;
|
prefs.auth_type = USE_KEY;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int intro_dialog(char* hostname, char* username, char* password)
|
int intro_dialog(void)
|
||||||
{
|
{
|
||||||
// modal dialog setup
|
// modal dialog setup
|
||||||
TEInit();
|
TEInit();
|
||||||
|
@ -742,29 +899,42 @@ int intro_dialog(char* hostname, char* username, char* password)
|
||||||
GetDialogItem(dlg, 2, &type, &itemH, &box);
|
GetDialogItem(dlg, 2, &type, &itemH, &box);
|
||||||
SetDialogItem(dlg, 2, type, (Handle)NewUserItemUPP(&ButtonFrameProc), &box);
|
SetDialogItem(dlg, 2, type, (Handle)NewUserItemUPP(&ButtonFrameProc), &box);
|
||||||
|
|
||||||
// get the handles for each of the text boxes
|
// get the handles for each of the text boxes, and load preference data in
|
||||||
ControlHandle address_text_box;
|
ControlHandle address_text_box;
|
||||||
GetDialogItem(dlg, 4, &type, &itemH, &box);
|
GetDialogItem(dlg, 4, &type, &itemH, &box);
|
||||||
address_text_box = (ControlHandle)itemH;
|
address_text_box = (ControlHandle)itemH;
|
||||||
|
SetDialogItemText((Handle)address_text_box, (ConstStr255Param)prefs.hostname);
|
||||||
|
|
||||||
ControlHandle port_text_box;
|
ControlHandle port_text_box;
|
||||||
GetDialogItem(dlg, 5, &type, &itemH, &box);
|
GetDialogItem(dlg, 5, &type, &itemH, &box);
|
||||||
port_text_box = (ControlHandle)itemH;
|
port_text_box = (ControlHandle)itemH;
|
||||||
|
SetDialogItemText((Handle)port_text_box, (ConstStr255Param)prefs.port);
|
||||||
|
|
||||||
ControlHandle username_text_box;
|
ControlHandle username_text_box;
|
||||||
GetDialogItem(dlg, 7, &type, &itemH, &box);
|
GetDialogItem(dlg, 7, &type, &itemH, &box);
|
||||||
username_text_box = (ControlHandle)itemH;
|
username_text_box = (ControlHandle)itemH;
|
||||||
|
SetDialogItemText((Handle)username_text_box, (ConstStr255Param)prefs.username);
|
||||||
|
|
||||||
ControlHandle password_radio;
|
ControlHandle password_radio;
|
||||||
GetDialogItem(dlg, 9, &type, &itemH, &box);
|
GetDialogItem(dlg, 9, &type, &itemH, &box);
|
||||||
password_radio = (ControlHandle)itemH;
|
password_radio = (ControlHandle)itemH;
|
||||||
SetControlValue(password_radio, 1);
|
SetControlValue(password_radio, 0);
|
||||||
|
|
||||||
ControlHandle key_radio;
|
ControlHandle key_radio;
|
||||||
GetDialogItem(dlg, 10, &type, &itemH, &box);
|
GetDialogItem(dlg, 10, &type, &itemH, &box);
|
||||||
key_radio = (ControlHandle)itemH;
|
key_radio = (ControlHandle)itemH;
|
||||||
SetControlValue(key_radio, 0);
|
SetControlValue(key_radio, 0);
|
||||||
|
|
||||||
|
// recall last-used connection type
|
||||||
|
if (prefs.auth_type == USE_PASSWORD)
|
||||||
|
{
|
||||||
|
SetControlValue(password_radio, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetControlValue(key_radio, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// let the modalmanager do everything
|
// let the modalmanager do everything
|
||||||
// stop when the connect button is hit
|
// stop when the connect button is hit
|
||||||
short item;
|
short item;
|
||||||
|
@ -783,12 +953,15 @@ int intro_dialog(char* hostname, char* username, char* password)
|
||||||
} while(item != 1 && item != 8);
|
} while(item != 1 && item != 8);
|
||||||
|
|
||||||
// copy the text out of the boxes
|
// copy the text out of the boxes
|
||||||
GetDialogItemText((Handle)address_text_box, (unsigned char *)hostname);
|
GetDialogItemText((Handle)address_text_box, (unsigned char *)prefs.hostname);
|
||||||
GetDialogItemText((Handle)username_text_box, (unsigned char *)username);
|
GetDialogItemText((Handle)username_text_box, (unsigned char *)prefs.username);
|
||||||
|
|
||||||
// splice the port number onto the hostname (n.b. they're pascal strings)
|
GetDialogItemText((Handle)port_text_box, (unsigned char *)prefs.hostname+prefs.hostname[0]+1);
|
||||||
GetDialogItemText((Handle)port_text_box, (unsigned char *)hostname+hostname[0]+1);
|
prefs.hostname[prefs.hostname[0]+1] = ':';
|
||||||
hostname[hostname[0]+1] = ':';
|
|
||||||
|
char* port_start = prefs.hostname+prefs.hostname[0] + 2;
|
||||||
|
prefs.port[0] = strlen(port_start);
|
||||||
|
strncpy(prefs.port+1, port_start, 255);
|
||||||
|
|
||||||
int use_password = GetControlValue(password_radio);
|
int use_password = GetControlValue(password_radio);
|
||||||
|
|
||||||
|
@ -823,25 +996,25 @@ void* read_thread(void* arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect and log in
|
// connect and log in
|
||||||
ok = init_connection(hostname+1);
|
ok = init_connection(prefs.hostname+1);
|
||||||
YieldToAnyThread();
|
YieldToAnyThread();
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
printf_i("Authenticating... "); YieldToAnyThread();
|
printf_i("Authenticating... "); YieldToAnyThread();
|
||||||
|
|
||||||
if (login_type == PASSWORD_LOGIN)
|
if (prefs.auth_type == USE_PASSWORD)
|
||||||
{
|
{
|
||||||
rc = libssh2_userauth_password(ssh_con.session, username+1, password+1);
|
rc = libssh2_userauth_password(ssh_con.session, prefs.username+1, prefs.password+1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = libssh2_userauth_publickey_fromfile_ex(ssh_con.session,
|
rc = libssh2_userauth_publickey_fromfile_ex(ssh_con.session,
|
||||||
username+1,
|
prefs.username+1,
|
||||||
username[0],
|
prefs.username[0],
|
||||||
pubkey_path,
|
prefs.pubkey_path,
|
||||||
privkey_path,
|
prefs.privkey_path,
|
||||||
password+1);
|
prefs.password+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == LIBSSH2_ERROR_NONE)
|
if (rc == LIBSSH2_ERROR_NONE)
|
||||||
|
@ -850,13 +1023,20 @@ void* read_thread(void* arg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED && login_type == PASSWORD_LOGIN) StopAlert(ALRT_PW_FAIL, nil);
|
if (rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED && prefs.auth_type == USE_PASSWORD) StopAlert(ALRT_PW_FAIL, nil);
|
||||||
if (rc == LIBSSH2_ERROR_FILE) StopAlert(ALRT_FILE_FAIL, nil);
|
else if (rc == LIBSSH2_ERROR_FILE) StopAlert(ALRT_FILE_FAIL, nil);
|
||||||
printf_i("failure: %s\r\n", libssh2_error_string(rc));
|
else if (rc == LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED)
|
||||||
|
{
|
||||||
|
printf_i("Invalid key files!\r\n"); // TODO: have an alert for this
|
||||||
|
}
|
||||||
|
else printf_i("failure: %s\r\n", libssh2_error_string(rc));
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we logged in, save the connection preferences, since we know they're ok
|
||||||
|
if (ok) save_prefs();
|
||||||
|
|
||||||
// if we logged in, open and set up the tty
|
// if we logged in, open and set up the tty
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
|
@ -994,48 +1174,6 @@ int safety_checks(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_preferences(void)
|
|
||||||
{
|
|
||||||
int ok = 1;
|
|
||||||
short foundVRefNum = 0;
|
|
||||||
long foundDirID = 0;
|
|
||||||
FSSpec pref_file;
|
|
||||||
int create_new = 0;
|
|
||||||
|
|
||||||
OSType pref_type = 'SH7p';
|
|
||||||
OSType creator_type = 'SSH7';
|
|
||||||
|
|
||||||
// find the preferences folder on the system disk, create folder if needed
|
|
||||||
OSErr e = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &foundVRefNum, &foundDirID);
|
|
||||||
if (e != noErr) ok = 0;
|
|
||||||
|
|
||||||
// make an FSSpec for the new file we want to make
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
e = FSMakeFSSpec(foundVRefNum, foundDirID, PREFERENCES_FILENAME, &pref_file);
|
|
||||||
if (e == fnfErr) // file doesn't exist, but is a valid path
|
|
||||||
{
|
|
||||||
create_new = 1;
|
|
||||||
}
|
|
||||||
else if (e != noErr) ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok && create_new)
|
|
||||||
{
|
|
||||||
e = FSpCreate(&pref_file, creator_type, pref_type, smSystemScript);
|
|
||||||
if (e != noErr) ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: actually save anything
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_preferences(void)
|
|
||||||
{
|
|
||||||
// TODO: actually load anything
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
OSStatus err = noErr;
|
OSStatus err = noErr;
|
||||||
|
@ -1049,7 +1187,9 @@ int main(int argc, char** argv)
|
||||||
MoreMasters();
|
MoreMasters();
|
||||||
MoreMasters();
|
MoreMasters();
|
||||||
|
|
||||||
load_preferences();
|
// set default preferences, then load from preferences file if possible
|
||||||
|
init_prefs();
|
||||||
|
load_prefs();
|
||||||
|
|
||||||
// general gui setup
|
// general gui setup
|
||||||
InitGraf(&qd.thePort);
|
InitGraf(&qd.thePort);
|
||||||
|
@ -1091,6 +1231,15 @@ int main(int argc, char** argv)
|
||||||
printf_i("Running in 68k mode.\r\n");
|
printf_i("Running in 68k mode.\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (prefs.loaded_from_file)
|
||||||
|
{
|
||||||
|
printf_i("Loaded preferences file.\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf_i("Could not load from preferences file.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
BeginUpdate(con.win);
|
BeginUpdate(con.win);
|
||||||
draw_screen(&(con.win->portRect));
|
draw_screen(&(con.win->portRect));
|
||||||
EndUpdate(con.win);
|
EndUpdate(con.win);
|
||||||
|
@ -1103,9 +1252,7 @@ int main(int argc, char** argv)
|
||||||
draw_screen(&(con.win->portRect));
|
draw_screen(&(con.win->portRect));
|
||||||
EndUpdate(con.win);
|
EndUpdate(con.win);
|
||||||
|
|
||||||
ok = intro_dialog(hostname, username, password);
|
ok = intro_dialog();
|
||||||
|
|
||||||
if (ok) save_preferences();
|
|
||||||
|
|
||||||
if (!ok) printf_i("Cancelled, not connecting.\r\n");
|
if (!ok) printf_i("Cancelled, not connecting.\r\n");
|
||||||
|
|
||||||
|
@ -1168,8 +1315,8 @@ int main(int argc, char** argv)
|
||||||
if (ssh_con.recv_buffer != NULL) OTFreeMem(ssh_con.recv_buffer);
|
if (ssh_con.recv_buffer != NULL) OTFreeMem(ssh_con.recv_buffer);
|
||||||
if (ssh_con.send_buffer != NULL) OTFreeMem(ssh_con.send_buffer);
|
if (ssh_con.send_buffer != NULL) OTFreeMem(ssh_con.send_buffer);
|
||||||
|
|
||||||
if (pubkey_path != NULL) free(pubkey_path);
|
if (prefs.pubkey_path != NULL && prefs.pubkey_path[0] != '\0') free(prefs.pubkey_path);
|
||||||
if (privkey_path != NULL) free(privkey_path);
|
if (prefs.privkey_path != NULL && prefs.privkey_path[0] != '\0') free(prefs.privkey_path);
|
||||||
|
|
||||||
if (con.vterm != NULL) vterm_free(con.vterm);
|
if (con.vterm != NULL) vterm_free(con.vterm);
|
||||||
|
|
||||||
|
|
30
ssheven.h
30
ssheven.h
|
@ -36,6 +36,8 @@
|
||||||
#include <vterm.h>
|
#include <vterm.h>
|
||||||
#include <vterm_keycodes.h>
|
#include <vterm_keycodes.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
// sinful globals
|
// sinful globals
|
||||||
struct ssheven_console
|
struct ssheven_console
|
||||||
{
|
{
|
||||||
|
@ -76,3 +78,31 @@ extern struct ssheven_ssh_connection ssh_con;
|
||||||
extern char key_to_vterm[256];
|
extern char key_to_vterm[256];
|
||||||
|
|
||||||
void ssh_write(char* buf, size_t len);
|
void ssh_write(char* buf, size_t len);
|
||||||
|
|
||||||
|
struct preferences
|
||||||
|
{
|
||||||
|
int major_version;
|
||||||
|
int minor_version;
|
||||||
|
|
||||||
|
int loaded_from_file;
|
||||||
|
|
||||||
|
// pascal strings
|
||||||
|
char hostname[512]; // of the form: "hostname:portnumber", size is first only
|
||||||
|
char username[256];
|
||||||
|
char password[256];
|
||||||
|
char port[256];
|
||||||
|
|
||||||
|
// malloc'd c strings
|
||||||
|
char* pubkey_path;
|
||||||
|
char* privkey_path;
|
||||||
|
|
||||||
|
const char* terminal_string;
|
||||||
|
|
||||||
|
enum { USE_KEY, USE_PASSWORD } auth_type;
|
||||||
|
|
||||||
|
enum { FASTEST, MONOCHROME, COLOR } display_mode;
|
||||||
|
int fg_color;
|
||||||
|
int bg_color;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct preferences prefs;
|
||||||
|
|
Loading…
Reference in New Issue