1 /*
2 * Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the License); you may
5 * not use this file except in compliance with the License.
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 */
9
10 #include <stdio.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <netdb.h>
16 #include <sys/types.h>
17 #include <arpa/inet.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <gmssl/tls.h>
21 #include <gmssl/error.h>
22 #include "url_parser.h"
23
24
main(int argc,char * argv[])25 int main(int argc, char *argv[])
26 {
27 int ret = -1;
28 char *prog = argv[0];
29 const int cipher = TLS_cipher_ecc_sm4_cbc_sm3;
30 URL_COMPONENTS *url;
31 struct hostent *hp;
32 int port = 443;
33 struct sockaddr_in server;
34 int sock;
35 TLS_CTX ctx;
36 TLS_CONNECT conn;
37 char request[1024];
38 uint8_t buf[16800];
39 char *p;
40 size_t len;
41
42 if (argc != 2) {
43 fprintf(stderr, "example: echo \"key=word\" | tlcp_post https://sm2only.ovssl.cn\n");
44 return 1;
45 }
46
47 if (!(url = parse_url(argv[1]))) {
48 fprintf(stderr, "parse url '%s' failure\n", argv[1]);
49 return 1;
50 }
51 if (!(hp = gethostbyname(url->host))) {
52 herror("tlcp_client: '-host' invalid");
53 goto end;
54 }
55 if (url->port != -1) {
56 port = url->port;
57 }
58
59 server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]);
60 server.sin_family = AF_INET;
61 server.sin_port = htons(port);
62
63 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
64 perror("socket");
65 goto end;
66 }
67 if (connect(sock, (struct sockaddr *)&server , sizeof(server)) < 0) {
68 perror("connect");
69 goto end;
70 }
71
72 memset(&ctx, 0, sizeof(ctx));
73 memset(&conn, 0, sizeof(conn));
74
75 tls_ctx_init(&ctx, TLS_protocol_tlcp, TLS_client_mode);
76 tls_ctx_set_cipher_suites(&ctx, &cipher, 1);
77 tls_init(&conn, &ctx);
78 tls_set_socket(&conn, sock);
79
80 if (tls_do_handshake(&conn) != 1) {
81 fprintf(stderr, "%s: error\n", prog);
82 goto end;
83 }
84
85 snprintf(request, sizeof(request)-1, "POST %s HTTP/1.1\r\nHost: %s\r\n\r\n",
86 url->path ? url->path : "/",
87 url->host);
88
89 tls_send(&conn, (uint8_t *)request, strlen(request), &len);
90
91 len = fread(buf, 1, sizeof(buf), stdin);
92 if (len) {
93 tls_send(&conn, buf, len, &len);
94 }
95
96 if (tls_recv(&conn, buf, sizeof(buf), &len) != 1) {
97 fprintf(stderr, "recv failure\n");
98 goto end;
99 }
100 buf[len] = 0;
101
102 p = strstr((char *)buf, "\r\n\r\n");
103 if (p) {
104 printf("%s", p + 4);
105 fflush(stdout);
106 }
107
108 end:
109 free_url_components(url);
110 close(sock);
111 tls_ctx_cleanup(&ctx);
112 tls_cleanup(&conn);
113 return 0;
114 }
115