Attachment #26588: proposed patch, see comments below. for bug #56924

View | Details | Raw Unified | Return to bug 56924
Collapse All | Expand All

(-)ssl3con.c (-9 / +12 lines)
Line     Link Here 
 Lines 1327-1332    Link Here 
1327
1327
1328
	    if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
1328
	    if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
1329
1329
1330
		ss->handshakeBegun = 1;
1330
		count = ssl_SendSavedWriteData(ss, &ss->pendingBuf,
1331
		count = ssl_SendSavedWriteData(ss, &ss->pendingBuf,
1331
		                               &ssl_DefSend);
1332
		                               &ssl_DefSend);
1332
		if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
1333
		if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) {
 Lines 1335-1340    Link Here 
1335
		}
1336
		}
1336
	    }
1337
	    }
1337
	} else if (write->len > 0) {
1338
	} else if (write->len > 0) {
1339
	    ss->handshakeBegun = 1;
1338
	    count = ssl_DefSend(ss, write->buf, write->len,
1340
	    count = ssl_DefSend(ss, write->buf, write->len,
1339
				flags & ~ssl_SEND_FLAG_MASK);
1341
				flags & ~ssl_SEND_FLAG_MASK);
1340
	    if (count < 0) {
1342
	    if (count < 0) {
 Lines 1455-1466    Link Here 
1455
    /* If the server has required client-auth blindly but doesn't
1457
    /* If the server has required client-auth blindly but doesn't
1456
     * actually look at the certificate it won't know that no
1458
     * actually look at the certificate it won't know that no
1457
     * certificate was presented so we shutdown the socket to ensure
1459
     * certificate was presented so we shutdown the socket to ensure
1458
     * an error.  We only do this if we aren't connected because
1460
     * an error.  We only do this if we haven't already completed the
1459
     * if we're redoing the handshake we know the server is paying
1461
     * first handshake because if we're redoing the handshake we 
1460
     * attention to the certificate.
1462
     * know the server is paying attention to the certificate.
1461
     */
1463
     */
1462
    if ((ss->requireCertificate == 1) ||
1464
    if ((ss->requireCertificate == 1) ||
1463
	(!ss->connected && (ss->requireCertificate > 1))) {
1465
	(!ss->firstHsDone && (ss->requireCertificate > 1))) {
1464
	PRFileDesc * lower;
1466
	PRFileDesc * lower;
1465
1467
1466
	ss->sec->uncache(ss->sec->ci.sid);
1468
	ss->sec->uncache(ss->sec->ci.sid);
 Lines 4616-4622    Link Here 
4616
	 */
4618
	 */
4617
	if ((sid->peerCert == NULL) && ss->requestCertificate &&
4619
	if ((sid->peerCert == NULL) && ss->requestCertificate &&
4618
	    ((ss->requireCertificate == 1) ||
4620
	    ((ss->requireCertificate == 1) ||
4619
	     ((ss->requireCertificate == 2) && !ss->connected))) {
4621
	     ((ss->requireCertificate == 2) && !ss->firstHsDone))) {
4620
4622
4621
	    ++ssl3stats.hch_sid_cache_not_ok;
4623
	    ++ssl3stats.hch_sid_cache_not_ok;
4622
	    ss->sec->uncache(sid);
4624
	    ss->sec->uncache(sid);
 Lines 6494-6502    Link Here 
6494
6496
6495
    ssl_ReleaseXmitBufLock(ss);	/*************************************/
6497
    ssl_ReleaseXmitBufLock(ss);	/*************************************/
6496
6498
6497
    /* we're connected now. */
6499
    /* The first handshake is now completed. */
6498
    ss->handshake           = NULL;
6500
    ss->handshake           = NULL;
6499
    ss->connected           = PR_TRUE;
6501
    ss->firstHsDone         = PR_TRUE;
6500
    ss->gather->writeOffset = 0;
6502
    ss->gather->writeOffset = 0;
6501
    ss->gather->readOffset  = 0;
6503
    ss->gather->readOffset  = 0;
6502
6504
 Lines 7445-7451    Link Here 
7445
}
7447
}
7446
7448
7447
/*
7449
/*
7448
** If ssl3 socket is connected and in idle state, then start a new handshake.
7450
** If ssl3 socket has completed the first handshake, and is in idle state, 
7451
** then start a new handshake.
7449
** If flushCache is true, the SID cache will be flushed first, forcing a
7452
** If flushCache is true, the SID cache will be flushed first, forcing a
7450
** "Full" handshake (not a session restart handshake), to be done.
7453
** "Full" handshake (not a session restart handshake), to be done.
7451
**
7454
**
 Lines 7460-7466    Link Here 
7460
7463
7461
    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
7464
    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
7462
7465
7463
    if (!ss->connected ||
7466
    if (!ss->firstHsDone ||
7464
        ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
7467
        ((ss->version >= SSL_LIBRARY_VERSION_3_0) &&
7465
	 ss->ssl3 && (ss->ssl3->hs.ws != idle_handshake))) {
7468
	 ss->ssl3 && (ss->ssl3->hs.ws != idle_handshake))) {
7466
	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
7469
	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
(-)sslauth.c (-1 / +1 lines)
Line     Link Here 
 Lines 84-90    Link Here 
84
	*op = SSL_SECURITY_STATUS_OFF;
84
	*op = SSL_SECURITY_STATUS_OFF;
85
    }
85
    }
86
86
87
    if (ss->useSecurity && ss->connected) {
87
    if (ss->useSecurity && ss->firstHsDone) {
88
	PORT_Assert(ss->sec != 0);
88
	PORT_Assert(ss->sec != 0);
89
	sec = ss->sec;
89
	sec = ss->sec;
90
90
(-)sslcon.c (+3 lines)
Line     Link Here 
 Lines 546-551    Link Here 
546
546
547
    SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
547
    SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
548
548
549
    ss->handshakeBegun = 1;
549
    rv = (*sec->send)(ss, msg, sizeof(msg), 0);
550
    rv = (*sec->send)(ss, msg, sizeof(msg), 0);
550
    if (rv >= 0) {
551
    if (rv >= 0) {
551
	rv = SECSuccess;
552
	rv = SECSuccess;
 Lines 3102-3107    Link Here 
3102
3103
3103
    /* Send it to the server */
3104
    /* Send it to the server */
3104
    DUMP_MSG(29, (ss, msg, sendLen));
3105
    DUMP_MSG(29, (ss, msg, sendLen));
3106
    ss->handshakeBegun = 1;
3105
    rv = (*sec->send)(ss, msg, sendLen, 0);
3107
    rv = (*sec->send)(ss, msg, sendLen, 0);
3106
3108
3107
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
3109
    ssl_ReleaseXmitBufLock(ss);    /***************************************/
 Lines 3595-3600    Link Here 
3595
3597
3596
    DUMP_MSG(29, (ss, msg, sendLen));
3598
    DUMP_MSG(29, (ss, msg, sendLen));
3597
3599
3600
    ss->handshakeBegun = 1;
3598
    sent = (*sec->send)(ss, msg, sendLen, 0);
3601
    sent = (*sec->send)(ss, msg, sendLen, 0);
3599
    if (sent < 0) {
3602
    if (sent < 0) {
3600
	goto loser;
3603
	goto loser;
(-)ssldef.c (-1 / +7 lines)
Line     Link Here 
 Lines 32-38    Link Here 
32
 * may use your version of this file under either the MPL or the
32
 * may use your version of this file under either the MPL or the
33
 * GPL.
33
 * GPL.
34
 *
34
 *
35
 * $Id: ssldef.c,v 1.2 2000/10/07 02:22:22 nelsonb%netscape.com Exp $
35
 * $Id: ssldef.c,v 1.1 2001/02/09 19:40:18 nelsonb Exp nelsonb $
36
 */
36
 */
37
37
38
#include "cert.h"
38
#include "cert.h"
 Lines 115-122    Link Here 
115
	if (rv < 0) {
115
	if (rv < 0) {
116
	    PRErrorCode err = PR_GetError();
116
	    PRErrorCode err = PR_GetError();
117
	    if (err == PR_WOULD_BLOCK_ERROR) {
117
	    if (err == PR_WOULD_BLOCK_ERROR) {
118
		ss->lastWriteBlocked = 1;
118
		return count ? count : rv;
119
		return count ? count : rv;
119
	    }
120
	    }
121
	    ss->lastWriteBlocked = 0;
120
	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
122
	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
121
	    /* Loser */
123
	    /* Loser */
122
	    return rv;
124
	    return rv;
 Lines 130-135    Link Here 
130
	}
132
	}
131
	break;
133
	break;
132
    }
134
    }
135
    ss->lastWriteBlocked = 0;
133
    return count;
136
    return count;
134
}
137
}
135
138
 Lines 157-164    Link Here 
157
	if (rv < 0) {
160
	if (rv < 0) {
158
	    PRErrorCode err = PR_GetError();
161
	    PRErrorCode err = PR_GetError();
159
	    if (err == PR_WOULD_BLOCK_ERROR) {
162
	    if (err == PR_WOULD_BLOCK_ERROR) {
163
		ss->lastWriteBlocked = 1;
160
		return count ? count : rv;
164
		return count ? count : rv;
161
	    }
165
	    }
166
	    ss->lastWriteBlocked = 0;
162
	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
167
	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
163
	    /* Loser */
168
	    /* Loser */
164
	    return rv;
169
	    return rv;
 Lines 172-177    Link Here 
172
	}
177
	}
173
	break;
178
	break;
174
    }
179
    }
180
    ss->lastWriteBlocked = 0;
175
    return count;
181
    return count;
176
}
182
}
177
183
(-)sslgathr.c (-2 / +2 lines)
Line     Link Here 
 Lines 139-145    Link Here 
139
	/* Probably finished this piece */
139
	/* Probably finished this piece */
140
	switch (gs->state) {
140
	switch (gs->state) {
141
	case GS_HEADER: 
141
	case GS_HEADER: 
142
	    if ((ss->enableSSL3 || ss->enableTLS) && !ss->connected) {
142
	    if ((ss->enableSSL3 || ss->enableTLS) && !ss->firstHsDone) {
143
143
144
		PORT_Assert( ssl_Have1stHandshakeLock(ss) );
144
		PORT_Assert( ssl_Have1stHandshakeLock(ss) );
145
145
 Lines 183-189    Link Here 
183
			return SECFailure;
183
			return SECFailure;
184
		    }
184
		    }
185
		}
185
		}
186
	    }	/* ((ss->enableSSL3 || ss->enableTLS) && !ss->connected) */
186
	    }	/* ((ss->enableSSL3 || ss->enableTLS) && !ss->firstHsDone) */
187
187
188
	    /* we've got the first 3 bytes.  The header may be two or three. */
188
	    /* we've got the first 3 bytes.  The header may be two or three. */
189
	    if (gs->hdr[0] & 0x80) {
189
	    if (gs->hdr[0] & 0x80) {
(-)sslimpl.h (-4 / +14 lines)
Line     Link Here 
 Lines 33-39    Link Here 
33
 * may use your version of this file under either the MPL or the
33
 * may use your version of this file under either the MPL or the
34
 * GPL.
34
 * GPL.
35
 *
35
 *
36
 * $Id: sslimpl.h,v 1.10 2001/02/07 17:50:43 wtc%netscape.com Exp $
36
 * $Id: sslimpl.h,v 1.3 2001/02/09 19:40:18 nelsonb Exp nelsonb $
37
 */
37
 */
38
38
39
#ifndef __sslimpl_h_
39
#ifndef __sslimpl_h_
 Lines 238-243    Link Here 
238
    unsigned int detectRollBack  	: 1;  /* 14 */
238
    unsigned int detectRollBack  	: 1;  /* 14 */
239
} sslOptions;
239
} sslOptions;
240
240
241
typedef enum { sslHandshakingUndetermined = 0,
242
	       sslHandshakingAsClient,
243
	       sslHandshakingAsServer 
244
} sslHandshakingType;
245
241
/*
246
/*
242
** SSL Socket struct
247
** SSL Socket struct
243
**
248
**
 Lines 254-273    Link Here 
254
    unsigned int     useSecurity	: 1;
259
    unsigned int     useSecurity	: 1;
255
    unsigned int     requestCertificate	: 1;
260
    unsigned int     requestCertificate	: 1;
256
    unsigned int     requireCertificate	: 2;
261
    unsigned int     requireCertificate	: 2;
257
258
    unsigned int     handshakeAsClient	: 1;
262
    unsigned int     handshakeAsClient	: 1;
259
    unsigned int     handshakeAsServer	: 1;
263
    unsigned int     handshakeAsServer	: 1;
260
    unsigned int     enableSSL2		: 1;
264
    unsigned int     enableSSL2		: 1;
265
261
    unsigned int     enableSSL3		: 1;
266
    unsigned int     enableSSL3		: 1;
262
    unsigned int     enableTLS		: 1;
267
    unsigned int     enableTLS		: 1;
263
264
    unsigned int     clientAuthRequested: 1;
268
    unsigned int     clientAuthRequested: 1;
265
    unsigned int     noCache		: 1;
269
    unsigned int     noCache		: 1;
266
    unsigned int     fdx		: 1; /* simultaneous read/write threads */
270
    unsigned int     fdx		: 1; /* simultaneous read/write threads */
267
    unsigned int     v2CompatibleHello	: 1; /* Send v3+ client hello in v2 format */
271
    unsigned int     v2CompatibleHello	: 1; /* Send v3+ client hello in v2 format */
268
    unsigned int     detectRollBack   	: 1; /* Detect rollback to SSL v3 */
272
    unsigned int     detectRollBack   	: 1; /* Detect rollback to SSL v3 */
269
    unsigned int     connected		: 1; /* initial handshake is complete. */
273
    unsigned int     firstHsDone	: 1; /* first handshake is complete. */
274
270
    unsigned int     recvdCloseNotify	: 1; /* received SSL EOF. */
275
    unsigned int     recvdCloseNotify	: 1; /* received SSL EOF. */
276
    unsigned int     lastWriteBlocked   : 1;
277
    unsigned int     TCPconnected       : 1;
278
    unsigned int     handshakeBegun     : 1;
271
279
272
    /* version of the protocol to use */
280
    /* version of the protocol to use */
273
    SSL3ProtocolVersion version;
281
    SSL3ProtocolVersion version;
 Lines 352-357    Link Here 
352
    PRUint16	allowedByPolicy;          /* copy of global policy bits. */
360
    PRUint16	allowedByPolicy;          /* copy of global policy bits. */
353
    PRUint16	maybeAllowedByPolicy;     /* copy of global policy bits. */
361
    PRUint16	maybeAllowedByPolicy;     /* copy of global policy bits. */
354
    PRUint16	chosenPreference;         /* SSL2 cipher preferences. */
362
    PRUint16	chosenPreference;         /* SSL2 cipher preferences. */
363
364
    sslHandshakingType handshaking;
355
365
356
    ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
366
    ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED];
357
367
(-)sslsecur.c (-35 / +44 lines)
Line     Link Here 
 Lines 143-154    Link Here 
143
	    /* for v3 this is done in ssl3_HandleFinished() */
143
	    /* for v3 this is done in ssl3_HandleFinished() */
144
	    if ((ss->sec != NULL) &&               /* used SSL */
144
	    if ((ss->sec != NULL) &&               /* used SSL */
145
	        (ss->handshakeCallback != NULL) && /* has callback */
145
	        (ss->handshakeCallback != NULL) && /* has callback */
146
		(!ss->connected) &&                /* only first time */
146
		(!ss->firstHsDone) &&              /* only first time */
147
		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
147
		(ss->version < SSL_LIBRARY_VERSION_3_0)) {  /* not ssl3 */
148
		ss->connected       = PR_TRUE;
148
		ss->firstHsDone     = PR_TRUE;
149
		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
149
		(ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData);
150
	    }
150
	    }
151
	    ss->connected           = PR_TRUE;
151
	    ss->firstHsDone         = PR_TRUE;
152
	    ss->gather->writeOffset = 0;
152
	    ss->gather->writeOffset = 0;
153
	    ss->gather->readOffset  = 0;
153
	    ss->gather->readOffset  = 0;
154
	    break;
154
	    break;
 Lines 187-193    Link Here 
187
void
187
void
188
ssl_SetAlwaysBlock(sslSocket *ss)
188
ssl_SetAlwaysBlock(sslSocket *ss)
189
{
189
{
190
    if (!ss->connected) {
190
    if (!ss->firstHsDone) {
191
	ss->handshake = AlwaysBlock;
191
	ss->handshake = AlwaysBlock;
192
	ss->nextHandshake = 0;
192
	ss->nextHandshake = 0;
193
    }
193
    }
 Lines 200-205    Link Here 
200
{
200
{
201
    sslSocket *ss;
201
    sslSocket *ss;
202
    SECStatus rv;
202
    SECStatus rv;
203
    PRNetAddr addr;
203
204
204
    ss = ssl_FindSocket(s);
205
    ss = ssl_FindSocket(s);
205
    if (!ss) {
206
    if (!ss) {
 Lines 218-226    Link Here 
218
    ssl_Get1stHandshakeLock(ss);
219
    ssl_Get1stHandshakeLock(ss);
219
    ssl_GetSSL3HandshakeLock(ss);
220
    ssl_GetSSL3HandshakeLock(ss);
220
221
221
    ss->connected = PR_FALSE;
222
    ss->firstHsDone = PR_FALSE;
222
    ss->handshake = asServer ? ssl2_BeginServerHandshake
223
    if ( asServer ) {
223
	                     : ssl2_BeginClientHandshake;
224
	ss->securityHandshake = ssl2_BeginServerHandshake;
225
	ss->handshaking = sslHandshakingAsServer;
226
    } else {
227
	ss->securityHandshake = ssl2_BeginClientHandshake;
228
	ss->handshaking = sslHandshakingAsClient;
229
    }
224
    ss->nextHandshake       = 0;
230
    ss->nextHandshake       = 0;
225
    ss->securityHandshake   = 0;
231
    ss->securityHandshake   = 0;
226
232
 Lines 244-249    Link Here 
244
    ssl_ReleaseSSL3HandshakeLock(ss);
250
    ssl_ReleaseSSL3HandshakeLock(ss);
245
    ssl_Release1stHandshakeLock(ss);
251
    ssl_Release1stHandshakeLock(ss);
246
252
253
    if (!ss->TCPconnected)
254
	ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
255
247
    SSL_UNLOCK_WRITER(ss);
256
    SSL_UNLOCK_WRITER(ss);
248
    SSL_UNLOCK_READER(ss);
257
    SSL_UNLOCK_READER(ss);
249
258
 Lines 369-378    Link Here 
369
	} else if (gatherResult == SECWouldBlock) {
378
	} else if (gatherResult == SECWouldBlock) {
370
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
379
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
371
	}
380
	}
372
    } else if (!ss->connected) {
381
    } else if (!ss->firstHsDone) {
373
	rv = ssl_Do1stHandshake(ss);
382
	rv = ssl_Do1stHandshake(ss);
374
    } else {
383
    } else {
375
	/* tried to force handshake on a connected SSL 2 socket. */
384
	/* tried to force handshake on an SSL 2 socket that has 
385
	** already completed the handshake. */
376
    	rv = SECSuccess;	/* just pretend we did it. */
386
    	rv = SECSuccess;	/* just pretend we did it. */
377
    }
387
    }
378
388
 Lines 882-913    Link Here 
882
892
883
    PORT_Assert(ss->sec != 0);
893
    PORT_Assert(ss->sec != 0);
884
894
885
    /* First connect to server */
886
    rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
887
    if (rv < 0) {
888
	int olderrno = PR_GetError();
889
	SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
890
		 SSL_GETPID(), ss->fd, olderrno));
891
	if ((olderrno == PR_IS_CONNECTED_ERROR) ||
892
	    (olderrno == PR_IN_PROGRESS_ERROR)) {
893
	    /*
894
	    ** Connected or trying to connect.  Caller is Using a non-blocking
895
	    ** connect. Go ahead and set things up.
896
	    */
897
	} else {
898
	    return rv;
899
	}
900
    }
901
902
    SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, setting up handshake",
903
		SSL_GETPID(), ss->fd));
904
905
    if ( ss->handshakeAsServer ) {
895
    if ( ss->handshakeAsServer ) {
906
	ss->securityHandshake = ssl2_BeginServerHandshake;
896
	ss->securityHandshake = ssl2_BeginServerHandshake;
897
	ss->handshaking = sslHandshakingAsServer;
907
    } else {
898
    } else {
908
	ss->securityHandshake = ssl2_BeginClientHandshake;
899
	ss->securityHandshake = ssl2_BeginClientHandshake;
900
	ss->handshaking = sslHandshakingAsClient;
909
    }
901
    }
910
    
902
903
    /* connect to server */
904
    rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
905
    if (rv == PR_SUCCESS) {
906
	ss->TCPconnected = 1;
907
    } else {
908
	int err = PR_GetError();
909
	SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
910
		 SSL_GETPID(), ss->fd, err));
911
	if (err == PR_IS_CONNECTED_ERROR) {
912
	    ss->TCPconnected = 1;
913
	} 
914
    }
915
916
    SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d",
917
		SSL_GETPID(), ss->fd, rv));
911
    return rv;
918
    return rv;
912
}
919
}
913
920
 Lines 917-924    Link Here 
917
    int rv;
924
    int rv;
918
925
919
    if (ss->version >= SSL_LIBRARY_VERSION_3_0 	&&
926
    if (ss->version >= SSL_LIBRARY_VERSION_3_0 	&&
920
    	ss->connected 				&& 
927
    	ss->firstHsDone 			&& 
921
	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)	&&
928
	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)	&&
929
	!ss->recvdCloseNotify                   &&
922
	(ss->ssl3 != NULL)) {
930
	(ss->ssl3 != NULL)) {
923
931
924
	(void) SSL3_SendAlert(ss, alert_warning, close_notify);
932
	(void) SSL3_SendAlert(ss, alert_warning, close_notify);
 Lines 943-949    Link Here 
943
    if ((sslHow & ssl_SHUTDOWN_SEND) != 0 		&&
951
    if ((sslHow & ssl_SHUTDOWN_SEND) != 0 		&&
944
	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)		&&
952
	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)		&&
945
    	(ss->version >= SSL_LIBRARY_VERSION_3_0)	&&
953
    	(ss->version >= SSL_LIBRARY_VERSION_3_0)	&&
946
	ss->connected 					&& 
954
	ss->firstHsDone 				&& 
955
	!ss->recvdCloseNotify                   	&&
947
	(ss->ssl3 != NULL)) {
956
	(ss->ssl3 != NULL)) {
948
957
949
	(void) SSL3_SendAlert(ss, alert_warning, close_notify);
958
	(void) SSL3_SendAlert(ss, alert_warning, close_notify);
 Lines 992-998    Link Here 
992
    
1001
    
993
    rv = 0;
1002
    rv = 0;
994
    /* If any of these is non-zero, the initial handshake is not done. */
1003
    /* If any of these is non-zero, the initial handshake is not done. */
995
    if (!ss->connected) {
1004
    if (!ss->firstHsDone) {
996
	ssl_Get1stHandshakeLock(ss);
1005
	ssl_Get1stHandshakeLock(ss);
997
	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
1006
	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
998
	    rv = ssl_Do1stHandshake(ss);
1007
	    rv = ssl_Do1stHandshake(ss);
 Lines 1054-1060    Link Here 
1054
    if (len > 0) 
1063
    if (len > 0) 
1055
    	ss->writerThread = PR_GetCurrentThread();
1064
    	ss->writerThread = PR_GetCurrentThread();
1056
    /* If any of these is non-zero, the initial handshake is not done. */
1065
    /* If any of these is non-zero, the initial handshake is not done. */
1057
    if (!ss->connected) {
1066
    if (!ss->firstHsDone) {
1058
	ssl_Get1stHandshakeLock(ss);
1067
	ssl_Get1stHandshakeLock(ss);
1059
	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
1068
	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {
1060
	    rv = ssl_Do1stHandshake(ss);
1069
	    rv = ssl_Do1stHandshake(ss);
 Lines 1214-1220    Link Here 
1214
	ssl_Get1stHandshakeLock(ss);
1223
	ssl_Get1stHandshakeLock(ss);
1215
	ssl_GetSSL3HandshakeLock(ss);
1224
	ssl_GetSSL3HandshakeLock(ss);
1216
1225
1217
	if (ss->useSecurity && ss->connected && ss->sec && ss->sec->ci.sid) {
1226
	if (ss->useSecurity && ss->firstHsDone && ss->sec && ss->sec->ci.sid) {
1218
	    sid = ss->sec->ci.sid;
1227
	    sid = ss->sec->ci.sid;
1219
	    item = (SECItem *)PORT_Alloc(sizeof(SECItem));
1228
	    item = (SECItem *)PORT_Alloc(sizeof(SECItem));
1220
	    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
1229
	    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
(-)sslsock.c (-17 / +57 lines)
Line     Link Here 
 Lines 34-40    Link Here 
34
 * may use your version of this file under either the MPL or the
34
 * may use your version of this file under either the MPL or the
35
 * GPL.
35
 * GPL.
36
 *
36
 *
37
 * $Id: sslsock.c,v 1.13 2001/02/09 02:11:31 nelsonb%netscape.com Exp $
37
 * $Id: sslsock.c,v 1.3 2001/02/09 19:40:18 nelsonb Exp nelsonb $
38
 */
38
 */
39
#include "seccomon.h"
39
#include "seccomon.h"
40
#include "cert.h"
40
#include "cert.h"
 Lines 897-902    Link Here 
897
{
897
{
898
    sslSocket * ns = NULL;
898
    sslSocket * ns = NULL;
899
    PRStatus    rv;
899
    PRStatus    rv;
900
    PRNetAddr   addr;
900
901
901
    if (model == NULL) {
902
    if (model == NULL) {
902
	/* Just create a default socket if we're given NULL for the model */
903
	/* Just create a default socket if we're given NULL for the model */
 Lines 922-927    Link Here 
922
#ifdef _WIN32
923
#ifdef _WIN32
923
    PR_Sleep(PR_INTERVAL_NO_WAIT);     /* workaround NT winsock connect bug. */
924
    PR_Sleep(PR_INTERVAL_NO_WAIT);     /* workaround NT winsock connect bug. */
924
#endif
925
#endif
926
    ns = ssl_FindSocket(fd);
927
    PORT_Assert(ns);
928
    if (ns)
929
	ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
925
    return fd;
930
    return fd;
926
}
931
}
927
932
 Lines 984-993    Link Here 
984
    if ( ns->useSecurity ) {
989
    if ( ns->useSecurity ) {
985
	if ( ns->handshakeAsClient ) {
990
	if ( ns->handshakeAsClient ) {
986
	    ns->handshake = ssl2_BeginClientHandshake;
991
	    ns->handshake = ssl2_BeginClientHandshake;
992
	    ss->handshaking = sslHandshakingAsClient;
987
	} else {
993
	} else {
988
	    ns->handshake = ssl2_BeginServerHandshake;
994
	    ns->handshake = ssl2_BeginServerHandshake;
995
	    ss->handshaking = sslHandshakingAsServer;
989
	}
996
	}
990
    }
997
    }
998
    ns->TCPconnected = 1;
991
    return newfd;
999
    return newfd;
992
1000
993
loser:
1001
loser:
 Lines 1236-1241    Link Here 
1236
    if (rv < 0) {
1244
    if (rv < 0) {
1237
	return SECFailure;
1245
	return SECFailure;
1238
    }
1246
    }
1247
    ss->TCPconnected = 1;
1239
    /* we have to mask off the high byte because AIX is lame */
1248
    /* we have to mask off the high byte because AIX is lame */
1240
    if ((sin.inet.family & 0xff) == PR_AF_INET) {
1249
    if ((sin.inet.family & 0xff) == PR_AF_INET) {
1241
        PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ci->peer);
1250
        PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ci->peer);
 Lines 1282-1287    Link Here 
1282
{
1291
{
1283
    sslSocket *ss;
1292
    sslSocket *ss;
1284
    PRInt16    ret_flags = how_flags;	/* should select on these flags. */
1293
    PRInt16    ret_flags = how_flags;	/* should select on these flags. */
1294
    PRNetAddr  addr;
1285
1295
1286
    *out_flags = 0;
1296
    *out_flags = 0;
1287
    ss = ssl_GetPrivate(fd);
1297
    ss = ssl_GetPrivate(fd);
 Lines 1291-1313    Link Here 
1291
	return 0;	/* don't poll on this socket */
1301
	return 0;	/* don't poll on this socket */
1292
    }
1302
    }
1293
1303
1294
    if ((ret_flags & PR_POLL_WRITE) && 
1304
    if (ss->useSecurity && 
1295
        ss->useSecurity && 
1305
	ss->handshaking != sslHandshakingUndetermined &&
1296
	!ss->connected && 
1306
        !ss->firstHsDone) {
1297
	   /* XXX There needs to be a better test than the following. */
1307
	if (!ss->TCPconnected) {
1298
	   /* Don't check ss->securityHandshake. */
1308
	    ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
1299
	(ss->handshake || ss->nextHandshake)) {
1309
	}
1300
    	/* The user is trying to write, but the handshake is blocked waiting
1310
	/* If it's not connected, then presumably the application is polling
1301
	 * to read, so tell NSPR NOT to poll on write.
1311
	** on read or write approrpiately, so don't change it. 
1302
	 */
1312
	*/
1303
	ret_flags ^=  PR_POLL_WRITE;	/* don't select on write. */
1313
	if (ss->TCPconnected) {
1304
	ret_flags |=  PR_POLL_READ;	/* do    select on read. */
1314
	    if (!ss->handshakeBegun) {
1305
    }
1315
		/* If the handshake has not begun, poll on read or write 
1306
1316
		** based on the local application's role in the handshake,
1307
    if ((ret_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
1317
		** not based on what the application requested.
1318
		*/
1319
		ret_flags &= ~(PR_POLL_WRITE | PR_POLL_READ);
1320
		if (ss->handshaking == sslHandshakingAsClient) {
1321
		    ret_flags |= PR_POLL_WRITE;
1322
		} else { /* handshaking as server */
1323
		    ret_flags |= PR_POLL_READ;
1324
		}
1325
	    } else 
1326
	    /* First handshake is in progress */
1327
	    if (ss->lastWriteBlocked) {
1328
		if (ret_flags & PR_POLL_READ) {
1329
		    /* The caller is waiting for data to be received, 
1330
		    ** but the initial handshake is blocked on write, or the 
1331
		    ** client's first handshake record has not been written.
1332
		    ** The code should select on write, not read.
1333
		    */
1334
		    ret_flags ^=  PR_POLL_READ;	   /* don't select on read. */
1335
		    ret_flags |=  PR_POLL_WRITE;   /* do    select on write. */
1336
		}
1337
	    } else if (ret_flags & PR_POLL_WRITE) {
1338
		    /* The caller is trying to write, but the handshake is 
1339
		    ** blocked waiting for data to read, and the first 
1340
		    ** handshake has been sent.  so do NOT to poll on write.
1341
		    */
1342
		    ret_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
1343
		    ret_flags |=  PR_POLL_READ;	   /* do    select on read. */
1344
	    }
1345
	}
1346
    } else if ((ret_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
1308
	*out_flags = PR_POLL_READ;	/* it's ready already. */
1347
	*out_flags = PR_POLL_READ;	/* it's ready already. */
1309
1348
	return ret_flags;
1310
    } else if (ret_flags && (fd->lower->methods->poll != NULL)) {
1349
    } 
1350
    if (ret_flags && (fd->lower->methods->poll != NULL)) {
1311
        ret_flags = fd->lower->methods->poll(fd->lower, ret_flags, out_flags);
1351
        ret_flags = fd->lower->methods->poll(fd->lower, ret_flags, out_flags);
1312
    }
1352
    }
1313
1353

Return to bug 56924