📄 auth.c
字号:
/* * auth.c - deal with authentication. * * This file implements authentication when setting up an RFB connection. *//* * Copyright (C) 2003-2006 Constantin Kaplinsky. All Rights Reserved. * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */#include <stdio.h>#include <stdlib.h>#include "windowstr.h"#include "rfb.h"char *rfbAuthPasswdFile = NULL;static void rfbSendSecurityType(rfbClientPtr cl, int securityType);static void rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType);static void rfbSendTunnelingCaps(rfbClientPtr cl);static void rfbSendAuthCaps(rfbClientPtr cl);static void rfbVncAuthSendChallenge(rfbClientPtr cl);/* * rfbAuthNewClient is called right after negotiating the protocol * version. Depending on the protocol version, we send either a code * for authentication scheme to be used (protocol 3.3), or a list of * possible "security types" (protocol 3.7 and above). */voidrfbAuthNewClient(cl) rfbClientPtr cl;{ int securityType = rfbSecTypeInvalid; if (!rfbAuthPasswdFile || cl->reverseConnection) { securityType = rfbSecTypeNone; } else { if (rfbAuthIsBlocked()) { rfbLog("Too many authentication failures - client rejected\n"); rfbClientConnFailed(cl, "Too many authentication failures"); return; } if (rfbAuthPasswdFile) securityType = rfbSecTypeVncAuth; } if (cl->protocol_minor_ver < 7) { /* Make sure we use only RFB 3.3 compatible security types. */ if (securityType == rfbSecTypeInvalid) { rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n"); rfbClientConnFailed(cl, "Your viewer cannot handle required " "authentication methods"); return; } rfbSendSecurityType(cl, securityType); } else { /* Here it's ok when securityType is set to rfbSecTypeInvalid. */ rfbSendSecurityTypeList(cl, securityType); }}/* * Tell the client what security type will be used (protocol 3.3). */static voidrfbSendSecurityType(cl, securityType) rfbClientPtr cl; int securityType;{ CARD32 value32; /* Send the value. */ value32 = Swap32IfLE(securityType); if (WriteExact(cl->sock, (char *)&value32, 4) < 0) { rfbLogPerror("rfbSendSecurityType: write"); rfbCloseSock(cl->sock); return; } /* Decide what to do next. */ switch (securityType) { case rfbSecTypeNone: /* Dispatch client input to rfbProcessClientInitMessage. */ cl->state = RFB_INITIALISATION; break; case rfbSecTypeVncAuth: /* Begin the standard VNC authentication procedure. */ rfbVncAuthSendChallenge(cl); break; default: /* Impossible case (hopefully). */ rfbLogPerror("rfbSendSecurityType: assertion failed"); rfbCloseSock(cl->sock); }}/* * Advertise our supported security types (protocol 3.7 and above). * The list includes one standard security type (if primaryType is not * set to rfbSecTypeInvalid), and then one more value telling the * client that we support TightVNC protocol extensions. Thus, * currently, there will be either 1 or 2 items in the list. */static voidrfbSendSecurityTypeList(cl, primaryType) rfbClientPtr cl; int primaryType;{ int count = 1; /* Fill in the list of security types in the client structure. */ if (primaryType != rfbSecTypeInvalid) { cl->securityTypes[count++] = (CARD8)primaryType; } cl->securityTypes[count] = (CARD8)rfbSecTypeTight; cl->securityTypes[0] = (CARD8)count++; /* Send the list. */ if (WriteExact(cl->sock, (char *)cl->securityTypes, count) < 0) { rfbLogPerror("rfbSendSecurityTypeList: write"); rfbCloseSock(cl->sock); return; } /* Dispatch client input to rfbProcessClientSecurityType. */ cl->state = RFB_SECURITY_TYPE;}/* * Read the security type chosen by the client (protocol 3.7 and * above). */voidrfbProcessClientSecurityType(cl) rfbClientPtr cl;{ int n, count, i; CARD8 chosenType; /* Read the security type. */ n = ReadExact(cl->sock, (char *)&chosenType, 1); if (n <= 0) { if (n == 0) rfbLog("rfbProcessClientSecurityType: client gone\n"); else rfbLogPerror("rfbProcessClientSecurityType: read"); rfbCloseSock(cl->sock); return; } /* Make sure it was present in the list sent by the server. */ count = (int)cl->securityTypes[0]; for (i = 1; i <= count; i++) { if (chosenType == cl->securityTypes[i]) break; } if (i > count) { rfbLog("rfbProcessClientSecurityType: " "wrong security type requested\n"); rfbCloseSock(cl->sock); return; } /* Now go to the proper authentication procedure. */ switch (chosenType) { case rfbSecTypeNone: /* No authentication needed. */ rfbClientAuthSucceeded(cl, rfbAuthNone); break; case rfbSecTypeVncAuth: /* Begin the standard VNC authentication procedure. */ rfbVncAuthSendChallenge(cl); break; case rfbSecTypeTight: /* We are lucky: the viewer supports TightVNC extensions. */ rfbLog("Enabling TightVNC protocol extensions\n"); /* Switch to the protocol 3.7t/3.8t. */ cl->protocol_tightvnc = TRUE; /* Advertise our tunneling capabilities. */ rfbSendTunnelingCaps(cl); break; default: /* Impossible case (hopefully). */ rfbLog("rfbProcessClientSecurityType: " "unknown authentication scheme\n"); rfbCloseSock(cl->sock); }}/* * Send the list of our tunneling capabilities (protocol 3.7t/3.8t). */static voidrfbSendTunnelingCaps(cl) rfbClientPtr cl;{ rfbTunnelingCapsMsg caps; CARD32 nTypes = 0; /* we don't support tunneling yet */ caps.nTunnelTypes = Swap32IfLE(nTypes); if (WriteExact(cl->sock, (char *)&caps, sz_rfbTunnelingCapsMsg) < 0) { rfbLogPerror("rfbSendTunnelingCaps: write"); rfbCloseSock(cl->sock); return; } if (nTypes) { /* Dispatch client input to rfbProcessClientTunnelingType(). */ cl->state = RFB_TUNNELING_TYPE; } else { rfbSendAuthCaps(cl); }}/* * Read tunneling type requested by the client (protocol 3.7t/3.8t). * NOTE: Currently, we don't support tunneling, and this function * can never be called. */voidrfbProcessClientTunnelingType(cl) rfbClientPtr cl;{ /* If we were called, then something's really wrong. */ rfbLog("rfbProcessClientTunnelingType: not implemented\n"); rfbCloseSock(cl->sock); return;}/* * Send the list of our authentication capabilities to the client * (protocol 3.7t/3.8t). */static voidrfbSendAuthCaps(cl) rfbClientPtr cl;{ Bool authRequired; rfbAuthenticationCapsMsg caps; rfbCapabilityInfo caplist[MAX_AUTH_CAPS]; int count = 0; authRequired = (rfbAuthPasswdFile != NULL && !cl->reverseConnection); if (authRequired) { if (rfbAuthPasswdFile != NULL) { SetCapInfo(&caplist[count], rfbAuthVNC, rfbStandardVendor); cl->authCaps[count++] = rfbAuthVNC; } if (count == 0) { /* Should never happen. */ rfbLog("rfbSendAuthCaps: assertion failed\n"); rfbCloseSock(cl->sock); return; } } cl->nAuthCaps = count; caps.nAuthTypes = Swap32IfLE((CARD32)count); if (WriteExact(cl->sock, (char *)&caps, sz_rfbAuthenticationCapsMsg) < 0) { rfbLogPerror("rfbSendAuthCaps: write"); rfbCloseSock(cl->sock); return; } if (count) { if (WriteExact(cl->sock, (char *)&caplist[0], count * sz_rfbCapabilityInfo) < 0) { rfbLogPerror("rfbSendAuthCaps: write"); rfbCloseSock(cl->sock); return; } /* Dispatch client input to rfbProcessClientAuthType. */ cl->state = RFB_AUTH_TYPE; } else { /* No authentication needed. */ rfbClientAuthSucceeded(cl, rfbAuthNone); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -