@@ -569,6 +569,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
569569typedef struct {
570570 git_stream parent ;
571571 git_stream * io ;
572+ int owned ;
572573 bool connected ;
573574 char * host ;
574575 SSL * ssl ;
@@ -583,7 +584,7 @@ int openssl_connect(git_stream *stream)
583584 BIO * bio ;
584585 openssl_stream * st = (openssl_stream * ) stream ;
585586
586- if ((ret = git_stream_connect (st -> io )) < 0 )
587+ if (st -> owned && (ret = git_stream_connect (st -> io )) < 0 )
587588 return ret ;
588589
589590 bio = BIO_new (git_stream_bio_method );
@@ -682,43 +683,43 @@ int openssl_close(git_stream *stream)
682683
683684 st -> connected = false;
684685
685- return git_stream_close (st -> io );
686+ return st -> owned ? git_stream_close (st -> io ) : 0 ;
686687}
687688
688689void openssl_free (git_stream * stream )
689690{
690691 openssl_stream * st = (openssl_stream * ) stream ;
691692
693+ if (st -> owned )
694+ git_stream_free (st -> io );
695+
692696 SSL_free (st -> ssl );
693697 git__free (st -> host );
694698 git__free (st -> cert_info .data );
695- git_stream_free (st -> io );
696699 git__free (st );
697700}
698701
699- int git_openssl_stream_new (git_stream * * out , const char * host , const char * port )
702+ static int openssl_stream_wrap (
703+ git_stream * * out ,
704+ git_stream * in ,
705+ const char * host ,
706+ int owned )
700707{
701- int error ;
702708 openssl_stream * st ;
703709
710+ assert (out && in && host );
711+
704712 st = git__calloc (1 , sizeof (openssl_stream ));
705713 GITERR_CHECK_ALLOC (st );
706714
707- st -> io = NULL ;
708- #ifdef GIT_CURL
709- error = git_curl_stream_new (& st -> io , host , port );
710- #else
711- error = git_socket_stream_new (& st -> io , host , port );
712- #endif
713-
714- if (error < 0 )
715- goto out_err ;
715+ st -> io = in ;
716+ st -> owned = owned ;
716717
717718 st -> ssl = SSL_new (git__ssl_ctx );
718719 if (st -> ssl == NULL ) {
719720 giterr_set (GITERR_SSL , "failed to create ssl object" );
720- error = -1 ;
721- goto out_err ;
721+ git__free ( st ) ;
722+ return -1 ;
722723 }
723724
724725 st -> host = git__strdup (host );
@@ -737,10 +738,33 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
737738
738739 * out = (git_stream * ) st ;
739740 return 0 ;
741+ }
740742
741- out_err :
742- git_stream_free (st -> io );
743- git__free (st );
743+ int git_openssl_stream_wrap (git_stream * * out , git_stream * in , const char * host )
744+ {
745+ return openssl_stream_wrap (out , in , host , 0 );
746+ }
747+
748+ int git_openssl_stream_new (git_stream * * out , const char * host , const char * port )
749+ {
750+ git_stream * stream = NULL ;
751+ int error ;
752+
753+ assert (out && host && port );
754+
755+ #ifdef GIT_CURL
756+ error = git_curl_stream_new (& stream , host , port );
757+ #else
758+ error = git_socket_stream_new (& stream , host , port );
759+ #endif
760+
761+ if (error < 0 )
762+ return error ;
763+
764+ if ((error = openssl_stream_wrap (out , stream , host , 1 )) < 0 ) {
765+ git_stream_close (stream );
766+ git_stream_free (stream );
767+ }
744768
745769 return error ;
746770}
0 commit comments