⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_server.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
				goto end;				}			ecdh = EC_KEY_new_by_curve_name(nid);			if (ecdh == NULL)				{				BIO_printf(bio_err, "unable to create curve (%s)\n", 					named_curve);				goto end;				}			}		if (ecdh != NULL)			{			BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");			}		else			{			BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");			ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);			if (ecdh == NULL) 				{				BIO_printf(bio_err, "unable to create curve (sect163r2)\n");				goto end;				}			}		(void)BIO_flush(bio_s_out);		SSL_CTX_set_tmp_ecdh(ctx,ecdh);		EC_KEY_free(ecdh);		}#endif		if (!set_cert_key_stuff(ctx,s_cert,s_key))		goto end;	if (s_dcert != NULL)		{		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))			goto end;		}#ifndef OPENSSL_NO_RSA#if 1	if (!no_tmp_rsa)		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);#else	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))		{		RSA *rsa;		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");		BIO_flush(bio_s_out);		rsa=RSA_generate_key(512,RSA_F4,NULL);		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))			{			ERR_print_errors(bio_err);			goto end;			}		RSA_free(rsa);		BIO_printf(bio_s_out,"\n");		}#endif#endif	if (cipher != NULL)		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {		BIO_printf(bio_err,"error setting cipher list\n");		ERR_print_errors(bio_err);		goto end;	}	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,		sizeof s_server_session_id_context);	if (CAfile != NULL)	    SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));	BIO_printf(bio_s_out,"ACCEPT\n");	if (www)		do_server(port,sock_type,&accept_socket,www_body, context);	else		do_server(port,sock_type,&accept_socket,sv_body, context);	print_stats(bio_s_out,ctx);	ret=0;end:	if (ctx != NULL) SSL_CTX_free(ctx);	if (s_cert)		X509_free(s_cert);	if (s_dcert)		X509_free(s_dcert);	if (s_key)		EVP_PKEY_free(s_key);	if (s_dkey)		EVP_PKEY_free(s_dkey);	if (pass)		OPENSSL_free(pass);	if (dpass)		OPENSSL_free(dpass);	if (bio_s_out != NULL)		{        BIO_free(bio_s_out);		bio_s_out=NULL;		}	apps_shutdown();	OPENSSL_EXIT(ret);	}static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)	{	BIO_printf(bio,"%4ld items in the session cache\n",		SSL_CTX_sess_number(ssl_ctx));	BIO_printf(bio,"%4ld client connects (SSL_connect())\n",		SSL_CTX_sess_connect(ssl_ctx));	BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",		SSL_CTX_sess_connect_renegotiate(ssl_ctx));	BIO_printf(bio,"%4ld client connects that finished\n",		SSL_CTX_sess_connect_good(ssl_ctx));	BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",		SSL_CTX_sess_accept(ssl_ctx));	BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",		SSL_CTX_sess_accept_renegotiate(ssl_ctx));	BIO_printf(bio,"%4ld server accepts that finished\n",		SSL_CTX_sess_accept_good(ssl_ctx));	BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));	BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));	BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));	BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));	BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",		SSL_CTX_sess_cache_full(ssl_ctx),		SSL_CTX_sess_get_cache_size(ssl_ctx));	}static int sv_body(char *hostname, int s, unsigned char *context)	{	char *buf=NULL;	fd_set readfds;	int ret=1,width;	int k,i;	unsigned long l;	SSL *con=NULL;	BIO *sbio;#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)	struct timeval tv;#endif	if ((buf=OPENSSL_malloc(bufsize)) == NULL)		{		BIO_printf(bio_err,"out of memory\n");		goto err;		}#ifdef FIONBIO		if (s_nbio)		{		unsigned long sl=1;		if (!s_quiet)			BIO_printf(bio_err,"turning on non blocking io\n");		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)			ERR_print_errors(bio_err);		}#endif	if (con == NULL) {		con=SSL_new(ctx);#ifndef OPENSSL_NO_KRB5		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)                        {                        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,								KRB5SVC);                        kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,								KRB5KEYTAB);                        }#endif	/* OPENSSL_NO_KRB5 */		if(context)		      SSL_set_session_id_context(con, context,						 strlen((char *)context));	}	SSL_clear(con);	if (SSL_version(con) == DTLS1_VERSION)		{		struct timeval timeout;		sbio=BIO_new_dgram(s,BIO_NOCLOSE);		if ( enable_timeouts)			{			timeout.tv_sec = 0;			timeout.tv_usec = DGRAM_RCV_TIMEOUT;			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);						timeout.tv_sec = 0;			timeout.tv_usec = DGRAM_SND_TIMEOUT;			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);			}				if ( mtu > 0)			{			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);			SSL_set_mtu(con, mtu);			}		else			/* want to do MTU discovery */			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);        /* turn on cookie exchange */        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);		}	else		sbio=BIO_new_socket(s,BIO_NOCLOSE);	if (s_nbio_test)		{		BIO *test;		test=BIO_new(BIO_f_nbio_test());		sbio=BIO_push(test,sbio);		}	SSL_set_bio(con,sbio,sbio);	SSL_set_accept_state(con);	/* SSL_set_fd(con,s); */	if (s_debug)		{		con->debug=1;		BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);		BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);		}	if (s_msg)		{		SSL_set_msg_callback(con, msg_cb);		SSL_set_msg_callback_arg(con, bio_s_out);		}	width=s+1;	for (;;)		{		int read_from_terminal;		int read_from_sslcon;		read_from_terminal = 0;		read_from_sslcon = SSL_pending(con);		if (!read_from_sslcon)			{			FD_ZERO(&readfds);#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)			FD_SET(fileno(stdin),&readfds);#endif			FD_SET(s,&readfds);			/* Note: under VMS with SOCKETSHR the second parameter is			 * currently of type (int *) whereas under other systems			 * it is (void *) if you don't have a cast it will choke			 * the compiler: if you do have a cast then you can either			 * go for (int *) or (void *).			 */#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)                        /* Under DOS (non-djgpp) and Windows we can't select on stdin: only			 * on sockets. As a workaround we timeout the select every			 * second and check for any keypress. In a proper Windows			 * application we wouldn't do this because it is inefficient.			 */			tv.tv_sec = 1;			tv.tv_usec = 0;			i=select(width,(void *)&readfds,NULL,NULL,&tv);			if((i < 0) || (!i && !_kbhit() ) )continue;			if(_kbhit())				read_from_terminal = 1;#else			i=select(width,(void *)&readfds,NULL,NULL,NULL);			if (i <= 0) continue;			if (FD_ISSET(fileno(stdin),&readfds))				read_from_terminal = 1;#endif			if (FD_ISSET(s,&readfds))				read_from_sslcon = 1;			}		if (read_from_terminal)			{			if (s_crlf)				{				int j, lf_num;				i=read(fileno(stdin), buf, bufsize/2);				lf_num = 0;				/* both loops are skipped when i <= 0 */				for (j = 0; j < i; j++)					if (buf[j] == '\n')						lf_num++;				for (j = i-1; j >= 0; j--)					{					buf[j+lf_num] = buf[j];					if (buf[j] == '\n')						{						lf_num--;						i++;						buf[j+lf_num] = '\r';						}					}				assert(lf_num == 0);				}			else				i=read(fileno(stdin),buf,bufsize);			if (!s_quiet)				{				if ((i <= 0) || (buf[0] == 'Q'))					{					BIO_printf(bio_s_out,"DONE\n");					SHUTDOWN(s);					close_accept_socket();					ret= -11;					goto err;					}				if ((i <= 0) || (buf[0] == 'q'))					{					BIO_printf(bio_s_out,"DONE\n");					if (SSL_version(con) != DTLS1_VERSION)                        SHUTDOWN(s);	/*				close_accept_socket();					ret= -11;*/					goto err;					}				if ((buf[0] == 'r') && 					((buf[1] == '\n') || (buf[1] == '\r')))					{					SSL_renegotiate(con);					i=SSL_do_handshake(con);					printf("SSL_do_handshake -> %d\n",i);					i=0; /*13; */					continue;					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */					}				if ((buf[0] == 'R') &&					((buf[1] == '\n') || (buf[1] == '\r')))					{					SSL_set_verify(con,						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);					SSL_renegotiate(con);					i=SSL_do_handshake(con);					printf("SSL_do_handshake -> %d\n",i);					i=0; /* 13; */					continue;					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */					}				if (buf[0] == 'P')					{					static const char *str="Lets print some clear text\n";					BIO_write(SSL_get_wbio(con),str,strlen(str));					}				if (buf[0] == 'S')					{					print_stats(bio_s_out,SSL_get_SSL_CTX(con));					}				}#ifdef CHARSET_EBCDIC			ebcdic2ascii(buf,buf,i);#endif			l=k=0;			for (;;)				{				/* should do a select for the write */#ifdef RENEG{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }#endif				k=SSL_write(con,&(buf[l]),(unsigned int)i);				switch (SSL_get_error(con,k))					{				case SSL_ERROR_NONE:					break;				case SSL_ERROR_WANT_WRITE:				case SSL_ERROR_WANT_READ:				case SSL_ERROR_WANT_X509_LOOKUP:					BIO_printf(bio_s_out,"Write BLOCK\n");					break;				case SSL_ERROR_SYSCALL:				case SSL_ERROR_SSL:					BIO_printf(bio_s_out,"ERROR\n");					ERR_print_errors(bio_err);					ret=1;					goto err;					/* break; */				case SSL_ERROR_ZERO_RETURN:					BIO_printf(bio_s_out,"DONE\n");					ret=1;					goto err;					}				l+=k;				i-=k;				if (i <= 0) break;				}			}		if (read_from_sslcon)			{			if (!SSL_is_init_finished(con))				{				i=init_ssl_connection(con);								if (i < 0)					{					ret=0;					goto err;					}				else if (i == 0)					{					ret=1;					goto err;					}				}			else				{again:					i=SSL_read(con,(char *)buf,bufsize);				switch (SSL_get_error(con,i))					{				case SSL_ERROR_NONE:#ifdef CHARSET_EBCDIC					ascii2ebcdic(buf,buf,i);#endif					write(fileno(stdout),buf,						(unsigned int)i);					if (SSL_pending(con)) goto again;					break;				case SSL_ERROR_WANT_WRITE:				case SSL_ERROR_WANT_READ:				case SSL_ERROR_WANT_X509_LOOKUP:					BIO_printf(bio_s_out,"Read BLOCK\n");					break;				case SSL_ERROR_SYSCALL:				case SSL_ERROR_SSL:					BIO_printf(bio_s_out,"ERROR\n");					ERR_print_errors(bio_err);					ret=1;					goto err;				case SSL_ERROR_ZERO_RETURN:					BIO_printf(bio_s_out,"DONE\n");					ret=1;					goto err;					}				}			}		}err:	BIO_printf(bio_s_out,"shutting down SSL\n");#if 1	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);#else	SSL_shutdown(con);#endif	if (con != NULL) SSL_free(con);	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");	if (buf != NULL)		{		OPENSSL_cleanse(buf,bufsize);		OPENSSL_free(buf);		}	if (ret >= 0)		BIO_printf(bio_s_out,"ACCEPT\n");	return(ret);	}static void close_accept_socket(void)	{	BIO_printf(bio_err,"shutdown accept socket\n");	if (accept_socket >= 0)		{		SHUTDOWN2(accept_socket);		}	}static int init_ssl_connection(SSL *con)	{	int i;	const char *str;	X509 *peer;	long verify_error;	MS_STATIC char buf[BUFSIZ];	if ((i=SSL_accept(con)) <= 0)		{		if (BIO_sock_should_retry(i))			{			BIO_printf(bio_s_out,"DELAY\n");			return(1);			}		BIO_printf(bio_err,"ERROR\n");		verify_error=SSL_get_verify_result(con);		if (verify_error != X509_V_OK)			{			BIO_printf(bio_err,"verify error:%s\n",				X509_verify_cert_error_string(verify_error));			}		else			ERR_print_errors(bio_err);		return(0);		}	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));	peer=SSL_get_peer_certificate(con);	if (peer != NULL)		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -