⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auth.c

📁 远程桌面连接工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Read client's preferred authentication type (protocol 3.7t/3.8t). */voidrfbProcessClientAuthType(cl)    rfbClientPtr cl;{    CARD32 auth_type;    int n, i;    /* Read authentication type selected by the client. */    n = ReadExact(cl->sock, (char *)&auth_type, sizeof(auth_type));    if (n <= 0) {	if (n == 0)	    rfbLog("rfbProcessClientAuthType: client gone\n");	else	    rfbLogPerror("rfbProcessClientAuthType: read");	rfbCloseSock(cl->sock);	return;    }    auth_type = Swap32IfLE(auth_type);    /* Make sure it was present in the list sent by the server. */    for (i = 0; i < cl->nAuthCaps; i++) {	if (auth_type == cl->authCaps[i])	    break;    }    if (i >= cl->nAuthCaps) {	rfbLog("rfbProcessClientAuthType: "	       "wrong authentication type requested\n");	rfbCloseSock(cl->sock);	return;    }    switch (auth_type) {    case rfbAuthNone:	/* Dispatch client input to rfbProcessClientInitMessage. */	cl->state = RFB_INITIALISATION;	break;    case rfbAuthVNC:	rfbVncAuthSendChallenge(cl);	break;    default:	rfbLog("rfbProcessClientAuthType: unknown authentication scheme\n");	rfbCloseSock(cl->sock);    }}/* * Send the authentication challenge. */static voidrfbVncAuthSendChallenge(cl)    rfbClientPtr cl;{    vncRandomBytes(cl->authChallenge);    if (WriteExact(cl->sock, (char *)cl->authChallenge, CHALLENGESIZE) < 0) {	rfbLogPerror("rfbVncAuthSendChallenge: write");	rfbCloseSock(cl->sock);	return;    }    /* Dispatch client input to rfbVncAuthProcessResponse. */    cl->state = RFB_AUTHENTICATION;}/* * rfbVncAuthProcessResponse is called when the client sends its * authentication response. */voidrfbVncAuthProcessResponse(cl)    rfbClientPtr cl;{    char passwdFullControl[9];    char passwdViewOnly[9];    int numPasswords;    Bool ok;    int n;    CARD8 encryptedChallenge1[CHALLENGESIZE];    CARD8 encryptedChallenge2[CHALLENGESIZE];    CARD8 response[CHALLENGESIZE];    n = ReadExact(cl->sock, (char *)response, CHALLENGESIZE);    if (n <= 0) {	if (n != 0)	    rfbLogPerror("rfbVncAuthProcessResponse: read");	rfbCloseSock(cl->sock);	return;    }    numPasswords = vncDecryptPasswdFromFile2(rfbAuthPasswdFile,					     passwdFullControl,					     passwdViewOnly);    if (numPasswords == 0) {	rfbLog("rfbVncAuthProcessResponse: could not get password from %s\n",	       rfbAuthPasswdFile);	rfbClientAuthFailed(cl, "The server is not configured properly");	return;    }    memcpy(encryptedChallenge1, cl->authChallenge, CHALLENGESIZE);    vncEncryptBytes(encryptedChallenge1, passwdFullControl);    memcpy(encryptedChallenge2, cl->authChallenge, CHALLENGESIZE);    vncEncryptBytes(encryptedChallenge2,		    (numPasswords == 2) ? passwdViewOnly : passwdFullControl);    /* Lose the passwords from memory */    memset(passwdFullControl, 0, 9);    memset(passwdViewOnly, 0, 9);    ok = FALSE;    if (memcmp(encryptedChallenge1, response, CHALLENGESIZE) == 0) {	rfbLog("Full-control authentication passed by %s\n", cl->host);	ok = TRUE;	cl->viewOnly = FALSE;    } else if (memcmp(encryptedChallenge2, response, CHALLENGESIZE) == 0) {	rfbLog("View-only authentication passed by %s\n", cl->host);	ok = TRUE;	cl->viewOnly = TRUE;    }    if (ok) {	rfbAuthUnblock();	rfbClientAuthSucceeded(cl, rfbAuthVNC);    } else {	rfbLog("rfbVncAuthProcessResponse: authentication failed from %s\n",	       cl->host);	if (rfbAuthConsiderBlocking()) {	    rfbClientAuthFailed(cl, "Authentication failed, too many tries");	} else {	    rfbClientAuthFailed(cl, "Authentication failed");	}    }}/* * rfbClientConnFailed is called when a client connection has failed * before the authentication stage. */voidrfbClientConnFailed(cl, reason)    rfbClientPtr cl;    char *reason;{    int headerLen, reasonLen;    char buf[8];    headerLen = (cl->protocol_minor_ver >= 7) ? 1 : 4;    reasonLen = strlen(reason);    ((CARD32 *)buf)[0] = 0;    ((CARD32 *)buf)[1] = Swap32IfLE(reasonLen);    if ( WriteExact(cl->sock, buf, headerLen) < 0 ||	 WriteExact(cl->sock, buf + 4, 4) < 0 ||	 WriteExact(cl->sock, reason, reasonLen) < 0 ) {	rfbLogPerror("rfbClientConnFailed: write");    }    rfbCloseSock(cl->sock);}/* * rfbClientAuthFailed is called on authentication failure. Sending a * reason string is defined in the RFB protocol 3.8 and above. */voidrfbClientAuthFailed(cl, reason)    rfbClientPtr cl;    char *reason;{    int reasonLen;    char buf[8];    if (cl->protocol_minor_ver < 8)	reason = NULL;		/* invalidate the pointer */    reasonLen = (reason == NULL) ? 0 : strlen(reason);    ((CARD32 *)buf)[0] = Swap32IfLE(rfbAuthFailed);    ((CARD32 *)buf)[1] = Swap32IfLE(reasonLen);    if (reasonLen == 0) {	if (WriteExact(cl->sock, buf, 4) < 0) {	    rfbLogPerror("rfbClientAuthFailed: write");	}    } else {	if ( WriteExact(cl->sock, buf, 8) < 0 ||	     WriteExact(cl->sock, reason, reasonLen) < 0 ) {	    rfbLogPerror("rfbClientAuthFailed: write");	}    }    rfbCloseSock(cl->sock);}/* * rfbClientAuthSucceeded is called on successful authentication. * It just sends rfbAuthOK and dispatches client input to * rfbProcessClientInitMessage(). However, rfbAuthOK message is * not sent if authentication was not required and the protocol * version is 3.7 or lower. */voidrfbClientAuthSucceeded(cl, authType)    rfbClientPtr cl;    CARD32 authType;{    CARD32 authResult;    if (cl->protocol_minor_ver >= 8 || authType != rfbAuthNone) {        authResult = Swap32IfLE(rfbAuthOK);        if (WriteExact(cl->sock, (char *)&authResult, 4) < 0) {            rfbLogPerror("rfbClientAuthSucceeded: write");            rfbCloseSock(cl->sock);            return;        }    }    /* Dispatch client input to rfbProcessClientInitMessage(). */    cl->state = RFB_INITIALISATION;}/********************************************************************* * Functions to prevent too many successive authentication failures. * FIXME: This should be performed separately per each client IP. *//* Maximum authentication failures before blocking connections */#define MAX_AUTH_TRIES 5/* Delay in ms, doubles for each failure over MAX_AUTH_TRIES */#define AUTH_TOO_MANY_BASE_DELAY 10 * 1000static int rfbAuthTries = 0;static Bool rfbAuthTooManyTries = FALSE;static OsTimerPtr timer = NULL;/* * This function should not be called directly, it is called by * setting a timer in rfbAuthConsiderBlocking(). */static CARD32rfbAuthReenable(OsTimerPtr timer, CARD32 now, pointer arg){    rfbAuthTooManyTries = FALSE;    return 0;}/* * This function should be called after each authentication failure. * The return value will be true if there was too many failures. */BoolrfbAuthConsiderBlocking(void){    int i;    rfbAuthTries++;    if (rfbAuthTries >= MAX_AUTH_TRIES) {	CARD32 delay = AUTH_TOO_MANY_BASE_DELAY;	for (i = MAX_AUTH_TRIES; i < rfbAuthTries; i++)	    delay *= 2;	timer = TimerSet(timer, 0, delay, rfbAuthReenable, NULL);	rfbAuthTooManyTries = TRUE;	return TRUE;    }    return FALSE;}/* * This function should be called after successful authentication. * It resets the counter of authentication failures. Note that it's * not necessary to clear the rfbAuthTooManyTries flag as it will be * reset by the timer function. */voidrfbAuthUnblock(void){    rfbAuthTries = 0;}/* * This function should be called before authentication process. * The return value will be true if there was too many authentication * failures, and the server should not allow another try. */BoolrfbAuthIsBlocked(void){    return rfbAuthTooManyTries;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -