1 /******************************************************************************
4 Copyright 1993, 1998 The Open Group
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
26 Author: Ralph Mor, X Consortium
27 ******************************************************************************/
32 #include <X11/ICE/ICElib.h>
33 #include "ICElibint.h"
35 #include <stdio.h> /* sprintf */
38 * Check for bad length
41 #define CHECK_SIZE_MATCH(_iceConn, _opcode, _expected_len, _actual_len, _severity, _return) \
42 if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) != _expected_len) \
44 _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
48 #define CHECK_AT_LEAST_SIZE(_iceConn, _opcode, _expected_len, _actual_len, _severity) \
49 if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) > _expected_len) \
51 _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
55 #define CHECK_COMPLETE_SIZE(_iceConn, _opcode, _expected_len, _actual_len, _pStart, _severity) \
56 if (((PADDED_BYTES64((_actual_len)) - SIZEOF (iceMsg)) >> 3) \
59 _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
60 IceDisposeCompleteMessage (iceConn, _pStart); \
64 #define BAIL_STRING(_iceConn, _opcode, _pStart) {\
65 _IceErrorBadLength (_iceConn, 0, _opcode, IceFatalToConnection);\
66 IceDisposeCompleteMessage (_iceConn, _pStart);\
73 * If replyWait == NULL, the client is not waiting for a reply.
75 * If replyWait != NULL, the client is waiting for a reply...
77 * - replyWait->sequence_of_request is the sequence number of the
78 * message for which the client is waiting a reply. This is needed
79 * to determine if an error matches a replyWait.
81 * - replyWait->major_opcode_of_request is the major opcode of the
82 * message for which we are waiting a reply.
84 * - replyWait->minor_opcode_of_request is the minor opcode of the
85 * message for which we are waiting a reply.
87 * - replyWait->reply is a pointer to the reply message which will be
88 * filled in when the reply is ready (the protocol library should
89 * cast this IcePointer to the appropriate reply type). In most cases,
90 * the reply will have some fixed-size part, and the sender function
91 * will have provided a pointer to a structure (e.g.) to hold this
92 * fixed-size data. If there is variable-length data, it would be
93 * expected that the reply function will have to allocate additional
94 * memory and store pointer(s) to that memory in the fixed-size
95 * structure. If the entire data is variable length (e.g., a single
96 * variable-length string), then the sender function would probably
97 * just pass a pointer to fixed-size space to hold a pointer, and the
98 * reply function would allocate the storage and store the pointer.
99 * It is the responsibility of the client receiving the reply to
100 * free up any memory allocated on it's behalf.
102 * We might be waiting for several different replies (a function can wait
103 * for a reply, and while calling IceProcessMessages, a callback can be
104 * invoked which will wait for another reply). We take advantage of the
105 * fact that for a given protocol, we are guaranteed that messages are
106 * processed in the order we sent them. So, everytime we have a new
107 * replyWait, we add it to the END of the 'saved_reply_waits' list. When
108 * we read a message and want to see if it matches a replyWait, we use the
109 * FIRST replyWait in the list with the major opcode of the message. If the
110 * reply is ready, we remove that replyWait from the list.
112 * If the reply/error is ready for the replyWait passed in to
113 * IceProcessMessages, *replyReadyRet is set to True.
115 * The return value of IceProcessMessages is one of the following:
117 * IceProcessMessagesSuccess - the message was processed successfully.
118 * IceProcessMessagesIOError - an IO error occured. The caller should
119 * invoked IceCloseConnection.
120 * IceProcessMessagesConnectionClosed - the connection was closed as a
121 * result of shutdown negotiation.
124 IceProcessMessagesStatus
127 IceReplyWaitInfo *replyWait,
132 Bool replyReady = False;
133 IceReplyWaitInfo *useThisReplyWait = NULL;
134 IceProcessMessagesStatus retStatus = IceProcessMessagesSuccess;
137 *replyReadyRet = False;
140 * Each time IceProcessMessages is entered, we increment the dispatch
141 * level. Each time we leave it, we decrement the dispatch level.
144 iceConn->dispatch_level++;
148 * Read the ICE message header.
151 if (!_IceRead (iceConn, (unsigned long) SIZEOF (iceMsg), iceConn->inbuf))
154 * If we previously sent a WantToClose and now we detected
155 * that the connection was closed, _IceRead returns status 0.
156 * Since the connection was closed, we just want to return here.
159 return (IceProcessMessagesConnectionClosed);
165 * An unexpected IO error occured. The caller of IceProcessMessages
166 * should call IceCloseConnection which will cause the watch procedures
167 * to be invoked and the ICE connection to be freed.
170 iceConn->dispatch_level--;
171 iceConn->connection_status = IceConnectIOError;
172 return (IceProcessMessagesIOError);
175 header = (iceMsg *) iceConn->inbuf;
176 iceConn->inbufptr = iceConn->inbuf + SIZEOF (iceMsg);
178 iceConn->receive_sequence++;
180 if (iceConn->waiting_for_byteorder)
182 if (header->majorOpcode == 0 &&
183 header->minorOpcode == ICE_ByteOrder)
185 char byteOrder = ((iceByteOrderMsg *) header)->byteOrder;
188 CHECK_SIZE_MATCH (iceConn, ICE_ByteOrder,
189 header->length, SIZEOF (iceByteOrderMsg),
190 IceFatalToConnection, IceProcessMessagesIOError);
192 if (byteOrder != IceMSBfirst && byteOrder != IceLSBfirst)
194 _IceErrorBadValue (iceConn, 0,
195 ICE_ByteOrder, 2, 1, &byteOrder);
197 iceConn->connection_status = IceConnectRejected;
202 (((*(char *) &endian) && byteOrder == IceMSBfirst) ||
203 (!(*(char *) &endian) && byteOrder == IceLSBfirst));
205 iceConn->waiting_for_byteorder = 0;
210 if (header->majorOpcode != 0)
212 _IceErrorBadMajor (iceConn, header->majorOpcode,
213 header->minorOpcode, IceFatalToConnection);
217 _IceErrorBadState (iceConn, 0,
218 header->minorOpcode, IceFatalToConnection);
221 iceConn->connection_status = IceConnectRejected;
224 iceConn->dispatch_level--;
227 iceConn->connection_status = IceConnectIOError;
228 retStatus = IceProcessMessagesIOError;
236 /* swap the length field */
238 header->length = lswapl (header->length);
244 * Add to the list of replyWaits (only if it doesn't exist
245 * in the list already.
248 _IceAddReplyWait (iceConn, replyWait);
251 * Note that there are two different replyWaits. The first is
252 * the one passed into IceProcessMessages, and is the replyWait
253 * for the message the client is blocking on. The second is
254 * the replyWait for the message currently being processed
255 * by IceProcessMessages. We call it "useThisReplyWait".
257 * Also, when two hosts communicate over an ICE connection and use
258 * different major opcodes for a subprotocol, it is impossible
259 * to use message replies unless we translate opcodes before
266 if (header->majorOpcode == 0)
272 int idx = header->majorOpcode - iceConn->his_min_opcode;
273 op = iceConn->process_msg_info[idx].my_opcode;
275 useThisReplyWait = _IceSearchReplyWaits (iceConn, op);
279 if (header->majorOpcode == 0)
285 Bool connectionClosed;
287 _IceProcessCoreMsgProc processIce =
288 _IceVersions[iceConn->my_ice_version_index].process_core_msg_proc;
290 (*processIce) (iceConn, header->minorOpcode,
291 header->length, iceConn->swap,
292 useThisReplyWait, &replyReady, &connectionClosed);
294 if (connectionClosed)
297 * As a result of shutdown negotiation, the connection was closed.
300 return (IceProcessMessagesConnectionClosed);
309 if ((int) header->majorOpcode < iceConn->his_min_opcode ||
310 (int) header->majorOpcode > iceConn->his_max_opcode ||
311 !(iceConn->process_msg_info[header->majorOpcode -
312 iceConn->his_min_opcode].in_use))
315 * The protocol of the message we just read is not supported.
318 _IceErrorBadMajor (iceConn, header->majorOpcode,
319 header->minorOpcode, IceCanContinue);
321 _IceReadSkip (iceConn, header->length << 3);
325 _IceProcessMsgInfo *processMsgInfo = &iceConn->process_msg_info[
326 header->majorOpcode - iceConn->his_min_opcode];
328 if (processMsgInfo->accept_flag)
330 IcePaProcessMsgProc processProc =
331 processMsgInfo->process_msg_proc.accept_client;
333 (*processProc) (iceConn, processMsgInfo->client_data,
334 header->minorOpcode, header->length, iceConn->swap);
338 IcePoProcessMsgProc processProc =
339 processMsgInfo->process_msg_proc.orig_client;
341 (*processProc) (iceConn,
342 processMsgInfo->client_data, header->minorOpcode,
343 header->length, iceConn->swap,
344 useThisReplyWait, &replyReady);
351 _IceSetReplyReady (iceConn, useThisReplyWait);
356 * Now we check if the reply is ready for the replyWait passed
357 * into IceProcessMessages. The replyWait is removed from the
358 * replyWait list if it is ready.
362 *replyReadyRet = _IceCheckReplyReady (iceConn, replyWait);
366 * Decrement the dispatch level. If we reach level 0, and the
367 * free_asap bit is set, free the connection now. Also check for
368 * possible bad IO status.
371 iceConn->dispatch_level--;
373 if (iceConn->dispatch_level == 0 && iceConn->free_asap)
375 _IceFreeConnection (iceConn);
376 retStatus = IceProcessMessagesConnectionClosed;
378 else if (!iceConn->io_ok)
380 iceConn->connection_status = IceConnectIOError;
381 retStatus = IceProcessMessagesIOError;
397 iceAuthRequiredMsg *pMsg;
399 IceGetHeader (iceConn, 0, ICE_AuthRequired,
400 SIZEOF (iceAuthRequiredMsg), iceAuthRequiredMsg, pMsg);
402 pMsg->authIndex = authIndex;
403 pMsg->authDataLength = authDataLen;
404 pMsg->length += WORD64COUNT (authDataLen);
406 IceWriteData (iceConn, authDataLen, (char *) authData);
408 if (PAD64 (authDataLen))
409 IceWritePad (iceConn, PAD64 (authDataLen));
423 iceAuthReplyMsg *pMsg;
425 IceGetHeader (iceConn, 0, ICE_AuthReply,
426 SIZEOF (iceAuthReplyMsg), iceAuthReplyMsg, pMsg);
428 pMsg->authDataLength = authDataLen;
429 pMsg->length += WORD64COUNT (authDataLen);
431 IceWriteData (iceConn, authDataLen, (char *) authData);
433 if (PAD64 (authDataLen))
434 IceWritePad (iceConn, PAD64 (authDataLen));
448 iceAuthNextPhaseMsg *pMsg;
450 IceGetHeader (iceConn, 0, ICE_AuthNextPhase,
451 SIZEOF (iceAuthNextPhaseMsg), iceAuthNextPhaseMsg, pMsg);
453 pMsg->authDataLength = authDataLen;
454 pMsg->length += WORD64COUNT (authDataLen);
456 IceWriteData (iceConn, authDataLen, (char *) authData);
458 if (PAD64 (authDataLen))
459 IceWritePad (iceConn, PAD64 (authDataLen));
472 iceConnectionReplyMsg *pMsg;
476 extra = STRING_BYTES (IceVendorString) + STRING_BYTES (IceReleaseString);
478 IceGetHeaderExtra (iceConn, 0, ICE_ConnectionReply,
479 SIZEOF (iceConnectionReplyMsg), WORD64COUNT (extra),
480 iceConnectionReplyMsg, pMsg, pData);
482 pMsg->versionIndex = versionIndex;
484 STORE_STRING (pData, IceVendorString);
485 STORE_STRING (pData, IceReleaseString);
489 iceConn->connection_status = IceConnectAccepted;
504 iceProtocolReplyMsg *pMsg;
508 extra = STRING_BYTES (vendor) + STRING_BYTES (release);
510 IceGetHeaderExtra (iceConn, 0, ICE_ProtocolReply,
511 SIZEOF (iceProtocolReplyMsg), WORD64COUNT (extra),
512 iceProtocolReplyMsg, pMsg, pData);
514 pMsg->protocolOpcode = myOpcode;
515 pMsg->versionIndex = versionIndex;
517 STORE_STRING (pData, vendor);
518 STORE_STRING (pData, release);
524 * We may be using a different major opcode for this protocol
525 * than the other client. Whenever we get a message, we must
526 * map to our own major opcode.
529 _IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode);
539 IceSimpleMessage (iceConn, 0, ICE_PingReply);
548 unsigned long length,
550 IceReplyWaitInfo *replyWait
553 int invokeHandler = 0;
554 Bool errorReturned = False;
555 iceErrorMsg *message;
556 char *pData, *pStart;
559 CHECK_AT_LEAST_SIZE (iceConn, ICE_Error,
560 length, SIZEOF (iceErrorMsg),
561 (iceConn->connect_to_you || iceConn->connect_to_me) ?
562 IceFatalToConnection : IceFatalToProtocol);
564 IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg),
565 iceErrorMsg, message, pStart);
567 if (!IceValidIO (iceConn))
569 IceDisposeCompleteMessage (iceConn, pStart);
573 severity = message->severity;
575 if (severity != IceCanContinue && severity != IceFatalToProtocol &&
576 severity != IceFatalToConnection)
578 _IceErrorBadValue (iceConn, 0,
579 ICE_Error, 9, 1, &severity);
580 IceDisposeCompleteMessage (iceConn, pStart);
588 message->errorClass = lswaps (message->errorClass);
589 message->offendingSequenceNum = lswapl (message->offendingSequenceNum);
593 message->offendingSequenceNum != replyWait->sequence_of_request)
599 if (iceConn->connect_to_you &&
600 ((!iceConn->connect_to_you->auth_active &&
601 message->offendingMinorOpcode == ICE_ConnectionSetup) ||
602 (iceConn->connect_to_you->auth_active &&
603 message->offendingMinorOpcode == ICE_AuthReply)))
605 _IceConnectionError *errorReply =
606 &(((_IceReply *) (replyWait->reply))->connection_error);
607 char *errorStr = NULL;
612 errorReturned = True;
614 switch (message->errorClass)
619 "None of the ICE versions specified are supported";
620 errorStr = strdup(tempstr);
626 "None of the authentication protocols specified are supported";
627 errorStr = strdup(tempstr);
632 prefix = "Connection Setup Failed, reason : ";
634 EXTRACT_STRING (pData, swap, temp);
635 errorStr = (char *) malloc (
636 strlen (prefix) + strlen (temp) + 1);
637 sprintf (errorStr, "%s%s", prefix, temp);
641 case IceAuthRejected:
643 prefix = "Authentication Rejected, reason : ";
644 EXTRACT_STRING (pData, swap, temp);
645 errorStr = (char *) malloc (
646 strlen (prefix) + strlen (temp) + 1);
647 sprintf (errorStr, "%s%s", prefix, temp);
653 prefix = "Authentication Failed, reason : ";
654 EXTRACT_STRING (pData, swap, temp);
655 errorStr = (char *) malloc (
656 strlen (prefix) + strlen (temp) + 1);
657 sprintf (errorStr, "%s%s", prefix, temp);
665 errorReply->type = ICE_CONNECTION_ERROR;
666 errorReply->error_message = errorStr;
668 else if (iceConn->protosetup_to_you &&
669 ((!iceConn->protosetup_to_you->auth_active &&
670 message->offendingMinorOpcode == ICE_ProtocolSetup) ||
671 (iceConn->protosetup_to_you->auth_active &&
672 message->offendingMinorOpcode == ICE_AuthReply)))
674 _IceProtocolError *errorReply =
675 &(((_IceReply *) (replyWait->reply))->protocol_error);
680 errorReturned = True;
682 switch (message->errorClass)
687 "None of the protocol versions specified are supported";
688 errorStr = strdup(temp);
694 "None of the authentication protocols specified are supported";
695 errorStr = strdup(temp);
700 prefix = "Protocol Setup Failed, reason : ";
702 EXTRACT_STRING (pData, swap, temp);
703 errorStr = (char *) malloc (
704 strlen (prefix) + strlen (temp) + 1);
705 sprintf (errorStr, "%s%s", prefix, temp);
709 case IceAuthRejected:
711 prefix = "Authentication Rejected, reason : ";
712 EXTRACT_STRING (pData, swap, temp);
713 errorStr = (char *) malloc (
714 strlen (prefix) + strlen (temp) + 1);
715 sprintf (errorStr, "%s%s", prefix, temp);
721 prefix = "Authentication Failed, reason : ";
722 EXTRACT_STRING (pData, swap, temp);
723 errorStr = (char *) malloc (
724 strlen (prefix) + strlen (temp) + 1);
725 sprintf (errorStr, "%s%s", prefix, temp);
729 case IceProtocolDuplicate:
731 prefix = "Protocol was already registered : ";
732 EXTRACT_STRING (pData, swap, temp);
733 errorStr = (char *) malloc (
734 strlen (prefix) + strlen (temp) + 1);
735 sprintf (errorStr, "%s%s", prefix, temp);
739 case IceMajorOpcodeDuplicate:
741 prefix = "The major opcode was already used : ";
742 errorStr = (char *) malloc (strlen (prefix) + 2);
743 sprintf (errorStr, "%s%d", prefix, (int) *pData);
746 case IceUnknownProtocol:
748 prefix = "Unknown Protocol : ";
749 EXTRACT_STRING (pData, swap, temp);
750 errorStr = (char *) malloc (
751 strlen (prefix) + strlen (temp) + 1);
752 sprintf (errorStr, "%s%s", prefix, temp);
760 errorReply->type = ICE_PROTOCOL_ERROR;
761 errorReply->error_message = errorStr;
764 if (errorReturned == True)
767 * If we tried to authenticate, tell the authentication
768 * procedure to clean up.
771 IcePoAuthProc authProc;
773 if (iceConn->connect_to_you &&
774 iceConn->connect_to_you->auth_active)
776 authProc = _IcePoAuthProcs[(int)
777 (iceConn->connect_to_you->my_auth_index)];
779 (*authProc) (iceConn, &iceConn->connect_to_you->my_auth_state,
780 True /* clean up */, False /* swap */,
781 0, NULL, NULL, NULL, NULL);
783 else if (iceConn->protosetup_to_you &&
784 iceConn->protosetup_to_you->auth_active)
786 _IcePoProtocol *protocol = _IceProtocols[
787 iceConn->protosetup_to_you->my_opcode - 1].orig_client;
789 authProc = protocol->auth_procs[(int)(iceConn->
790 protosetup_to_you->my_auth_index)];
792 (*authProc) (iceConn,
793 &iceConn->protosetup_to_you->my_auth_state,
794 True /* clean up */, False /* swap */,
795 0, NULL, NULL, NULL, NULL);
802 (*_IceErrorHandler) (iceConn, swap, message->offendingMinorOpcode,
803 message->offendingSequenceNum, message->errorClass,
804 message->severity, (IcePointer) pData);
807 IceDisposeCompleteMessage (iceConn, pStart);
809 return (errorReturned);
815 ProcessConnectionSetup (
817 unsigned long length,
821 iceConnectionSetupMsg *message;
822 int myVersionCount, hisVersionCount;
823 int myVersionIndex, hisVersionIndex;
824 int hisMajorVersion, hisMinorVersion;
825 int myAuthCount, hisAuthCount;
827 char *myAuthName, **hisAuthNames = NULL;
828 char *pData, *pStart, *pEnd;
830 char *release = NULL;
832 int hisAuthIndex = 0;
833 int accept_setup_now = 0;
834 char mustAuthenticate;
836 int authUsableFlags[MAX_ICE_AUTH_NAMES];
837 int authIndices[MAX_ICE_AUTH_NAMES];
839 CHECK_AT_LEAST_SIZE (iceConn, ICE_ConnectionSetup,
840 length, SIZEOF (iceConnectionSetupMsg), IceFatalToConnection);
842 IceReadCompleteMessage (iceConn, SIZEOF (iceConnectionSetupMsg),
843 iceConnectionSetupMsg, message, pStart);
845 if (!IceValidIO (iceConn))
847 IceDisposeCompleteMessage (iceConn, pStart);
852 pEnd = pStart + (length << 3);
854 SKIP_STRING (pData, swap, pEnd,
855 BAIL_STRING(iceConn, ICE_ConnectionSetup,
856 pStart)); /* vendor */
857 SKIP_STRING (pData, swap, pEnd,
858 BAIL_STRING(iceConn, ICE_ConnectionSetup,
859 pStart)); /* release */
860 SKIP_LISTOF_STRING (pData, swap, (int) message->authCount, pEnd,
861 BAIL_STRING(iceConn, ICE_ConnectionSetup,
862 pStart)); /* auth names */
864 pData += (message->versionCount * 4); /* versions */
866 CHECK_COMPLETE_SIZE (iceConn, ICE_ConnectionSetup,
867 length, pData - pStart + SIZEOF (iceConnectionSetupMsg),
868 pStart, IceFatalToConnection);
870 mustAuthenticate = message->mustAuthenticate;
871 if (mustAuthenticate != 0 && mustAuthenticate != 1)
873 _IceErrorBadValue (iceConn, 0,
874 ICE_ConnectionSetup, 8, 1, &mustAuthenticate);
875 iceConn->connection_status = IceConnectRejected;
876 IceDisposeCompleteMessage (iceConn, pStart);
882 EXTRACT_STRING (pData, swap, vendor);
883 EXTRACT_STRING (pData, swap, release);
885 if ((hisAuthCount = message->authCount) > 0)
887 hisAuthNames = (char **) malloc (hisAuthCount * sizeof (char *));
888 EXTRACT_LISTOF_STRING (pData, swap, hisAuthCount, hisAuthNames);
891 hisVersionCount = message->versionCount;
892 myVersionCount = _IceVersionCount;
894 hisVersionIndex = myVersionIndex = found = 0;
896 for (i = 0; i < hisVersionCount && !found; i++)
898 EXTRACT_CARD16 (pData, swap, hisMajorVersion);
899 EXTRACT_CARD16 (pData, swap, hisMinorVersion);
901 for (j = 0; j < myVersionCount && !found; j++)
903 if (_IceVersions[j].major_version == hisMajorVersion &&
904 _IceVersions[j].minor_version == hisMinorVersion)
915 _IceErrorNoVersion (iceConn, ICE_ConnectionSetup);
916 iceConn->connection_status = IceConnectRejected;
921 if (hisAuthCount > 0)
923 for (i = 0; i < hisAuthCount; i++)
924 free (hisAuthNames[i]);
926 free ((char *) hisAuthNames);
929 IceDisposeCompleteMessage (iceConn, pStart);
933 _IceGetPaValidAuthIndices ("ICE", iceConn->connection_string,
934 _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices);
936 for (i = 0; i < _IceAuthCount; i++)
938 authUsableFlags[i] = 0;
939 for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
940 authUsableFlags[i] = (authIndices[j] == i);
943 myAuthCount = _IceAuthCount;
945 for (i = found = 0; i < myAuthCount && !found; i++)
947 if (authUsableFlags[i])
949 myAuthName = _IceAuthNames[i];
951 for (j = 0; j < hisAuthCount && !found; j++)
952 if (strcmp (myAuthName, hisAuthNames[j]) == 0)
964 * None of the authentication methods specified by the
965 * other client is supported. If the other client requires
966 * authentication, we must reject the connection now.
967 * Otherwise, we can invoke the host-based authentication callback
968 * to see if we can accept this connection.
971 if (mustAuthenticate || !iceConn->listen_obj->host_based_auth_proc)
973 _IceErrorNoAuthentication (iceConn, ICE_ConnectionSetup);
974 iceConn->connection_status = IceConnectRejected;
978 char *hostname = _IceGetPeerName (iceConn);
980 if ((*iceConn->listen_obj->host_based_auth_proc) (hostname))
982 accept_setup_now = 1;
986 _IceErrorAuthenticationRejected (iceConn,
987 ICE_ConnectionSetup, "None of the authentication protocols specified are supported and host-based authentication failed");
989 iceConn->connection_status = IceConnectRejected;
996 if (iceConn->connection_status == IceConnectRejected)
1004 IcePaAuthStatus status;
1006 IcePointer authData = NULL;
1007 IcePointer authState;
1008 char *errorString = NULL;
1009 IcePaAuthProc authProc = _IcePaAuthProcs[myAuthIndex];
1013 status = (*authProc) (iceConn, &authState,
1014 swap, 0, NULL, &authDataLen, &authData, &errorString);
1016 if (status == IcePaAuthContinue)
1018 _IceConnectToMeInfo *setupInfo;
1020 AuthRequired (iceConn, hisAuthIndex, authDataLen, authData);
1022 iceConn->connect_to_me = setupInfo = (_IceConnectToMeInfo *)
1023 malloc (sizeof (_IceConnectToMeInfo));
1025 setupInfo->my_version_index = myVersionIndex;
1026 setupInfo->his_version_index = hisVersionIndex;
1027 setupInfo->his_vendor = vendor;
1028 setupInfo->his_release = release;
1029 setupInfo->my_auth_index = myAuthIndex;
1030 setupInfo->my_auth_state = authState;
1031 setupInfo->must_authenticate = mustAuthenticate;
1033 else if (status == IcePaAuthAccepted)
1035 accept_setup_now = 1;
1038 if (authData && authDataLen > 0)
1039 free ((char *) authData);
1045 if (accept_setup_now)
1047 AcceptConnection (iceConn, hisVersionIndex);
1049 iceConn->vendor = vendor;
1050 iceConn->release = release;
1051 iceConn->my_ice_version_index = myVersionIndex;
1054 if (hisAuthCount > 0)
1056 for (i = 0; i < hisAuthCount; i++)
1057 free (hisAuthNames[i]);
1059 free ((char *) hisAuthNames);
1062 IceDisposeCompleteMessage (iceConn, pStart);
1069 ProcessAuthRequired (
1071 unsigned long length,
1073 IceReplyWaitInfo *replyWait
1076 iceAuthRequiredMsg *message;
1078 IcePointer authData;
1080 IcePointer replyData = NULL;
1081 char *errorString = NULL;
1082 IcePoAuthProc authProc;
1083 IcePoAuthStatus status;
1084 IcePointer authState;
1085 int realAuthIndex = 0;
1087 CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthRequired,
1088 length, SIZEOF (iceAuthRequiredMsg),
1089 iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
1091 IceReadCompleteMessage (iceConn, SIZEOF (iceAuthRequiredMsg),
1092 iceAuthRequiredMsg, message, authData);
1094 if (!IceValidIO (iceConn))
1096 IceDisposeCompleteMessage (iceConn, authData);
1102 message->authDataLength = lswaps (message->authDataLength);
1105 CHECK_COMPLETE_SIZE (iceConn, ICE_AuthRequired, length,
1106 message->authDataLength + SIZEOF (iceAuthRequiredMsg), authData,
1107 iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
1109 if (iceConn->connect_to_you)
1111 if ((int) message->authIndex >= _IceAuthCount)
1113 _IceConnectionError *errorReply =
1114 &(((_IceReply *) (replyWait->reply))->connection_error);
1117 = "Received bad authIndex in the AuthRequired message";
1118 char errIndex = (int) message->authIndex;
1120 errorString = strdup(tempstr);
1122 errorReply->type = ICE_CONNECTION_ERROR;
1123 errorReply->error_message = errorString;
1125 _IceErrorBadValue (iceConn, 0,
1126 ICE_AuthRequired, 2, 1, &errIndex);
1128 IceDisposeCompleteMessage (iceConn, authData);
1133 authProc = _IcePoAuthProcs[message->authIndex];
1135 iceConn->connect_to_you->auth_active = 1;
1138 else if (iceConn->protosetup_to_you)
1140 if ((int) message->authIndex >=
1141 iceConn->protosetup_to_you->my_auth_count)
1143 _IceProtocolError *errorReply =
1144 &(((_IceReply *) (replyWait->reply))->protocol_error);
1147 = "Received bad authIndex in the AuthRequired message";
1148 char errIndex = (int) message->authIndex;
1150 errorString = strdup(tempstr);
1152 errorReply->type = ICE_PROTOCOL_ERROR;
1153 errorReply->error_message = errorString;
1155 _IceErrorBadValue (iceConn, 0,
1156 ICE_AuthRequired, 2, 1, &errIndex);
1158 IceDisposeCompleteMessage (iceConn, authData);
1163 _IcePoProtocol *myProtocol = _IceProtocols[
1164 iceConn->protosetup_to_you->my_opcode - 1].orig_client;
1166 realAuthIndex = iceConn->protosetup_to_you->
1167 my_auth_indices[message->authIndex];
1169 authProc = myProtocol->auth_procs[realAuthIndex];
1171 iceConn->protosetup_to_you->auth_active = 1;
1177 * Unexpected message
1180 _IceErrorBadState (iceConn, 0, ICE_AuthRequired, IceCanContinue);
1182 IceDisposeCompleteMessage (iceConn, authData);
1187 authDataLen = message->authDataLength;
1189 status = (*authProc) (iceConn, &authState, False /* don't clean up */,
1190 swap, authDataLen, authData, &replyDataLen, &replyData, &errorString);
1192 if (status == IcePoAuthHaveReply)
1194 AuthReply (iceConn, replyDataLen, replyData);
1196 replyWait->sequence_of_request = iceConn->send_sequence;
1197 replyWait->minor_opcode_of_request = ICE_AuthReply;
1199 if (iceConn->connect_to_you)
1201 iceConn->connect_to_you->my_auth_state = authState;
1202 iceConn->connect_to_you->my_auth_index = message->authIndex;
1204 else if (iceConn->protosetup_to_you)
1206 iceConn->protosetup_to_you->my_auth_state = authState;
1207 iceConn->protosetup_to_you->my_auth_index = realAuthIndex;
1210 else if (status == IcePoAuthRejected || status == IcePoAuthFailed)
1212 char *prefix, *returnErrorString;
1214 if (status == IcePoAuthRejected)
1216 _IceErrorAuthenticationRejected (iceConn,
1217 ICE_AuthRequired, errorString);
1219 prefix = "Authentication Rejected, reason : ";
1223 _IceErrorAuthenticationFailed (iceConn,
1224 ICE_AuthRequired, errorString);
1226 prefix = "Authentication Failed, reason : ";
1229 returnErrorString = (char *) malloc (strlen (prefix) +
1230 strlen (errorString) + 1);
1231 sprintf (returnErrorString, "%s%s", prefix, errorString);
1234 if (iceConn->connect_to_you)
1236 _IceConnectionError *errorReply =
1237 &(((_IceReply *) (replyWait->reply))->connection_error);
1239 errorReply->type = ICE_CONNECTION_ERROR;
1240 errorReply->error_message = returnErrorString;
1244 _IceProtocolError *errorReply =
1245 &(((_IceReply *) (replyWait->reply))->protocol_error);
1247 errorReply->type = ICE_PROTOCOL_ERROR;
1248 errorReply->error_message = returnErrorString;
1252 if (replyData && replyDataLen > 0)
1253 free ((char *) replyData);
1255 IceDisposeCompleteMessage (iceConn, authData);
1257 return (status != IcePoAuthHaveReply);
1265 unsigned long length,
1269 iceAuthReplyMsg *message;
1271 IcePointer replyData;
1273 IcePointer authData = NULL;
1274 char *errorString = NULL;
1276 CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthReply,
1277 length, SIZEOF (iceAuthReplyMsg),
1278 iceConn->connect_to_me ? IceFatalToConnection : IceFatalToProtocol);
1280 IceReadCompleteMessage (iceConn, SIZEOF (iceAuthReplyMsg),
1281 iceAuthReplyMsg, message, replyData);
1283 if (!IceValidIO (iceConn))
1285 IceDisposeCompleteMessage (iceConn, replyData);
1291 message->authDataLength = lswaps (message->authDataLength);
1294 CHECK_COMPLETE_SIZE (iceConn, ICE_AuthReply, length,
1295 message->authDataLength + SIZEOF (iceAuthReplyMsg), replyData,
1296 iceConn->connect_to_me ? IceFatalToConnection : IceFatalToProtocol);
1298 replyDataLen = message->authDataLength;
1300 if (iceConn->connect_to_me)
1302 IcePaAuthProc authProc = _IcePaAuthProcs[(int)
1303 (iceConn->connect_to_me->my_auth_index)];
1304 IcePaAuthStatus status =
1305 (*authProc) (iceConn, &iceConn->connect_to_me->my_auth_state, swap,
1306 replyDataLen, replyData, &authDataLen, &authData, &errorString);
1308 if (status == IcePaAuthContinue)
1310 AuthNextPhase (iceConn, authDataLen, authData);
1312 else if (status == IcePaAuthRejected || status == IcePaAuthFailed)
1315 * Before we reject, invoke host-based authentication callback
1316 * and give it a chance to accept the connection (only if the
1317 * other client doesn't require authentication).
1320 if (!iceConn->connect_to_me->must_authenticate &&
1321 iceConn->listen_obj->host_based_auth_proc)
1323 char *hostname = _IceGetPeerName (iceConn);
1325 if ((*iceConn->listen_obj->host_based_auth_proc) (hostname))
1327 status = IcePaAuthAccepted;
1334 if (status != IcePaAuthAccepted)
1336 free (iceConn->connect_to_me->his_vendor);
1337 free (iceConn->connect_to_me->his_release);
1338 free ((char *) iceConn->connect_to_me);
1339 iceConn->connect_to_me = NULL;
1341 iceConn->connection_status = IceConnectRejected;
1343 if (status == IcePaAuthRejected)
1345 _IceErrorAuthenticationRejected (iceConn,
1346 ICE_AuthReply, errorString);
1350 _IceErrorAuthenticationFailed (iceConn,
1351 ICE_AuthReply, errorString);
1356 if (status == IcePaAuthAccepted)
1358 AcceptConnection (iceConn,
1359 iceConn->connect_to_me->his_version_index);
1361 iceConn->vendor = iceConn->connect_to_me->his_vendor;
1362 iceConn->release = iceConn->connect_to_me->his_release;
1363 iceConn->my_ice_version_index =
1364 iceConn->connect_to_me->my_version_index;
1366 free ((char *) iceConn->connect_to_me);
1367 iceConn->connect_to_me = NULL;
1370 else if (iceConn->protosetup_to_me)
1372 _IcePaProtocol *myProtocol = _IceProtocols[iceConn->protosetup_to_me->
1373 my_opcode - 1].accept_client;
1374 IcePaAuthProc authProc = myProtocol->auth_procs[(int)
1375 (iceConn->protosetup_to_me->my_auth_index)];
1376 IcePaAuthStatus status =
1377 (*authProc) (iceConn, &iceConn->protosetup_to_me->my_auth_state,
1378 swap, replyDataLen, replyData,
1379 &authDataLen, &authData, &errorString);
1380 int free_setup_info = 1;
1382 if (status == IcePaAuthContinue)
1384 AuthNextPhase (iceConn, authDataLen, authData);
1385 free_setup_info = 0;
1387 else if (status == IcePaAuthRejected || status == IcePaAuthFailed)
1390 * Before we reject, invoke host-based authentication callback
1391 * and give it a chance to accept the Protocol Setup (only if the
1392 * other client doesn't require authentication).
1395 if (!iceConn->protosetup_to_me->must_authenticate &&
1396 myProtocol->host_based_auth_proc)
1398 char *hostname = _IceGetPeerName (iceConn);
1400 if ((*myProtocol->host_based_auth_proc) (hostname))
1402 status = IcePaAuthAccepted;
1409 if (status == IcePaAuthRejected)
1411 _IceErrorAuthenticationRejected (iceConn,
1412 ICE_AuthReply, errorString);
1416 _IceErrorAuthenticationFailed (iceConn,
1417 ICE_AuthReply, errorString);
1421 if (status == IcePaAuthAccepted)
1423 IcePaProcessMsgProc processMsgProc;
1424 IceProtocolSetupProc protocolSetupProc;
1425 IceProtocolActivateProc protocolActivateProc;
1426 _IceProcessMsgInfo *process_msg_info;
1427 IcePointer clientData = NULL;
1428 char *failureReason = NULL;
1431 protocolSetupProc = myProtocol->protocol_setup_proc;
1432 protocolActivateProc = myProtocol->protocol_activate_proc;
1434 if (protocolSetupProc)
1437 * Notify the client of the Protocol Setup.
1440 status = (*protocolSetupProc) (iceConn,
1441 myProtocol->version_recs[iceConn->protosetup_to_me->
1442 my_version_index].major_version,
1443 myProtocol->version_recs[iceConn->protosetup_to_me->
1444 my_version_index].minor_version,
1445 iceConn->protosetup_to_me->his_vendor,
1446 iceConn->protosetup_to_me->his_release,
1447 &clientData, &failureReason);
1450 * Set vendor and release pointers to NULL, so it won't
1451 * get freed below. The ProtocolSetupProc should
1455 iceConn->protosetup_to_me->his_vendor = NULL;
1456 iceConn->protosetup_to_me->his_release = NULL;
1462 * Send the Protocol Reply
1465 AcceptProtocol (iceConn,
1466 iceConn->protosetup_to_me->his_opcode,
1467 iceConn->protosetup_to_me->my_opcode,
1468 iceConn->protosetup_to_me->his_version_index,
1469 myProtocol->vendor, myProtocol->release);
1473 * Set info for this protocol.
1476 processMsgProc = myProtocol->version_recs[
1477 iceConn->protosetup_to_me->
1478 my_version_index].process_msg_proc;
1480 process_msg_info = &iceConn->process_msg_info[
1481 iceConn->protosetup_to_me->
1482 his_opcode -iceConn->his_min_opcode];
1484 process_msg_info->client_data = clientData;
1485 process_msg_info->accept_flag = 1;
1486 process_msg_info->process_msg_proc.
1487 accept_client = processMsgProc;
1491 * Increase the reference count for the number
1492 * of active protocols.
1495 iceConn->proto_ref_count++;
1499 * Notify the client that the protocol is active. The reason
1500 * we have this 2nd callback invoked is because the client
1501 * may wish to immediately generate a message for this
1502 * protocol, but it must wait until we send the Protocol Reply.
1505 if (protocolActivateProc)
1507 (*protocolActivateProc) (iceConn,
1508 process_msg_info->client_data);
1514 * An error was encountered.
1517 _IceErrorSetupFailed (iceConn, ICE_ProtocolSetup,
1521 free (failureReason);
1526 if (free_setup_info)
1528 if (iceConn->protosetup_to_me->his_vendor)
1529 free (iceConn->protosetup_to_me->his_vendor);
1530 if (iceConn->protosetup_to_me->his_release)
1531 free (iceConn->protosetup_to_me->his_release);
1532 free ((char *) iceConn->protosetup_to_me);
1533 iceConn->protosetup_to_me = NULL;
1539 * Unexpected message
1542 _IceErrorBadState (iceConn, 0, ICE_AuthReply, IceCanContinue);
1545 if (authData && authDataLen > 0)
1546 free ((char *) authData);
1551 IceDisposeCompleteMessage (iceConn, replyData);
1558 ProcessAuthNextPhase (
1560 unsigned long length,
1562 IceReplyWaitInfo *replyWait
1565 iceAuthNextPhaseMsg *message;
1567 IcePointer authData;
1569 IcePointer replyData = NULL;
1570 char *errorString = NULL;
1571 IcePoAuthProc authProc;
1572 IcePoAuthStatus status;
1573 IcePointer *authState;
1575 CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthNextPhase,
1576 length, SIZEOF (iceAuthNextPhaseMsg),
1577 iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
1579 IceReadCompleteMessage (iceConn, SIZEOF (iceAuthNextPhaseMsg),
1580 iceAuthNextPhaseMsg, message, authData);
1582 if (!IceValidIO (iceConn))
1584 IceDisposeCompleteMessage (iceConn, authData);
1590 message->authDataLength = lswaps (message->authDataLength);
1593 CHECK_COMPLETE_SIZE (iceConn, ICE_AuthNextPhase, length,
1594 message->authDataLength + SIZEOF (iceAuthNextPhaseMsg), authData,
1595 iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
1597 if (iceConn->connect_to_you)
1599 authProc = _IcePoAuthProcs[(int)
1600 (iceConn->connect_to_you->my_auth_index)];
1602 authState = &iceConn->connect_to_you->my_auth_state;
1604 else if (iceConn->protosetup_to_you)
1606 _IcePoProtocol *myProtocol =
1607 _IceProtocols[iceConn->protosetup_to_you->my_opcode - 1].orig_client;
1609 authProc = myProtocol->auth_procs[(int)
1610 (iceConn->protosetup_to_you->my_auth_index)];
1612 authState = &iceConn->protosetup_to_you->my_auth_state;
1617 * Unexpected message
1620 _IceErrorBadState (iceConn, 0, ICE_AuthNextPhase, IceCanContinue);
1622 IceDisposeCompleteMessage (iceConn, authData);
1626 authDataLen = message->authDataLength;
1628 status = (*authProc) (iceConn, authState, False /* don't clean up */,
1629 swap, authDataLen, authData, &replyDataLen, &replyData, &errorString);
1631 if (status == IcePoAuthHaveReply)
1633 AuthReply (iceConn, replyDataLen, replyData);
1635 replyWait->sequence_of_request = iceConn->send_sequence;
1637 else if (status == IcePoAuthRejected || status == IcePoAuthFailed)
1639 char *prefix = NULL, *returnErrorString;
1641 if (status == IcePoAuthRejected)
1643 _IceErrorAuthenticationRejected (iceConn,
1644 ICE_AuthNextPhase, errorString);
1646 prefix = "Authentication Rejected, reason : ";
1648 else if (status == IcePoAuthFailed)
1650 _IceErrorAuthenticationFailed (iceConn,
1651 ICE_AuthNextPhase, errorString);
1653 prefix = "Authentication Failed, reason : ";
1656 returnErrorString = (char *) malloc (strlen (prefix) +
1657 strlen (errorString) + 1);
1658 sprintf (returnErrorString, "%s%s", prefix, errorString);
1661 if (iceConn->connect_to_you)
1663 _IceConnectionError *errorReply =
1664 &(((_IceReply *) (replyWait->reply))->connection_error);
1666 errorReply->type = ICE_CONNECTION_ERROR;
1667 errorReply->error_message = returnErrorString;
1671 _IceProtocolError *errorReply =
1672 &(((_IceReply *) (replyWait->reply))->protocol_error);
1674 errorReply->type = ICE_PROTOCOL_ERROR;
1675 errorReply->error_message = returnErrorString;
1679 if (replyData && replyDataLen > 0)
1680 free ((char *) replyData);
1682 IceDisposeCompleteMessage (iceConn, authData);
1684 return (status != IcePoAuthHaveReply);
1690 ProcessConnectionReply (
1692 unsigned long length,
1694 IceReplyWaitInfo *replyWait
1697 iceConnectionReplyMsg *message;
1698 char *pData, *pStart, *pEnd;
1702 CHECK_AT_LEAST_SIZE (iceConn, ICE_ConnectionReply,
1703 length, SIZEOF (iceConnectionReplyMsg), IceFatalToConnection);
1706 IceReadCompleteMessage (iceConn, SIZEOF (iceConnectionReplyMsg),
1707 iceConnectionReplyMsg, message, pStart);
1709 if (!IceValidIO (iceConn))
1711 IceDisposeCompleteMessage (iceConn, pStart);
1716 pEnd = pStart + (length << 3);
1718 SKIP_STRING (pData, swap, pEnd,
1719 BAIL_STRING (iceConn, ICE_ConnectionReply,
1720 pStart)); /* vendor */
1721 SKIP_STRING (pData, swap, pEnd,
1722 BAIL_STRING (iceConn, ICE_ConnectionReply,
1723 pStart)); /* release */
1725 CHECK_COMPLETE_SIZE (iceConn, ICE_ConnectionReply,
1726 length, pData - pStart + SIZEOF (iceConnectionReplyMsg),
1727 pStart, IceFatalToConnection);
1731 if (iceConn->connect_to_you)
1733 if (iceConn->connect_to_you->auth_active)
1736 * Tell the authentication procedure to clean up.
1739 IcePoAuthProc authProc = _IcePoAuthProcs[(int)
1740 (iceConn->connect_to_you->my_auth_index)];
1742 (*authProc) (iceConn, &iceConn->connect_to_you->my_auth_state,
1743 True /* clean up */, False /* swap */,
1744 0, NULL, NULL, NULL, NULL);
1747 if ((int) message->versionIndex >= _IceVersionCount)
1749 _IceConnectionError *errorReply =
1750 &(((_IceReply *) (replyWait->reply))->connection_error);
1751 char errIndex = message->versionIndex;
1753 _IceErrorBadValue (iceConn, 0,
1754 ICE_ConnectionReply, 2, 1, &errIndex);
1756 errorReply->type = ICE_CONNECTION_ERROR;
1757 errorReply->error_message =
1758 "Received bad version index in Connection Reply";
1762 _IceReply *reply = (_IceReply *) (replyWait->reply);
1764 reply->type = ICE_CONNECTION_REPLY;
1765 reply->connection_reply.version_index = message->versionIndex;
1767 EXTRACT_STRING (pData, swap, reply->connection_reply.vendor);
1768 EXTRACT_STRING (pData, swap, reply->connection_reply.release);
1776 * Unexpected message
1779 _IceErrorBadState (iceConn, 0, ICE_ConnectionReply, IceCanContinue);
1784 IceDisposeCompleteMessage (iceConn, pStart);
1786 return (replyReady);
1792 ProcessProtocolSetup (
1794 unsigned long length,
1798 iceProtocolSetupMsg *message;
1799 _IcePaProtocol *myProtocol;
1800 int myVersionCount, hisVersionCount;
1801 int myVersionIndex, hisVersionIndex;
1802 int hisMajorVersion, hisMinorVersion;
1803 int myAuthCount, hisAuthCount;
1804 int myOpcode, hisOpcode;
1806 char *myAuthName, **hisAuthNames = NULL;
1808 char *pData, *pStart, *pEnd;
1809 char *vendor = NULL;
1810 char *release = NULL;
1811 int accept_setup_now = 0;
1812 int myAuthIndex = 0;
1813 int hisAuthIndex = 0;
1814 char mustAuthenticate;
1815 int authUsableCount;
1816 int authUsableFlags[MAX_ICE_AUTH_NAMES];
1817 int authIndices[MAX_ICE_AUTH_NAMES];
1819 CHECK_AT_LEAST_SIZE (iceConn, ICE_ProtocolSetup,
1820 length, SIZEOF (iceProtocolSetupMsg), IceFatalToProtocol);
1822 if (iceConn->want_to_close)
1825 * If we sent a WantToClose message, but just got a ProtocolSetup,
1826 * we must cancel our WantToClose. It is the responsiblity of the
1827 * other client to send a WantToClose later on.
1830 iceConn->want_to_close = 0;
1833 IceReadCompleteMessage (iceConn, SIZEOF (iceProtocolSetupMsg),
1834 iceProtocolSetupMsg, message, pStart);
1836 if (!IceValidIO (iceConn))
1838 IceDisposeCompleteMessage (iceConn, pStart);
1843 pEnd = pStart + (length << 3);
1845 SKIP_STRING (pData, swap, pEnd,
1846 BAIL_STRING(iceConn, ICE_ProtocolSetup,
1847 pStart)); /* proto name */
1848 SKIP_STRING (pData, swap, pEnd,
1849 BAIL_STRING(iceConn, ICE_ProtocolSetup,
1850 pStart)); /* vendor */
1851 SKIP_STRING (pData, swap, pEnd,
1852 BAIL_STRING(iceConn, ICE_ProtocolSetup,
1853 pStart)); /* release */
1854 SKIP_LISTOF_STRING (pData, swap, (int) message->authCount, pEnd,
1855 BAIL_STRING(iceConn, ICE_ProtocolSetup,
1856 pStart)); /* auth names */
1857 pData += (message->versionCount * 4); /* versions */
1859 CHECK_COMPLETE_SIZE (iceConn, ICE_ProtocolSetup,
1860 length, pData - pStart + SIZEOF (iceProtocolSetupMsg),
1861 pStart, IceFatalToProtocol);
1863 mustAuthenticate = message->mustAuthenticate;
1865 if (mustAuthenticate != 0 && mustAuthenticate != 1)
1867 _IceErrorBadValue (iceConn, 0,
1868 ICE_ProtocolSetup, 4, 1, &mustAuthenticate);
1869 IceDisposeCompleteMessage (iceConn, pStart);
1875 if (iceConn->process_msg_info &&
1876 (int) message->protocolOpcode >= iceConn->his_min_opcode &&
1877 (int) message->protocolOpcode <= iceConn->his_max_opcode &&
1878 iceConn->process_msg_info[
1879 message->protocolOpcode - iceConn->his_min_opcode].in_use)
1881 _IceErrorMajorOpcodeDuplicate (iceConn, message->protocolOpcode);
1882 IceDisposeCompleteMessage (iceConn, pStart);
1886 EXTRACT_STRING (pData, swap, protocolName);
1888 if (iceConn->process_msg_info)
1891 i <= (iceConn->his_max_opcode - iceConn->his_min_opcode); i++)
1893 if (iceConn->process_msg_info[i].in_use && strcmp (protocolName,
1894 iceConn->process_msg_info[i].protocol->protocol_name) == 0)
1896 _IceErrorProtocolDuplicate (iceConn, protocolName);
1897 free (protocolName);
1898 IceDisposeCompleteMessage (iceConn, pStart);
1904 for (i = 0; i < _IceLastMajorOpcode; i++)
1905 if (strcmp (protocolName, _IceProtocols[i].protocol_name) == 0)
1908 if (i < _IceLastMajorOpcode &&
1909 (myProtocol = _IceProtocols[i].accept_client) != NULL)
1911 hisOpcode = message->protocolOpcode;
1913 free (protocolName);
1917 _IceErrorUnknownProtocol (iceConn, protocolName);
1918 free (protocolName);
1919 IceDisposeCompleteMessage (iceConn, pStart);
1923 EXTRACT_STRING (pData, swap, vendor);
1924 EXTRACT_STRING (pData, swap, release);
1926 if ((hisAuthCount = message->authCount) > 0)
1928 hisAuthNames = (char **) malloc (hisAuthCount * sizeof (char *));
1929 EXTRACT_LISTOF_STRING (pData, swap, hisAuthCount, hisAuthNames);
1932 hisVersionCount = message->versionCount;
1933 myVersionCount = myProtocol->version_count;
1935 hisVersionIndex = myVersionIndex = found = 0;
1937 for (i = 0; i < hisVersionCount && !found; i++)
1939 EXTRACT_CARD16 (pData, swap, hisMajorVersion);
1940 EXTRACT_CARD16 (pData, swap, hisMinorVersion);
1942 for (j = 0; j < myVersionCount && !found; j++)
1944 if (myProtocol->version_recs[j].major_version == hisMajorVersion &&
1945 myProtocol->version_recs[j].minor_version == hisMinorVersion)
1947 hisVersionIndex = i;
1956 _IceErrorNoVersion (iceConn, ICE_ProtocolSetup);
1961 if (hisAuthCount > 0)
1963 for (i = 0; i < hisAuthCount; i++)
1964 free (hisAuthNames[i]);
1966 free ((char *) hisAuthNames);
1969 IceDisposeCompleteMessage (iceConn, pStart);
1973 myAuthCount = myProtocol->auth_count;
1975 _IceGetPaValidAuthIndices (
1976 _IceProtocols[myOpcode - 1].protocol_name,
1977 iceConn->connection_string, myAuthCount, myProtocol->auth_names,
1978 &authUsableCount, authIndices);
1980 for (i = 0; i < myAuthCount; i++)
1982 authUsableFlags[i] = 0;
1983 for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
1984 authUsableFlags[i] = (authIndices[j] == i);
1987 for (i = found = 0; i < myAuthCount && !found; i++)
1989 if (authUsableFlags[i])
1991 myAuthName = myProtocol->auth_names[i];
1993 for (j = 0; j < hisAuthCount && !found; j++)
1994 if (strcmp (myAuthName, hisAuthNames[j]) == 0)
2006 * None of the authentication methods specified by the
2007 * other client is supported. If the other client requires
2008 * authentication, we must reject the Protocol Setup now.
2009 * Otherwise, we can invoke the host-based authentication callback
2010 * to see if we can accept this Protocol Setup.
2013 if (mustAuthenticate || !myProtocol->host_based_auth_proc)
2015 _IceErrorNoAuthentication (iceConn, ICE_ProtocolSetup);
2019 char *hostname = _IceGetPeerName (iceConn);
2021 if ((*myProtocol->host_based_auth_proc) (hostname))
2023 accept_setup_now = 1;
2027 _IceErrorAuthenticationRejected (iceConn,
2028 ICE_ProtocolSetup, "None of the authentication protocols specified are supported and host-based authentication failed");
2037 IcePaAuthStatus status;
2039 IcePointer authData = NULL;
2040 IcePointer authState;
2041 char *errorString = NULL;
2042 IcePaAuthProc authProc =
2043 myProtocol->auth_procs[myAuthIndex];
2047 status = (*authProc) (iceConn, &authState, swap, 0, NULL,
2048 &authDataLen, &authData, &errorString);
2050 if (status == IcePaAuthContinue)
2052 _IceProtoSetupToMeInfo *setupInfo;
2054 AuthRequired (iceConn, hisAuthIndex, authDataLen, authData);
2056 iceConn->protosetup_to_me = setupInfo =
2057 (_IceProtoSetupToMeInfo *) malloc (
2058 sizeof (_IceProtoSetupToMeInfo));
2060 setupInfo->his_opcode = hisOpcode;
2061 setupInfo->my_opcode = myOpcode;
2062 setupInfo->my_version_index = myVersionIndex;
2063 setupInfo->his_version_index = hisVersionIndex;
2064 setupInfo->his_vendor = vendor;
2065 setupInfo->his_release = release;
2066 vendor = release = NULL; /* so we don't free it */
2067 setupInfo->my_auth_index = myAuthIndex;
2068 setupInfo->my_auth_state = authState;
2069 setupInfo->must_authenticate = mustAuthenticate;
2071 else if (status == IcePaAuthAccepted)
2073 accept_setup_now = 1;
2076 if (authData && authDataLen > 0)
2077 free ((char *) authData);
2083 if (accept_setup_now)
2085 IcePaProcessMsgProc processMsgProc;
2086 IceProtocolSetupProc protocolSetupProc;
2087 IceProtocolActivateProc protocolActivateProc;
2088 _IceProcessMsgInfo *process_msg_info;
2089 IcePointer clientData = NULL;
2090 char *failureReason = NULL;
2093 protocolSetupProc = myProtocol->protocol_setup_proc;
2094 protocolActivateProc = myProtocol->protocol_activate_proc;
2096 if (protocolSetupProc)
2099 * Notify the client of the Protocol Setup.
2102 status = (*protocolSetupProc) (iceConn,
2103 myProtocol->version_recs[myVersionIndex].major_version,
2104 myProtocol->version_recs[myVersionIndex].minor_version,
2105 vendor, release, &clientData, &failureReason);
2107 vendor = release = NULL; /* so we don't free it */
2113 * Send the Protocol Reply
2116 AcceptProtocol (iceConn, hisOpcode, myOpcode, hisVersionIndex,
2117 myProtocol->vendor, myProtocol->release);
2121 * Set info for this protocol.
2124 processMsgProc = myProtocol->version_recs[
2125 myVersionIndex].process_msg_proc;
2127 process_msg_info = &iceConn->process_msg_info[hisOpcode -
2128 iceConn->his_min_opcode];
2130 process_msg_info->client_data = clientData;
2131 process_msg_info->accept_flag = 1;
2132 process_msg_info->process_msg_proc.accept_client = processMsgProc;
2136 * Increase the reference count for the number of active protocols.
2139 iceConn->proto_ref_count++;
2143 * Notify the client that the protocol is active. The reason
2144 * we have this 2nd callback invoked is because the client
2145 * may wish to immediately generate a message for this
2146 * protocol, but it must wait until we send the Protocol Reply.
2149 if (protocolActivateProc)
2151 (*protocolActivateProc) (iceConn,
2152 process_msg_info->client_data);
2158 * An error was encountered.
2161 _IceErrorSetupFailed (iceConn, ICE_ProtocolSetup, failureReason);
2164 free (failureReason);
2174 if (hisAuthCount > 0)
2176 for (i = 0; i < hisAuthCount; i++)
2177 free (hisAuthNames[i]);
2179 free ((char *) hisAuthNames);
2182 IceDisposeCompleteMessage (iceConn, pStart);
2189 ProcessProtocolReply (
2191 unsigned long length,
2193 IceReplyWaitInfo *replyWait
2196 iceProtocolReplyMsg *message;
2197 char *pData, *pStart, *pEnd;
2201 CHECK_AT_LEAST_SIZE (iceConn, ICE_ProtocolReply,
2202 length, SIZEOF (iceProtocolReplyMsg), IceFatalToProtocol);
2205 IceReadCompleteMessage (iceConn, SIZEOF (iceProtocolReplyMsg),
2206 iceProtocolReplyMsg, message, pStart);
2208 if (!IceValidIO (iceConn))
2210 IceDisposeCompleteMessage (iceConn, pStart);
2215 pEnd = pStart + (length << 3);
2217 SKIP_STRING (pData, swap, pEnd,
2218 BAIL_STRING(iceConn, ICE_ProtocolReply,
2219 pStart)); /* vendor */
2220 SKIP_STRING (pData, swap, pEnd,
2221 BAIL_STRING(iceConn, ICE_ProtocolReply,
2222 pStart)); /* release */
2224 CHECK_COMPLETE_SIZE (iceConn, ICE_ProtocolReply,
2225 length, pData - pStart + SIZEOF (iceProtocolReplyMsg),
2226 pStart, IceFatalToProtocol);
2230 if (iceConn->protosetup_to_you)
2232 if (iceConn->protosetup_to_you->auth_active)
2235 * Tell the authentication procedure to clean up.
2238 _IcePoProtocol *myProtocol = _IceProtocols[
2239 iceConn->protosetup_to_you->my_opcode - 1].orig_client;
2241 IcePoAuthProc authProc = myProtocol->auth_procs[(int)
2242 (iceConn->protosetup_to_you->my_auth_index)];
2247 * authProc is never NULL, but the cc compiler on UNIX System V/386
2248 * Release 4.2 Version 1 screws up an optimization. Unless there is
2249 * some sort of reference to authProc before the function call, the
2250 * function call will seg fault.
2254 (*authProc) (iceConn,
2255 &iceConn->protosetup_to_you->my_auth_state,
2256 True /* clean up */, False /* swap */,
2257 0, NULL, NULL, NULL, NULL);
2260 if ((int) message->versionIndex >= _IceVersionCount)
2262 _IceProtocolError *errorReply =
2263 &(((_IceReply *) (replyWait->reply))->protocol_error);
2264 char errIndex = message->versionIndex;
2266 _IceErrorBadValue (iceConn, 0,
2267 ICE_ProtocolReply, 2, 1, &errIndex);
2269 errorReply->type = ICE_PROTOCOL_ERROR;
2270 errorReply->error_message =
2271 "Received bad version index in Protocol Reply";
2275 _IceProtocolReply *reply =
2276 &(((_IceReply *) (replyWait->reply))->protocol_reply);
2278 reply->type = ICE_PROTOCOL_REPLY;
2279 reply->major_opcode = message->protocolOpcode;
2280 reply->version_index = message->versionIndex;
2282 EXTRACT_STRING (pData, swap, reply->vendor);
2283 EXTRACT_STRING (pData, swap, reply->release);
2290 _IceErrorBadState (iceConn, 0, ICE_ProtocolReply, IceCanContinue);
2295 IceDisposeCompleteMessage (iceConn, pStart);
2297 return (replyReady);
2305 unsigned long length
2308 CHECK_SIZE_MATCH (iceConn, ICE_Ping,
2309 length, SIZEOF (icePingMsg), IceFatalToConnection, 0);
2311 PingReply (iceConn);
2321 unsigned long length
2324 CHECK_SIZE_MATCH (iceConn, ICE_PingReply,
2325 length, SIZEOF (icePingReplyMsg), IceFatalToConnection, 0);
2327 if (iceConn->ping_waits)
2329 _IcePingWait *next = iceConn->ping_waits->next;
2331 (*iceConn->ping_waits->ping_reply_proc) (iceConn,
2332 iceConn->ping_waits->client_data);
2334 free ((char *) iceConn->ping_waits);
2335 iceConn->ping_waits = next;
2339 _IceErrorBadState (iceConn, 0, ICE_PingReply, IceCanContinue);
2348 ProcessWantToClose (
2350 unsigned long length,
2351 Bool *connectionClosedRet
2354 *connectionClosedRet = False;
2356 CHECK_SIZE_MATCH (iceConn, ICE_WantToClose,
2357 length, SIZEOF (iceWantToCloseMsg), IceFatalToConnection, 0);
2359 if (iceConn->want_to_close || iceConn->open_ref_count == 0)
2362 * We just received a WantToClose. Either we also sent a
2363 * WantToClose, so we close the connection, or the iceConn
2364 * is not being used, so we close the connection. This
2365 * second case is possible if we sent a WantToClose because
2366 * the iceConn->open_ref_count reached zero, but then we
2367 * received a NoClose.
2370 _IceConnectionClosed (iceConn); /* invoke watch procs */
2371 _IceFreeConnection (iceConn);
2372 *connectionClosedRet = True;
2374 else if (iceConn->proto_ref_count > 0)
2377 * We haven't shut down all of our protocols yet. We send a NoClose,
2378 * and it's up to us to generate a WantToClose later on.
2381 IceSimpleMessage (iceConn, 0, ICE_NoClose);
2387 * The reference count on this iceConn is zero. This means that
2388 * there are no active protocols, but the client didn't explicitly
2389 * close the connection yet. If we didn't just send a Protocol Setup,
2390 * we send a NoClose, and it's up to us to generate a WantToClose
2394 if (!iceConn->protosetup_to_you)
2396 IceSimpleMessage (iceConn, 0, ICE_NoClose);
2409 unsigned long length
2412 CHECK_SIZE_MATCH (iceConn, ICE_NoClose,
2413 length, SIZEOF (iceNoCloseMsg), IceFatalToConnection, 0);
2415 if (iceConn->want_to_close)
2418 * The other side can't close now. We cancel our WantToClose,
2419 * and we can expect a WantToClose from the other side.
2422 iceConn->want_to_close = 0;
2426 _IceErrorBadState (iceConn, 0, ICE_NoClose, IceCanContinue);
2435 _IceProcessCoreMessage (
2438 unsigned long length,
2440 IceReplyWaitInfo *replyWait,
2441 Bool *replyReadyRet,
2442 Bool *connectionClosedRet
2445 Bool replyReady = False;
2447 *connectionClosedRet = False;
2453 replyReady = ProcessError (iceConn, length, swap, replyWait);
2456 case ICE_ConnectionSetup:
2458 ProcessConnectionSetup (iceConn, length, swap);
2461 case ICE_AuthRequired:
2463 replyReady = ProcessAuthRequired (iceConn, length, swap, replyWait);
2468 ProcessAuthReply (iceConn, length, swap);
2471 case ICE_AuthNextPhase:
2473 replyReady = ProcessAuthNextPhase (iceConn, length, swap, replyWait);
2476 case ICE_ConnectionReply:
2478 replyReady = ProcessConnectionReply (iceConn, length, swap, replyWait);
2481 case ICE_ProtocolSetup:
2483 ProcessProtocolSetup (iceConn, length, swap);
2486 case ICE_ProtocolReply:
2488 replyReady = ProcessProtocolReply (iceConn, length, swap, replyWait);
2493 ProcessPing (iceConn, length);
2498 ProcessPingReply (iceConn, length);
2501 case ICE_WantToClose:
2503 ProcessWantToClose (iceConn, length, connectionClosedRet);
2508 ProcessNoClose (iceConn, length);
2513 _IceErrorBadMinor (iceConn, 0, opcode, IceCanContinue);
2514 _IceReadSkip (iceConn, length << 3);
2519 *replyReadyRet = replyReady;
2522 int _IceVersionCount = 1;
2523 _IceVersion _IceVersions[] = {
2524 {IceProtoMajor, IceProtoMinor, _IceProcessCoreMessage}};