Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  tls_bio_ops.c

  Sprache: C
 

/*++
/* NAME
/* tls_bio_ops 3
/* SUMMARY
/* TLS network basic I/O management
/* SYNOPSIS
/* #define TLS_INTERNAL
/* #include <tls.h>
/*
/* int tls_bio_connect(fd, timeout, context)
/* int fd;
/* int timeout;
/* TLS_SESS_STATE *context;
/*
/* int tls_bio_accept(fd, timeout, context)
/* int fd;
/* int timeout;
/* TLS_SESS_STATE *context;
/*
/* int tls_bio_shutdown(fd, timeout, context)
/* int fd;
/* int timeout;
/* TLS_SESS_STATE *context;
/*
/* int tls_bio_read(fd, buf, len, timeout, context)
/* int fd;
/* void *buf;
/* int len;
/* int timeout;
/* TLS_SESS_STATE *context;
/*
/* int tls_bio_write(fd, buf, len, timeout, context)
/* int fd;
/* void *buf;
/* int len;
/* int timeout;
/* TLS_SESS_STATE *context;
/* DESCRIPTION
/* This module enforces VSTREAM-style timeouts on non-blocking
/* I/O while performing TLS handshake or input/output operations.
/*
/* The Postfix VSTREAM read/write routines invoke the
/* tls_bio_read/write routines to send and receive plain-text
/* data.  In addition, this module provides tls_bio_connect/accept
/* routines that trigger the initial TLS handshake.  The
/* tls_bio_xxx routines invoke the corresponding SSL routines
/* that translate the requests into TLS protocol messages.
/*
/* Whenever an SSL operation indicates that network input (or
/* output) needs to happen, the tls_bio_xxx routines wait for
/* the network to become readable (or writable) within the
/* timeout limit, then retry the SSL operation. This works
/* because the network socket is in non-blocking mode.
/*
/* tls_bio_connect() performs the SSL_connect() operation.
/*
/* tls_bio_accept() performs the SSL_accept() operation.
/*
/* tls_bio_shutdown() performs the SSL_shutdown() operation.
/*
/* tls_bio_read() performs the SSL_read() operation.
/*
/* tls_bio_write() performs the SSL_write() operation.
/*
/* Arguments:
/* .IP fd
/* Network socket.
/* .IP buf
/* Read/write buffer.
/* .IP len
/* Read/write request size.
/* .IP timeout
/* Read/write timeout.
/* .IP TLScontext
/* TLS session state.
/* DIAGNOSTICS
/* A result value > 0 means successful completion.
/*
/* A result value < 0 means that the requested operation did
/* not complete due to TLS protocol failure, system call
/* failure, or for any reason described under "in addition"
/* below.
/*
/* A result value of 0 from tls_bio_shutdown() means that the
/* operation is in progress. A result value of 0 from other
/* tls_bio_ops(3) operations means that the remote party either
/* closed the network connection or that it sent a TLS shutdown
/* request.
/*
/* Upon return from the tls_bio_ops(3) routines the global
/* errno value is non-zero when the requested operation did not
/* complete due to system call failure.
/*
/* In addition, the result value is set to -1, and the global
/* errno value is set to ETIMEDOUT, when some network read/write
/* operation did not complete within the time limit.
/* LICENSE
/* .ad
/* .fi
/* This software is free. You can do with it whatever you want.
/* The original author kindly requests that you acknowledge
/* the use of his software.
/* AUTHOR(S)
/* Originally written by:
/* Lutz Jaenicke
/* BTU Cottbus
/* Allgemeine Elektrotechnik
/* Universitaetsplatz 3-4
/* D-03044 Cottbus, Germany
/*
/* Updated by:
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Victor Duchovni
/* Morgan Stanley
/*--*/


/* System library. */

#include <sys_defs.h>
#include <sys/time.h>

#ifndef timersub
/* res = a - b */
#define timersub(a, b, res) do { \
 (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
 (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
 if ((res)->tv_usec < 0) { \
  (res)->tv_sec--; \
  (res)->tv_usec += 1000000; \
 } \
    } while (0)
#endif

#ifdef USE_TLS

/* Utility library. */

#include <msg.h>
#include <iostuff.h>

/* TLS library. */

#define TLS_INTERNAL
#include <tls.h>

/* tls_bio - perform SSL input/output operation with extreme prejudice */

int     tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext,
          int (*hsfunc) (SSL *),
          int (*rfunc) (SSL *, void *, int),
          int (*wfunc) (SSL *, const void *, int),
          void *buf, int num)
{
    const char *myname = "tls_bio";
    int     status;
    int     err;
    int     enable_deadline;
    struct timeval time_left;  /* amount of time left */
    struct timeval time_deadline; /* time of deadline */
    struct timeval time_now;  /* time after SSL_mumble() call */

    /*
     * Compensation for interface mis-match: With VSTREAMs, timeout <= 0
     * means wait forever; with the read/write_wait() calls below, we need to
     * specify timeout < 0 instead.
     * 
     * Safety: no time limit means no deadline.
     */

    if (timeout <= 0) {
 timeout = -1;
 enable_deadline = 0;
    }

    /*
     * Deadline management is simpler than with VSTREAMs, because we don't
     * need to decrement a per-stream time limit. We just work within the
     * budget that is available for this tls_bio() call.
     */

    else {
 enable_deadline =
     vstream_fstat(TLScontext->stream, VSTREAM_FLAG_DEADLINE);
 if (enable_deadline) {
     GETTIMEOFDAY(&time_deadline);
     time_deadline.tv_sec += timeout;
 }
    }

    /*
     * If necessary, retry the SSL handshake or read/write operation after
     * handling any pending network I/O.
     */

    for (;;) {

 /*
  * Flush the per-thread SSL error queue. Otherwise, errors from other
  * code that also uses TLS may confuse SSL_get_error(3).
 */

 ERR_clear_error();

 if (hsfunc)
     status = hsfunc(TLScontext->con);
 else if (rfunc)
     status = rfunc(TLScontext->con, buf, num);
 else if (wfunc)
     status = wfunc(TLScontext->con, buf, num);
 else
     msg_panic("%s: nothing to do here", myname);
 err = SSL_get_error(TLScontext->con, status);

 /*
  * Correspondence between SSL_ERROR_* error codes and tls_bio_(read,
  * write, accept, connect, shutdown) return values (for brevity:
  * retval).
  * 
  * SSL_ERROR_NONE corresponds with retval > 0. With SSL_(read, write)
  * this is the number of plaintext bytes sent or received. With
  * SSL_(accept, connect, shutdown) this means that the operation was
  * completed successfully.
  * 
  * SSL_ERROR_WANT_(WRITE, READ) start a new loop iteration, or force
  * (retval = -1, errno = ETIMEDOUT) when the time limit is exceeded.
  * 
  * All other SSL_ERROR_* cases correspond with retval <= 0. With
  * SSL_(read, write, accept, connect) retval == 0 means that the
  * remote party either closed the network connection or that it
  * requested TLS shutdown; with SSL_shutdown() retval == 0 means that
  * our own shutdown request is in progress. With all operations
  * retval < 0 means that there was an error. In the latter case,
  * SSL_ERROR_SYSCALL means that error details are returned via the
  * errno value.
  * 
  * Find out if we must retry the operation and/or if there is pending
  * network I/O.
  * 
  * XXX If we're the first to invoke SSL_shutdown(), then the operation
  * isn't really complete when the call returns. We could hide that
  * anomaly here and repeat the call.
 */

 switch (err) {
 case SSL_ERROR_WANT_WRITE:
 case SSL_ERROR_WANT_READ:
     if (enable_deadline) {
  GETTIMEOFDAY(&time_now);
  timersub(&time_deadline, &time_now, &time_left);
  timeout = time_left.tv_sec + (time_left.tv_usec > 0);
  if (timeout <= 0) {
      errno = ETIMEDOUT;
      return (-1);
  }
     }
     if (err == SSL_ERROR_WANT_WRITE) {
  if (write_wait(fd, timeout) < 0)
      return (-1);  /* timeout error */
     } else {
  if (read_wait(fd, timeout) < 0)
      return (-1);  /* timeout error */
     }
     break;

     /*
      * Unhandled cases: SSL_ERROR_WANT_(ACCEPT, CONNECT, X509_LOOKUP)
      * etc. Historically, Postfix silently treated these as ordinary
      * I/O errors so we don't really know how common they are. For
      * now, we just log a warning.
     */

 default:
     msg_warn("%s: unexpected SSL_ERROR code %d", myname, err);
     /* FALLTHROUGH */

     /*
      * With tls_timed_read() and tls_timed_write() the caller is the
      * VSTREAM library module which is unaware of TLS, so we log the
      * TLS error stack here. In a better world, each VSTREAM I/O
      * object would provide an error reporting method in addition to
      * the timed_read and timed_write methods, so that we would not
      * need to have ad-hoc code like this.
     */

 case SSL_ERROR_SSL:
     if (rfunc || wfunc)
  tls_print_errors();
     /* FALLTHROUGH */
 case SSL_ERROR_ZERO_RETURN:
 case SSL_ERROR_NONE:
     errno = 0;    /* avoid bogus warnings */
     /* FALLTHROUGH */
 case SSL_ERROR_SYSCALL:
     return (status);
 }
    }
}

#endif

Messung V0.5 in Prozent
C=55 H=89 G=73

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142