security/nss/lib/ssl/ssldef.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /*
     2  * "Default" SSLSocket methods, used by sockets that do neither SSL nor socks.
     3  *
     4  * This Source Code Form is subject to the terms of the Mozilla Public
     5  * License, v. 2.0. If a copy of the MPL was not distributed with this
     6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     8 #include "cert.h"
     9 #include "ssl.h"
    10 #include "sslimpl.h"
    12 #if defined(WIN32)
    13 #define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
    14 #define DEFINE_ERROR       PRErrorCode err = PR_GetError();
    15 #else
    16 #define MAP_ERROR(from,to)
    17 #define DEFINE_ERROR
    18 #endif
    20 int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
    21 {
    22     PRFileDesc *lower = ss->fd->lower;
    23     int rv;
    25     rv = lower->methods->connect(lower, sa, ss->cTimeout);
    26     return rv;
    27 }
    29 int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
    30 {
    31     PRFileDesc *lower = ss->fd->lower;
    32     int rv;
    34     rv = lower->methods->bind(lower, addr);
    35     return rv;
    36 }
    38 int ssl_DefListen(sslSocket *ss, int backlog)
    39 {
    40     PRFileDesc *lower = ss->fd->lower;
    41     int rv;
    43     rv = lower->methods->listen(lower, backlog);
    44     return rv;
    45 }
    47 int ssl_DefShutdown(sslSocket *ss, int how)
    48 {
    49     PRFileDesc *lower = ss->fd->lower;
    50     int rv;
    52     rv = lower->methods->shutdown(lower, how);
    53     return rv;
    54 }
    56 int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
    57 {
    58     PRFileDesc *lower = ss->fd->lower;
    59     int rv;
    61     rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
    62     if (rv < 0) {
    63 	DEFINE_ERROR
    64 	MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
    65     } else if (rv > len) {
    66 	PORT_Assert(rv <= len);
    67 	PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
    68 	rv = SECFailure;
    69     }
    70     return rv;
    71 }
    73 /* Default (unencrypted) send.
    74  * For blocking sockets, always returns len or SECFailure, no short writes.
    75  * For non-blocking sockets:
    76  *   Returns positive count if any data was written, else returns SECFailure. 
    77  *   Short writes may occur.  Does not return SECWouldBlock.
    78  */
    79 int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
    80 {
    81     PRFileDesc *lower = ss->fd->lower;
    82     int sent = 0;
    84 #if NSS_DISABLE_NAGLE_DELAYS
    85     /* Although this is overkill, we disable Nagle delays completely for 
    86     ** SSL sockets.
    87     */
    88     if (ss->opt.useSecurity && !ss->delayDisabled) {
    89 	ssl_EnableNagleDelay(ss, PR_FALSE);   /* ignore error */
    90     	ss->delayDisabled = 1;
    91     }
    92 #endif
    93     do {
    94 	int rv = lower->methods->send(lower, (const void *)(buf + sent), 
    95 	                              len - sent, flags, ss->wTimeout);
    96 	if (rv < 0) {
    97 	    PRErrorCode err = PR_GetError();
    98 	    if (err == PR_WOULD_BLOCK_ERROR) {
    99 		ss->lastWriteBlocked = 1;
   100 		return sent ? sent : SECFailure;
   101 	    }
   102 	    ss->lastWriteBlocked = 0;
   103 	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
   104 	    /* Loser */
   105 	    return rv;
   106 	}
   107 	sent += rv;
   109 	if (IS_DTLS(ss) && (len > sent)) { 
   110 	    /* We got a partial write so just return it */
   111 	    return sent;
   112 	}
   113     } while (len > sent);
   114     ss->lastWriteBlocked = 0;
   115     return sent;
   116 }
   118 int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
   119 {
   120     PRFileDesc *lower = ss->fd->lower;
   121     int rv;
   123     rv = lower->methods->read(lower, (void *)buf, len);
   124     if (rv < 0) {
   125 	DEFINE_ERROR
   126 	MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
   127     }
   128     return rv;
   129 }
   131 int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
   132 {
   133     PRFileDesc *lower = ss->fd->lower;
   134     int sent = 0;
   136     do {
   137 	int rv = lower->methods->write(lower, (const void *)(buf + sent), 
   138 	                               len - sent);
   139 	if (rv < 0) {
   140 	    PRErrorCode err = PR_GetError();
   141 	    if (err == PR_WOULD_BLOCK_ERROR) {
   142 		ss->lastWriteBlocked = 1;
   143 		return sent ? sent : SECFailure;
   144 	    }
   145 	    ss->lastWriteBlocked = 0;
   146 	    MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
   147 	    /* Loser */
   148 	    return rv;
   149 	}
   150 	sent += rv;
   151     } while (len > sent);
   152     ss->lastWriteBlocked = 0;
   153     return sent;
   154 }
   156 int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
   157 {
   158     PRFileDesc *lower = ss->fd->lower;
   159     int rv;
   161     rv = lower->methods->getpeername(lower, name);
   162     return rv;
   163 }
   165 int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
   166 {
   167     PRFileDesc *lower = ss->fd->lower;
   168     int rv;
   170     rv = lower->methods->getsockname(lower, name);
   171     return rv;
   172 }
   174 int ssl_DefClose(sslSocket *ss)
   175 {
   176     PRFileDesc *fd;
   177     PRFileDesc *popped;
   178     int         rv;
   180     fd    = ss->fd;
   182     /* First, remove the SSL layer PRFileDesc from the socket's stack, 
   183     ** then invoke the SSL layer's PRFileDesc destructor.
   184     ** This must happen before the next layer down is closed.
   185     */
   186     PORT_Assert(fd->higher == NULL);
   187     if (fd->higher) {
   188 	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
   189 	return SECFailure;
   190     }
   191     ss->fd = NULL;
   193     /* PR_PopIOLayer will swap the contents of the top two PRFileDescs on
   194     ** the stack, and then remove the second one.  This way, the address
   195     ** of the PRFileDesc on the top of the stack doesn't change.
   196     */
   197     popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); 
   198     popped->dtor(popped);
   200     /* fd is now the PRFileDesc for the next layer down.
   201     ** Now close the underlying socket. 
   202     */
   203     rv = fd->methods->close(fd);
   205     ssl_FreeSocket(ss);
   207     SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
   208 		SSL_GETPID(), fd, rv, PORT_GetError()));
   209     return rv;
   210 }

mercurial