在纯C中将HTTP连接传输到HTTPS
我在将HTTP连接套接字程序转换为HTTPS连接套接字代码时遇到了一个严重的问题,如何在纯C中仅建立HTTPS连接 我正在处理一个包管理器,正在重写connection.c文件,该文件包含的唯一内容是用于与包含包的服务器建立初始连接的代码,它不做任何其他事情。我使用HTTP连接100%工作,但是我需要移动到HTTPS连接,并且需要使用LibreSSL;目前我正在尝试使用OpenSSL,因为我在LibreSSL上找不到任何东西。我的HTTP代码如下所示:在纯C中将HTTP连接传输到HTTPS,c,libressl,C,Libressl,我在将HTTP连接套接字程序转换为HTTPS连接套接字代码时遇到了一个严重的问题,如何在纯C中仅建立HTTPS连接 我正在处理一个包管理器,正在重写connection.c文件,该文件包含的唯一内容是用于与包含包的服务器建立初始连接的代码,它不做任何其他事情。我使用HTTP连接100%工作,但是我需要移动到HTTPS连接,并且需要使用LibreSSL;目前我正在尝试使用OpenSSL,因为我在LibreSSL上找不到任何东西。我的HTTP代码如下所示: #include <stdio.h&
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include "repos.h"
#include "resolv.h"
short connection()
{
short socket_desc;
socket_desc = socket(AF_INET, SOCK_STREAM, 0); /* create socket with IPv4 and TCP protocol */
char host[17];
if (socket_desc == -1)
printf("could not create socket\n");
struct sockaddr_in *serv_addr = calloc(1, sizeof(struct sockaddr_in));
serv_addr->sin_family = AF_INET;
serv_addr->sin_port = htons(80);
resolv(DEFAULT_HOST, host); /* set repository to use */
if (inet_pton(AF_INET, host, &serv_addr->sin_addr) <= 0) {
printf("error");
free(serv_addr);
return -1;
}
if (connect(socket_desc, (struct sockaddr *)serv_addr, sizeof(*serv_addr)) < 0) {
printf("connection failed\n");
return 1;
}
else {
printf("connection initialized\n");
return 0;
}
/* close the connection */
free(serv_addr);
close(socket_desc);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "repos.h"
#include "resolv.h"
SSL *cSSL;
void initssl()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void destroyssl()
{
ERR_free_strings();
EVP_cleanup();
}
void shutdownssl()
{
SSL_shutdown(cSSL);
SSL_free(cSSL);
}
int main()
{
short socket_desc;
short socket_ssl;
char host[17];
socklen_t sock_size;
SSL_CTX *sslctx;
initssl();
socket_desc = socket(AF_INET, SOCK_STREAM, 0); /* create socket with IPv4 and TCP protocol */
if (socket_desc == -1)
printf("could not create socket\n");
struct sockaddr_in *serv_addr = calloc(1, sizeof(struct sockaddr_in));
serv_addr->sin_family = AF_INET;
serv_addr->sin_port = htons(443);
resolv(DEFAULT_HOST, host); /* resolve DEFAULT_HOST and store the ip in host */
if (inet_pton(AF_INET, host, &serv_addr->sin_addr) <= 0) {
printf("error");
free(serv_addr);
return -1;
}
bind(socket_desc, (struct sockaddr *)serv_addr, sizeof(struct sockaddr_in));
listen(socket_desc, 5);
sock_size = sizeof(struct sockaddr_in);
socket_ssl = accept(socket_desc, (struct sockaddr *)serv_addr, &sock_size); /* this is where hang occurs, however I am usnure why. I am reading docs and such and if I figure this out I will post the fix; however I would love some advice/help if anyone sees my error */
sslctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
short use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
short use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, socket_ssl);
char ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0) {
printf("connection failed\n");
shutdownssl();
}
else
printf("connected\n");
return 0;
}
/*resolv.c*/
#包括
#包括
#包括
#包括
#包括
短解析(字符*主机,字符*ip)
{
struct hostent*hp=calloc(1,sizeof(struct hostent));
hp=gethostbyname(主机);
如果(hp==NULL){
fprintf(stderr,“gethostbyname()失败\n”);
出口(1);
}
否则{
短i=0;
while(hp->h\u addr\u list[i]!=NULL){
inet_ntoa(*(地址中的结构*)(hp->h_地址列表[i]);
i++;
}
strlcpy(ip,inet\u ntoa(*(地址中的结构*)(hp->h\u地址列表[0]),16);
}
返回0;
}
我知道,由于IPv6的原因,其中一些呼叫已经过时,但我将在所有这些都正常工作后添加IPv6,并将端口从BSD libc添加到musl libc
我希望HTTPS代码运行并连接到服务器,从而打印连接,但它只是运行,不会失败或打印任何内容。
struct-hostent*hp=calloc(1,sizeof(struct-hostent));hp=gethostbyname(主机)代码>是胡说八道。为字符串数组指定长度也是无稽之谈,请使用char DEFAULT\u HOST[]=“gitlab.com”代码>谁说套接字短路?^^^^更确切地说,这两行声明、初始化然后覆盖hp
的值是两行中的完美内存泄漏。只有裸malloc可以更直接。如果我可以问一下,那怎么会导致内存泄漏呢?我正在查看什么是内存泄漏,如果我正确的话,将内存归零,然后分配它不应该导致内存泄漏,但是我仍然在学习,可能是错误的。除此之外,我还做了另一个测试,甚至使用了printf(“test\n”)代码>行后<代码>袜子尺寸代码>未打印任何内容。大多数数字变量被声明为typeshort
的原因是我自己不使用int,除非它是必需的。我知道它很小,但我喜欢保存所有内存(即使在这么低的级别上)。只是一个更新:我注释掉所有内容,然后慢慢地逐行取消注释,挂起发生在socket\u ssl=accept(socket\u desc,(struct sockaddr*)serv\u addr,&sock\u size)代码>struct hostent*hp=calloc(1,sizeof(struct hostent));hp=gethostbyname(主机)代码>是胡说八道。为字符串数组指定长度也是无稽之谈,请使用char DEFAULT\u HOST[]=“gitlab.com”代码>谁说套接字短路?^^^^更确切地说,这两行声明、初始化然后覆盖hp
的值是两行中的完美内存泄漏。只有裸malloc可以更直接。如果我可以问一下,那怎么会导致内存泄漏呢?我正在查看什么是内存泄漏,如果我正确的话,将内存归零,然后分配它不应该导致内存泄漏,但是我仍然在学习,可能是错误的。除此之外,我还做了另一个测试,甚至使用了printf(“test\n”)代码>行后<代码>袜子尺寸代码>未打印任何内容。大多数数字变量被声明为typeshort
的原因是我自己不使用int,除非它是必需的。我知道它很小,但我喜欢保存所有内存(即使在这么低的级别上)。只是一个更新:我注释掉所有内容,然后慢慢地逐行取消注释,挂起发生在socket\u ssl=accept(socket\u desc,(struct sockaddr*)serv\u addr,&sock\u size)代码>
/* repos.h */
char DEFAULT_HOST[11] = "gitlab.com";
char DEFAULT_PAGE[24] = "Puffles_the_Dragon/core";
/* resolv.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
short resolv(char *host, char *ip)
{
struct hostent *hp = calloc(1, sizeof(struct hostent));
hp = gethostbyname(host);
if (hp == NULL) {
fprintf(stderr, "gethostbyname() failed\n");
exit(1);
}
else {
short i = 0;
while (hp->h_addr_list[i] != NULL) {
inet_ntoa(*(struct in_addr *)(hp->h_addr_list[i]));
i++;
}
strlcpy(ip, inet_ntoa(*(struct in_addr *)(hp->h_addr_list[0])), 16);
}
return 0;
}