From a52a0413898de5010cc59307dcba5f1db2d96eaf Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sat, 15 Apr 2017 18:11:24 -0500 Subject: [PATCH] Add support for rewriting login requests to force use of AFP version 2.2. This should add support for a greater variety of servers, which may only support AFP 2.2 and up (or refuse to use older versions over TCP). The IIgs software is designed for AFP 2.0. AFP 2.2 is close enough that things seem to work, but there could potentially be a few compatibility issues. --- aspinterface.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/aspinterface.c b/aspinterface.c index 2244838..aafd6eb 100644 --- a/aspinterface.c +++ b/aspinterface.c @@ -14,6 +14,7 @@ #include "installcmds.h" #include "atipmapping.h" #include "afpoptions.h" +#include "strncasecmp.h" typedef struct FPReadRec { Word CommandCode; /* includes pad byte */ @@ -25,6 +26,12 @@ typedef struct FPReadRec { } FPReadRec; #define kFPRead 27 +#define kFPLogin 18 + +/* For forced AFP 2.2 login */ +static Byte loginBuf[100]; +static const Byte afp20VersionStr[] = "\pAFPVersion 2.0"; +static const Byte afp22VersionStr[] = "\pAFP2.2"; static void EndSession(Session *sess, Boolean callAttnRoutine); @@ -247,6 +254,34 @@ static void DoSPCommand(Session *sess, ASPCommandRec *commandRec) { } } } + /* + * If requested, replace AFP 2.0 login requests with otherwise-identical + * AFP 2.2 login requests. This provides compatibility with some servers + * that don't support AFP 2.0 over TCP. The protocols are similar enough + * that it seems to work, although there could be issues. + */ + else if ((sess->atipMapping.flags & fForceAFP22) + && commandRec->cmdBlkLength >= sizeof(afp20VersionStr) + && *((Byte*)commandRec->cmdBlkAddr) == kFPLogin + && commandRec->cmdBlkLength <= sizeof(loginBuf) + && strncasecmp(afp20VersionStr, (Byte*)commandRec->cmdBlkAddr + 1, + sizeof(afp20VersionStr) - 1) == 0) + { + memcpy(loginBuf, (Byte*)commandRec->cmdBlkAddr, + commandRec->cmdBlkLength); + loginBuf[sizeof(afp20VersionStr)-sizeof(afp22VersionStr)] = kFPLogin; + memcpy(&loginBuf[sizeof(afp20VersionStr)-sizeof(afp22VersionStr)+1], + afp22VersionStr, + sizeof(afp22VersionStr) - 1); + + sess->request.totalDataLength = + htonl(commandRec->cmdBlkLength + -sizeof(afp20VersionStr)+sizeof(afp22VersionStr)); + SendDSIMessage(sess, &sess->request, + loginBuf+sizeof(afp20VersionStr)-sizeof(afp22VersionStr), + NULL); + return; + } /* Mask off high byte of addresses because PFI (at least) may * put junk in them, and this can cause Marinetti errors. */