From 653cd31ec4f803e69208ca45904f04f0ac631305 Mon Sep 17 00:00:00 2001 From: chombier <> Date: Sun, 1 Apr 2001 16:42:31 +0000 Subject: [PATCH] added keychain support --- lsh/MacOS/src/lsh_context.h | 1 + macssh/source/Headers/Preferences.h | 4 +- macssh/source/Headers/globaldefs.h | 2 + macssh/source/config/configure.c | 7 ++ macssh/source/init/init.c | 7 ++ macssh/source/ssh/PasswordDialog.c | 177 +++++++++++++++++++++++++++- macssh/source/ssh/PasswordDialog.h | 6 +- macssh/source/ssh/ssh2.c | 27 +++-- macssh/source/telnet.rsrc | Bin 163689 -> 163780 bytes macssh/www/download/ChangeLog | Bin 13026 -> 13175 bytes 10 files changed, 214 insertions(+), 17 deletions(-) diff --git a/lsh/MacOS/src/lsh_context.h b/lsh/MacOS/src/lsh_context.h index f2774de..500a714 100755 --- a/lsh/MacOS/src/lsh_context.h +++ b/lsh/MacOS/src/lsh_context.h @@ -66,6 +66,7 @@ typedef struct lshcontext { char _kpassword[64]; int _kindex; int _pindex; + char _keychainprompt[256]; } lshcontext; diff --git a/macssh/source/Headers/Preferences.h b/macssh/source/Headers/Preferences.h index f0770e2..f82a5fc 100755 --- a/macssh/source/Headers/Preferences.h +++ b/macssh/source/Headers/Preferences.h @@ -255,8 +255,8 @@ typedef struct { /* NONO */ Boolean - cachePassphrase, // Connection's windows remain open after connection close - unused1, // free + cachePassphrase, // + useKeyChain, // unused2, // free unused3; // free long diff --git a/macssh/source/Headers/globaldefs.h b/macssh/source/Headers/globaldefs.h index 7f1b76d..b87736e 100755 --- a/macssh/source/Headers/globaldefs.h +++ b/macssh/source/Headers/globaldefs.h @@ -152,6 +152,8 @@ PaletteHandle AnsiColors; //The Global ANSI Color palette Boolean haveColorQuickDraw; +Boolean + haveKeyChain; NewMacroInfo newMacros; }; diff --git a/macssh/source/config/configure.c b/macssh/source/config/configure.c index d876006..8b10c70 100755 --- a/macssh/source/config/configure.c +++ b/macssh/source/config/configure.c @@ -156,6 +156,11 @@ void Cenviron( void) } else { cachePass = TRUE; } + if ( !TelInfo->haveKeyChain ) { + HideDialogItem(dptr, 41); + } else { + SetCntrl(dptr, 41, gApplicationPrefs->useKeyChain); + } /* NONO */ scratchPstring[0] = 4; @@ -199,6 +204,7 @@ void Cenviron( void) case 35: case 36: case 37: + case 41: FlipCheckBox( dptr, ditem); break; case PrefStag: @@ -312,6 +318,7 @@ void Cenviron( void) GetTEText(dptr,24, scratchPstring); StringToNum(scratchPstring, &scratchlong); gApplicationPrefs->cacheDelay = scratchlong; + gApplicationPrefs->useKeyChain = GetCntlVal(dptr, 41); /* NONO */ gApplicationPrefs->CommandKeys = GetCntlVal(dptr, PrefCMDkey); diff --git a/macssh/source/init/init.c b/macssh/source/init/init.c index 2f2c7f1..5946f89 100755 --- a/macssh/source/init/init.c +++ b/macssh/source/init/init.c @@ -45,6 +45,8 @@ #include "memory.proto.h" #include "AddressXLation.h" +#include + #define _POSIX_SOURCE 1 #include #include @@ -253,6 +255,11 @@ void InquireEnvironment( void) } TelInfo->haveColorQuickDraw = theWorld.hasColorQD; +#if GENERATINGCFM + TelInfo->haveKeyChain = KeychainManagerAvailable(); +#else + TelInfo->haveKeyChain = false; +#endif } #define kURLEventClass 'GURL' diff --git a/macssh/source/ssh/PasswordDialog.c b/macssh/source/ssh/PasswordDialog.c index 97d419d..d4af121 100755 --- a/macssh/source/ssh/PasswordDialog.c +++ b/macssh/source/ssh/PasswordDialog.c @@ -24,14 +24,22 @@ #include #include #include +#include #include "PasswordDialog.h" #include "movableModal.h" #include "event.proto.h" #include "netevent.proto.h" #include "DlogUtils.proto.h" +#include "wind.h" + +#include extern void ssh2_sched(); +extern WindRec *ssh2_window(); + +extern void setctxprompt(const char *prompt); +extern char *getctxprompt(); extern TelInfoRec *TelInfo; extern Boolean gAEavail; @@ -368,11 +376,144 @@ Boolean SSH2LoginDialog(StringPtr host, StringPtr login, StringPtr password) return item == 1; } -Boolean SSH2PasswordDialog(StringPtr prompt, StringPtr password) +#if GENERATINGCFM + +/* + * GetPassFromKeychain + */ + +static void GetLabelFromPrompt(const char *prompt, StringPtr host, StringPtr user) +{ + WindRec *wind = ssh2_window(); + if ( wind && strstr(prompt, "assword for") ) { + StringPtr p = wind->sshdata.host; + memcpy( host, p, *p + 1 ); + p = wind->sshdata.login; + memcpy( user, p, *p + 1 ); + } else { + /* use key label as both host name and user name */ + int l = strlen(prompt); + *host = 4 + l; + memcpy(host + 1, "Key ", 4); + memcpy(host + 5, prompt, l); + *user = l; + memcpy(user + 1, prompt, l); + } +} + +/* + * GetPassFromKeychain + */ + +static Boolean GetPassFromKeychain(const char *prompt, StringPtr password) +{ + OSStatus theStatus; + UInt32 theLength; + KCItemRef theItem; + + if ( TelInfo->haveKeyChain && gApplicationPrefs->useKeyChain ) { + Str255 phost; + Str255 puser; + GetLabelFromPrompt(prompt, phost, puser); + theStatus = KCFindGenericPassword(phost, puser, 255, + password + 1, &theLength, &theItem); + if ( theStatus == noErr ) { + password[0] = theLength; + if (theItem != NULL) + KCReleaseItem( &theItem ); + return true; + } + } + return false; +} + +/* + * AddPassToKeychain + */ + +static void AddPassToKeychain(const char *prompt, StringPtr password) +{ + OSStatus theStatus; + UInt32 theLength; + KCItemRef theItem = NULL; + Str255 phost; + Str255 puser; + Str255 ppass; + KCAttribute theAttribute; + OSType theTypeCreator; + + if ( !TelInfo->haveKeyChain || !gApplicationPrefs->useKeyChain ) + return; + + GetLabelFromPrompt(prompt, phost, puser); + theStatus = KCFindGenericPassword(phost, puser, 255, + ppass + 1, &theLength, &theItem); + if ( theStatus == noErr && theItem != NULL) { + ppass[0] = theLength; + if ( memcmp(ppass, password, *ppass + 1) ) { + theStatus = KCSetData(theItem, *password, password + 1); + if (theStatus == noErr) + theStatus = KCUpdateItem(theItem); + } + } else { + theStatus = KCAddGenericPassword(phost, puser, + *password, password + 1, &theItem); + if (theStatus == noErr) { + unsigned char *theDescriptionText = "\pMacSSH password"; + theAttribute.tag = kDescriptionKCItemAttr; + theAttribute.length = *theDescriptionText; + theAttribute.data = theDescriptionText + 1; + theStatus = KCSetAttribute(theItem, &theAttribute); + } + if (theStatus == noErr) { + theTypeCreator = 'Ssh2'; + theAttribute.tag = kCreatorKCItemAttr; + theAttribute.length = sizeof(theTypeCreator); + theAttribute.data = &theTypeCreator; + theStatus = KCSetAttribute(theItem, &theAttribute); + } + if (theStatus == noErr) { + theTypeCreator = 'APPL'; + theAttribute.tag = kTypeKCItemAttr; + theStatus = KCSetAttribute(theItem, &theAttribute); + } + if (theStatus == noErr) { + Boolean theCustomIcon = true; + theAttribute.tag = kCustomIconKCItemAttr; + theAttribute.length = sizeof(theCustomIcon); + theAttribute.data = &theCustomIcon; + theStatus = KCSetAttribute(theItem, &theAttribute); + } + if (theStatus == noErr) + theStatus = KCUpdateItem(theItem); + } + if (theItem != NULL) + KCReleaseItem(&theItem); +} +#endif + + +/* + * SSH2PasswordDialog + */ + + + +Boolean SSH2PasswordDialog(const char *prompt, StringPtr password) { DialogPtr dlog; short item = 0; + Boolean addKey = false; ModalFilterUPP internalBufferFilterUPP; + ConstStringPtr keyPrompt = "\pEnter passphrase for private key "; + WindRec *wind; + +#if GENERATINGCFM + if ( strcmp(prompt, getctxprompt()) && GetPassFromKeychain(prompt, password) ) { + setctxprompt(prompt); + return true; + } +#endif InteractWithUser( true, 128, 128 ); @@ -381,12 +522,29 @@ Boolean SSH2PasswordDialog(StringPtr prompt, StringPtr password) *password = '\0'; dlog = GetNewMyDialog(rSSH2PasswordDialog, 0L, (WindowPtr)-1L, NULL); if ( dlog ) { + Str255 pprompt; SInt16 itemType; Handle itemHandle; Rect itemRect; + ControlHandle cntlHandle; + WindRec *wind = ssh2_window(); // set prompt + if ( wind && strstr(prompt, "assword for") ) { + pprompt[0] = strlen(prompt); + memcpy(pprompt + 1, prompt, pprompt[0]); + } else { + memcpy(pprompt, keyPrompt, keyPrompt[0] + 1); + memcpy(pprompt + pprompt[0] + 1, prompt, strlen(prompt)); + pprompt[0] += strlen(prompt); + } GetDialogItem(dlog, 5, &itemType, &itemHandle, &itemRect); - SetDialogItemText(itemHandle, prompt); + SetDialogItemText(itemHandle, pprompt); + if ( TelInfo->haveKeyChain && gApplicationPrefs->useKeyChain ) { + GetDialogItem(dlog, 6, &itemType, (Handle *)&cntlHandle, &itemRect); + SetControlValue(cntlHandle, addKey = true); + } else { + HideDialogItem(dlog, 6); + } SetDialogDefaultItem(dlog, 1); SetDialogCancelItem(dlog, 2); SetDialogTracksCursor(dlog, 1); @@ -394,16 +552,25 @@ Boolean SSH2PasswordDialog(StringPtr prompt, StringPtr password) SetWRefCon(dlog, (long)password); // Stash the buffer's address do { movableModalDialog(internalBufferFilterUPP, &item); + if (item == 6) { + SetControlValue(cntlHandle, !GetControlValue(cntlHandle)); + } } while (item != 1 && item != 2); // Until the OK button is hit + addKey = GetControlValue(cntlHandle); DisposeDialog(dlog); } DisposeRoutineDescriptor(internalBufferFilterUPP); ResetMenus(); +#if GENERATINGCFM + if ( item == 1 && addKey ) { + AddPassToKeychain( prompt, password ); + } +#endif return item == 1; } -static short SSH2SOCDialog(char *fingerprint, int id) +static short SSH2SOCDialog(const char *fingerprint, int id) { DialogPtr dlog; short item = 3; /* cancel */ @@ -442,12 +609,12 @@ static short SSH2SOCDialog(char *fingerprint, int id) return item; } -short SSH2SOC1Dialog(char *fingerprint) +short SSH2SOC1Dialog(const char *fingerprint) { return SSH2SOCDialog(fingerprint, rSSH2SOC1Dialog); } -short SSH2SOC2Dialog(char *fingerprint) +short SSH2SOC2Dialog(const char *fingerprint) { return SSH2SOCDialog(fingerprint, rSSH2SOC2Dialog); } diff --git a/macssh/source/ssh/PasswordDialog.h b/macssh/source/ssh/PasswordDialog.h index 31f53c5..533819b 100755 --- a/macssh/source/ssh/PasswordDialog.h +++ b/macssh/source/ssh/PasswordDialog.h @@ -38,9 +38,9 @@ Boolean SSH2RandomizeDialog( long *type, long *level, long *encrypt, Str255 labe void SSH2ErrorDialog(char *mess1); Boolean SSH2LoginDialog(StringPtr inhost, StringPtr iologin, StringPtr outpassword); -Boolean SSH2PasswordDialog (StringPtr inprompt, StringPtr outpassword); -short SSH2SOC1Dialog(char *fingerprint); -short SSH2SOC2Dialog(char *fingerprint); +Boolean SSH2PasswordDialog (const char *inprompt, StringPtr outpassword); +short SSH2SOC1Dialog(const char *fingerprint); +short SSH2SOC2Dialog(const char *fingerprint); void InternalBufferDialog (StringPtr inprompt, StringPtr outpassword); Boolean YesNoDialog (StringPtr inprompt); diff --git a/macssh/source/ssh/ssh2.c b/macssh/source/ssh/ssh2.c index 16b56b3..a7daa8f 100755 --- a/macssh/source/ssh/ssh2.c +++ b/macssh/source/ssh/ssh2.c @@ -781,11 +781,9 @@ char *getpass( const char *prompt ) wind->sshdata.password[0] = '\0'; valid = 1; } else { - pprompt[0] = strlen(prompt); - memcpy(pprompt + 1, prompt, pprompt[0]); ppassword[0] = 0; pthread_mutex_lock( &dialock ); - valid = SSH2PasswordDialog(pprompt, ppassword); + valid = SSH2PasswordDialog(prompt, ppassword); pthread_mutex_unlock( &dialock ); if (valid) { memcpy(password, ppassword + 1, ppassword[0]); @@ -805,12 +803,9 @@ char *getpass( const char *prompt ) && getnextcachedpassphrase(prompt, context->_kpassword, &context->_kindex) ) { return context->_kpassword; } - PLstrcpy(pprompt, "\pEnter passphrase for private key "); - memcpy(pprompt + pprompt[0] + 1, prompt, strlen(prompt)); - pprompt[0] += strlen(prompt); context->_kpassword[0] = 0; pthread_mutex_lock( &dialock ); - valid = SSH2PasswordDialog(pprompt, (StringPtr)context->_kpassword); + valid = SSH2PasswordDialog(prompt, (StringPtr)context->_kpassword); pthread_mutex_unlock( &dialock ); if (valid) { plen = context->_kpassword[0]; @@ -825,6 +820,23 @@ char *getpass( const char *prompt ) return (valid) ? password : NULL; } +/* + * setctxprompt + */ +void setctxprompt(const char *prompt) +{ + strcpy(((lshcontext *)pthread_getspecific(ssh2threadkey))->_keychainprompt, prompt); +} + +/* + * getctxprompt + */ + +char *getctxprompt() +{ + return ((lshcontext *)pthread_getspecific(ssh2threadkey))->_keychainprompt; +} + /* * save_once_cancel1 */ @@ -1110,6 +1122,7 @@ void init_context(lshcontext *context, short port) context->_kpassword[0] = 0; context->_kindex = 0; context->_pindex = 0; + context->_keychainprompt[0] = 0; } /* diff --git a/macssh/source/telnet.rsrc b/macssh/source/telnet.rsrc index ce8b7a90c816ca55bde04a9b01f45a945d8bcb40..85fdf584772d3cde6069c9627becd7641aff6c8a 100755 GIT binary patch delta 3308 zcmYk93viUx701uH`F6j31oDK!ZW1nO+(2GDo)LI$OP5W*ubl90zHgoI5@QhBLM zfKe;0)k)1&Yn6_)G6Gsavl19e9Rxv32_U3VionQg>Xf0?S}IBJIbUe_X0qS!``>fV ze)pVn&)wYUa~|n;zBnPi1^}EOg4^|70w91WUj(9Tk$xQ3ercF&3w#j3r;YZ*wn?EU z?AV5PIYUJ zaK2O&oe<`Mv1EikoPwFyeDCYg2e&X&<(Fcw4;^q2<8ZbSz1ZKNS1ogzni}e=DrosU zHypw-PUV+jo6V;&Q}vYLQ?^-{pkJuC9AB~H5coNI)c55$ZS*$~33uUnQ@|FQeD7*A z0KG*zV{>1Qz(ts%{$#_Eq4!qcF;rbEFnmPz^`U#izKXnO?}J8Ik0Bw{3zaz9TjuI` z^{wo$Cyob0Tj{XpPl%TJq{8k<`!CP5OfvAD9pnqc=yTxO*xwHr6GKnNQu`(eAHU5bn;=@>=?`GDGZ!!;T0K%B zrUu&qQ)@{zPuWiZTzG}K+p%5iA26RblL2mKFrRT8(E1n5XC3DO)3`v)&mFfkr?Gy{ zsl%1Ffcd=Bqj@cJk24D}-Ot?XOw)Qdfcl|AJmj1DcT$tR^zsi)Vvb{ek~yCFh$^lW zQ*EC}wCzzHm7>HpTZf=aeOD<`Z5>HC{WayQ5>xEvb%_qIs;m;JMd3*pbCP_R-FP4g zB16Oxzr|(=;X0wZ{-1O_E^!POqqoQ%kfM-vZ!xZyFk~IscuUL%33skAFL!<_adxx1 zS|w6~?gdgT;~GtlcI}Y3=QP~yq`-9A%5brD_#u3CbK4Sis*pUrE{S?+u53!`{#SoAABeAzgvnW}^T%sBJ z{>;3bZ02(%BuA0Wvg4#DN0YuUoH>U04?i%+5*wC{hxpTU)^)NX0h34a17~Zxp%VN$ z7k`y#?^X-^qBefEgy=-Fz$lTec{cM1=Q~N5wL_iuQ@Z}8)3sX-tBnllmTkQf^LD8>YDCHccbOCgT)H~=`z7w{By$~nr4w;4_y=^g zY-Qc!j+OY?C}yvtQetvDbDZ-ziPM|a@LDk{C=L9KTU^eI?lFK@CX-3dHuprpuYXAl z)&^V5+(zMu;rzfRW`1MX%uM?iU<)&43e2OnSpeI3)51pAb-)k*LproMbbumr^=^2- zR!ojc0gR(g0q`tM{;FKvsnua!X5h{qm9kRY@tFBEYIf6b(tnvx6VK{US#@G~(ByhH zKPN5gOCIkb&Msx{C4S&4F(7e)<-_u)ccu1yhIG-ze3sa5*;qc$v3`#9w0|?R|MZQ_ zqpUBmTFDn=lxm$L9K75O>UN#T2wuBE#&euB{?BpDF5k#!g~Nn1m(Y6C!9EsJlxXrrum7h9tOj^&RG{h4mTn z5|(nN3>_7Tg>~x0Dv=O$-32^eL6gj*F8z7oD6v%uU5^g(Vcyy1F;|7eT_)+~Dc2g! zBbd8g9s_rrVLt6Tp$qmh^I2oEglD)a%pT_eQa6aa|jx&x&eMZ7O|+u-CL-qw~=xtw*1B)YDs-bRt(8NPkcwpTmS7k|;vYbvox zk9(|k#xHU)Y;Zint5)$iw;!vMU7UK~cu?)t<38_9)~xv)ILrTju3c*(QI9J7iZt14#OQ}@~KX6E-!STblE9iiUUw!u+_gSM9^F!RxC{S>f{ z-V8qV&^mfKnAXV~bBOE*3g;VQ>*Ouq#ChrDMSPoeK6&$ch^>>ia0YV;S3^NNKX8>5 z9AmbsjI(G}!|@BO>!Vj!++UcjllKK;tCtt@56pqHVYljR7KxtJTpBj5?ZuU2S}ppc z(Cuc?>jJecs(OQv!(D>|_o2!R HigEt~KY2gu delta 3079 zcmY+Gdr*|u6~OPg`z_yoyR^KG;dy0{#pM-k(So8AmqyVJ#(Fdc2~{d2%lAhpmllvqL#43G^egx* zgojR7^Gulg!mlIEJ(0F}1?jAhU57t%pNy#C^FsAi;QANblY7_k1KF8nExv&8hz?(4 zz}F$X&4GZruezpaZ}EBk^?qNSsC`i>R938GAx|mKuqCqki}4jTEB?CZ8F~fvN{pTO z+p?u6ZtWYCYioGc;$%-rhnJ^B?G>=Vi{=ul?4<(S_hnL@3dLOk#ph*F z9d`xw_XJpePA5j&Ck32JAda#BNx*OaNgS(xB*5BA9PcO-aA_-Xf~{SHj6C8*3 zTTouwfb5Jy*0PDCkq0V?V~|g-A&x~3OCgR&9(#dUgyUe z6~&)u&_7SU+`u0NZDd0q!R7SzsH%@5ulj`e5;DI}JcewetkuVnS1uy?72;#WSCO5| zkQpGm>FzW3Rf#G4rp=SYWu{T{VAE(8EnLRUIi_%%Tc~|<@B_A%Q56~8_H8}5#wH-L!Gyr_U2Qs zFQ>i5_vQ8Nszx1!0xrCd`j#mzNwCTwvZfqYX-0AzQ+AlYk92Nps&Bn~hWL)7n8E0~ z$og6PS5&V%i){Mw!Jb*ZKsBwOv%f2#zZ~WIu>G`R57nqXV)ttBej+W5I${J2W)hES zd4j!SzU~#{F9M2+Q66zn8xU+?8gk5cwR4JH$f`DkfQ`Q*-mHC3u)b%A-G)l=f^QRV zu^R$5{Ft~}I~=K$KBtcXU3J!?9Wt(wyTTmG&`_0J)5up9ZDcV21gfxZZA!2ott9TT zHZa)KP26jAGFV~|@3c0lSr8)LW$a+^)iilQnXw*Kt>-ft)x=W+9(o6-Y8R1EP)n*9 zWBwe?3bSBx%>;Z!$$__{j%5Pbh(b1#H>-)*%&l(`Q*LGd7kTC#j>|($s>i%x-SKpZ z9BksreCZ8&y@_w-MxiVW@YFBI-au`$J1&TjO-jadZE~;ryWFjw8`}sTJ)cI6lRBQ2 zhAg_kzxXxKO>iK*c&yDTRIyqLT0%KTC>O=NCd9#`4q{ls&)xEWPR(BqyHY45ee3{q6bK;+R zG^_h@$*gW9cn4nEsM(3YDg5H^wK8Hl7m{@6GDo zrHWuQMm=QL9HY5AQ3q&@+7}?tOwm~6nLJsAY);XQIx$XBfOm*#idLApV@}Ztlsnz@ z_-@L1GpXDZl$oS5=RH0CC34FA4<=(iZ8oQ<893FSRAU}S`AlQB$f$On8lR;Ghmx5! zA&IFboO45^?Yzwob=PmaKdG7xJ DX&Mq| diff --git a/macssh/www/download/ChangeLog b/macssh/www/download/ChangeLog index 593f1d63c85be7fe7d1257942d2f2b8e79f3faa5..9436b94acb13daee1d3eb8f1a352342390bc3ac0 100755 GIT binary patch delta 667 zcmZXS&ubGw6vt=NHP zLdzCCiboHgD*XdIiwAEWL=f#E|A1HD>{^Iq4zq8*eBbB2$J?L$PjqnQqJKmPsSx6S zC1mLp#><3UdxT#II-RcHxqi6jPk{;s>sy0+5VX7P8^fSoZ^3;UZVq6B?}af<1cX$8 zkP{ek$P8x?Nezk`Gm)B^0^nXM*3@tVm|$aG2k7@#VV7%@Na3IxTo1XH22`4j&}3qn zrBhark+cJo#KtalJ`t>xF1g1T7H()xSp#}XrF;)*?|xn4qx?P0OY; z!MIKnfh{^xe#^U1qY--YXP!QOT={jic1nnMdffBBd(#i(9Im436$`<2;934yYA!4U zye@B-T6JD~y69`JEb^MGi@w%TsjbWdTW=PPRxmO!Fx0Q8nCPmnq{pkP5L%Fu zSdyBeP@Y+mq2L}G?5SX+XQ*eEWCW5-nY^2^MkhZ{At}G4BtKUnKTV-HxhOR?52Cy@ zFD11oCo?ZqA+e;SC^MpKPp#&?_V>EC6n7hvE9dV+-! z>=mF#fPhmRA_iiD1%QOoK8P3#ve-dPb(-@r&C^_lsZQrRM9c=+K%HNh3K>#9zb-Vj ze`;jF08|PA+n(>fz3q9G*W@xIEi<`9u%|(OR!9Ve1~4cy3rZA{^K)|(^HP91fPQ0O d0(%+Am>=vP6v8}j@;Rdb7S;;sIg^!)LjfM&YxV#D