2 * Copyright (c) 2003-2005 Greg Parker. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "vt100/vt100.h"
28 #include "rsrc/rsrc.h"
29 #include "crypto/rand.h"
32 #include "data/connectionlist.h"
33 #include "data/hostkeys.h"
34 #include "data/memolist.h"
35 #include "data/prefs.h"
36 #include "data/publickeys.h"
38 #include "forms/about.h"
39 #include "forms/connectionprefsform.h"
40 #include "forms/detailsform.h"
41 #include "forms/displayprefsform.h"
42 #include "forms/hostkeysform.h"
43 #include "forms/hostkeydetailsform.h"
44 #include "forms/kbdintform.h"
45 #include "forms/kbdint0form.h"
46 #include "forms/keyboardprefsform.h"
47 #include "forms/loginform.h"
48 #include "forms/mainform.h"
49 #include "forms/memoform.h"
50 #include "forms/passwordform.h"
51 #include "forms/passphraseform.h"
52 #include "forms/publickeysform.h"
53 #include "forms/publickeychoiceform.h"
54 #include "forms/publickeydetailsform.h"
55 #include "forms/terminalform.h"
56 #include "forms/DIA.h"
58 #include "crypto/openssl/bn/bn.h"
59 #include "crypto/openssl/md5/md5.h"
65 UInt16 NetLibCount = 0;
66 struct ssh_session_t *ss = NULL;
69 // fixme move to recordlist
70 DmOpenRef OpenDB(UInt32 type, char *name, Boolean resDB, Boolean create)
75 result = DmOpenDatabaseByTypeCreator(type, PSSH_CREATOR, dmModeReadWrite);
76 if (!result && create) {
81 err = DmCreateDatabase(0, name, PSSH_CREATOR, type, resDB);
82 if (err) { complain_int("db 1", err); return 0; }
83 result = DmOpenDatabaseByTypeCreator(type, PSSH_CREATOR, dmModeReadWrite);
84 if (!result) { complain_int("db 2", DmGetLastErr()); return 0; }
87 DmOpenDatabaseInfo(result, &id, NULL, NULL, &card, NULL);
88 DmDatabaseInfo(card, id, NULL, &attr, NULL, NULL, NULL,
89 NULL, NULL, NULL, NULL, NULL, NULL);
90 attr |= dmHdrAttrBackup;
91 DmSetDatabaseInfo(card, id, NULL, &attr, NULL, NULL, NULL,
92 NULL, NULL, NULL, NULL, NULL, NULL);
102 void complain(char *err)
106 WinSetCoordinateSystem(kCoordinatesStandard);
107 FrmCustomAlert(AlertFormID, err, StrIToA(errnobuf, errno), " ");
111 void complain_int(char *err, uint32_t i)
115 WinSetCoordinateSystem(kCoordinatesStandard);
116 FrmCustomAlert(AlertFormID, err, StrIToA(intbuf, i), " ");
121 Boolean ApplicationHandleEvent(EventPtr e)
123 if (e->eType == frmLoadEvent) {
124 UInt16 formId = e->data.frmLoad.formID;
125 FormPtr frmP = FrmInitForm(formId);
126 FrmSetActiveForm(frmP);
130 SetResizePolicy(formId);
131 SetResizeCallback(formId, MainFormResize);
132 FrmSetEventHandler(frmP, MainFormHandleEvent);
135 SetResizePolicy(formId);
136 FrmSetEventHandler(frmP, DetailsFormHandleEvent);
139 SetResizePolicy(formId);
140 FrmSetEventHandler(frmP, LoginFormHandleEvent);
143 SetResizePolicy(formId);
144 FrmSetEventHandler(frmP, PasswordFormHandleEvent);
147 SetResizePolicy(formId);
148 SetResizeCallback(formId, TerminalFormResize);
149 FrmSetEventHandler(frmP, TerminalFormHandleEvent);
152 SetResizePolicy(formId);
153 SetResizeCallback(formId, HostKeysFormResize);
154 FrmSetEventHandler(frmP, HostKeysFormHandleEvent);
156 case HostKeyDetailsFormID:
157 SetResizePolicy(formId);
158 FrmSetEventHandler(frmP, HostKeyDetailsFormHandleEvent);
161 SetResizePolicy(formId);
162 FrmSetEventHandler(frmP, AboutFormHandleEvent);
165 SetResizePolicy(formId);
166 FrmSetEventHandler(frmP, CreditsFormHandleEvent);
168 case DisplayPrefsFormID:
169 SetResizePolicy(formId);
170 FrmSetEventHandler(frmP, DisplayPrefsFormHandleEvent);
172 case ConnectionPrefsFormID:
173 SetResizePolicy(formId);
174 FrmSetEventHandler(frmP, ConnectionPrefsFormHandleEvent);
176 case KeyboardPrefsFormID:
177 SetResizePolicy(formId);
178 FrmSetEventHandler(frmP, KeyboardPrefsFormHandleEvent);
181 SetResizePolicy(formId);
182 SetResizeCallback(formId, MemoFormResize);
183 FrmSetEventHandler(frmP, MemoFormHandleEvent);
185 case PublicKeysFormID:
186 SetResizePolicy(formId);
187 SetResizeCallback(formId, PublicKeysFormResize);
188 FrmSetEventHandler(frmP, PublicKeysFormHandleEvent);
190 case PublicKeyDetailsFormID:
191 SetResizePolicy(formId);
192 FrmSetEventHandler(frmP, PublicKeyDetailsFormHandleEvent);
194 case PassphraseFormID:
195 SetResizePolicy(formId);
196 FrmSetEventHandler(frmP, PasswordFormHandleEvent);
198 case PublicKeyChoiceFormID:
199 SetResizePolicy(formId);
200 FrmSetEventHandler(frmP, PublicKeyChoiceFormHandleEvent);
203 SetResizePolicy(formId);
204 FrmSetEventHandler(frmP, KbdIntFormHandleEvent);
207 SetResizePolicy(formId);
208 FrmSetEventHandler(frmP, KbdInt0FormHandleEvent);
211 SetResizePolicy(formId);
212 FrmSetEventHandler(frmP, BannerFormHandleEvent);
224 static Boolean RomVersionCompatible (UInt32 requiredVersion)
228 // See if we're on in minimum required version of the ROM or later.
229 // The system records the version number in a feature. A feature is a
230 // piece of information which can be looked up by a creator and feature
232 FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
233 return (romVersion >= requiredVersion);
237 static Boolean CPUIsARM(void)
240 FtrGet(sysFtrCreator, sysFtrNumProcessorID, &cpu);
241 return sysFtrNumProcessorIsARM(cpu);
244 static void StartupError(char *msg, UInt16 launchFlags)
247 FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
249 // If the user launched the app from the launcher, explain
250 // why the app shouldn't run. If the app was contacted for something
251 // else, like it was asked to find a string by the system find, then
252 // don't bother the user with a warning dialog. These flags tell how
253 // the app was launched to decided if a warning should be displayed.
254 if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
255 (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
259 // Pilot 1.0 will continuously relaunch this app unless we switch to
260 // another safe one. The sysFileCDefaultApp is considered "safe".
261 if (romVersion < 0x02000000)
263 AppLaunchWithCommand(sysFileCDefaultApp,
264 sysAppLaunchCmdNormalLaunch, NULL);
270 static Boolean NetLibAvailable(void)
275 err = FtrGet(netFtrCreator, netFtrNumVersion, &version);
276 if (err) return false;
277 // any NetLib version is OK
279 err = SysLibFind("Net.lib", &AppNetRefnum);
280 if (err) return false;
286 UInt32 PilotMain(UInt16 cmd, void *cmdPBP, UInt16 launchFlags)
291 UInt32 tenth = SysTicksPerSecond() / 10;
292 UInt32 lastUpdate = 0;
295 if (cmd == sysAppLaunchCmdNotify) {
296 HandleResizeNotification(((SysNotifyParamType *)cmdPBP)->notifyType);
299 // we don't handle search et al.
300 if (cmd != sysAppLaunchCmdNormalLaunch) return 0;
303 // fixme unless better bnlib is written
305 StartupError("pssh requires an ARM processor", launchFlags);
309 // ROM version 3.5+ required
310 // fixme this should always pass given ARM
311 if (!RomVersionCompatible(sysMakeROMVersion(3,5,0,0,0))) {
312 StartupError("pssh requires ROM version 3.5 or later", launchFlags);
316 // NetLib required (any version)
317 if (!NetLibAvailable()) {
318 StartupError("pssh requires NetLib", launchFlags);
323 StartupError("Couldn't load ARM code", launchFlags);
327 if (!ConnectionListInit()) {
328 StartupError("Couldn't open connection list", launchFlags);
332 if (!HostKeysInit()) {
333 StartupError("Couldn't open known host key list", launchFlags);
337 if (!PublicKeysInit()) {
338 StartupError("Couldn't open public key list", launchFlags);
343 StartupError("Couldn't open preferences", launchFlags);
351 err = FtrGet(PSSH_CREATOR, ftrSecurityWarning, &warned);
354 FrmCustomAlert(AlertFormID, "WARNING: pssh is substantially UNTESTED and probably INSECURE. Do not use for security-critical applications.", " ", " ");
356 FtrSet(PSSH_CREATOR, ftrSecurityWarning, warned);
360 // init virtual Graffiti area API, if any
361 InitializeResizeSupport(ResizeDataID);
362 LoadResizePrefs(PSSH_CREATOR, ResizeDataID);
368 // fixme quickie dynamic heap check
373 heapID = MemHeapID(0, 0);
374 MemHeapFreeBytes(heapID, &free, &max);
375 size = MemHeapSize(heapID);
376 complain_int("dynamic heap size ", size);
377 complain_int("dynamic heap free ", free);
378 complain_int("dynamic heap max chunk ", max);
386 #define DEFINEFONT(f) \
387 fontH = DmGetResource(fontExtRscType, f); \
388 fontP = MemHandleLock(fontH); \
389 FntDefineFont((FontID)f, fontP);
391 DEFINEFONT(NanoFontSingleID);
392 DEFINEFONT(NanoFontDoubleID);
393 DEFINEFONT(MediumFontSingleID);
394 DEFINEFONT(MediumFontDoubleID);
395 DEFINEFONT(PasswordFontID);
400 // 10 second timeout for DNS and connect()
401 AppNetTimeout = SysTicksPerSecond() * 10;
403 FrmGotoForm(MainFormID);
409 if (ss && !ssh_is_closed(ss)) {
417 FD_SET(STDIN_FILENO, &rfds);
419 ssfd = ssh_request_select(ss, &rfds, NULL);
420 maxfd = MAX(STDIN_FILENO, ssfd);
422 // Don't block in select() if there are events in the event queue.
423 // fixme even if there are no events, keep block time short
424 // because of stuck-in-select problem
425 if (EvtEventAvail()) {
429 tv.tv_usec = 100000L; // 1/10 sec
433 selected = select(maxfd + 1, &rfds, NULL, NULL, &tv);
436 if (FD_ISSET(ssfd, &rfds)) {
438 e.eType = usrNetEvent;
439 EvtAddUniqueEventToQueue(&e, 0, true);
443 delay = 0; // DON'T block in EvtGetEvent
445 // No sockets to select() yet
446 delay = -1; // DO block in EvtGetEvent (forever)
454 EvtGetEvent(&event, delay);
456 if (event.eType == usrNetEvent) {
457 // Handle incoming network data
458 if (ss && !ssh_is_closed(ss)) {
463 if (TerminalFormStealEvent(&event)) {
464 FrmDispatchEvent(&event);
466 if (!SysHandleEvent(&event)) {
467 if (!MenuHandleEvent(NULL, &event, &err)) {
468 if (!ApplicationHandleEvent(&event)) {
469 FrmDispatchEvent(&event);
477 if (now >= lastUpdate + tenth) {
483 if (event.eType == keyDownEvent || event.eType == keyUpEvent ||
484 event.eType == penUpEvent || event.eType == penMoveEvent)
486 RAND_add_event_entropy(&event);
489 if (event.eType == appStopEvent) break;
500 ConnectionListFree();
502 for (i = 0; i < NetLibCount; i++) {
503 NetLibClose(AppNetRefnum, false);
506 SaveResizePrefs(PSSH_CREATOR, ResizeDataID, 0);
507 TerminateResizeSupport();
511 PealUnload(arm_module);
521 // memory leak tracing
523 static int inited = 0;
524 static UInt16 heapID;
525 static uint32_t gen = 0;
529 extern uint32_t ev_block_count;
530 extern uint32_t ev_byte_count;
531 // extern uint32_t ev_blocks_used;
534 heapID = MemHeapID(0, 0);
536 MemHeapFreeBytes(heapID, &free, &max);
537 size = MemHeapSize(heapID);
539 debug_printf("mem %luK,%lu[%luK]AB,%lu gen", (size-free)/1024, ev_block_count, ev_byte_count/1024, gen++);
540 // if (gen % 100 == 0) arena_dump_blocks();
545 //if (ssh_is_selected(ss, &wfds)) {