2022-03-19 06:03:41 +00:00
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2022-03-15 14:34:40 +00:00
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <linux/in.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <sasl/sasl.h>
|
|
|
|
|
|
2022-03-19 06:03:41 +00:00
|
|
|
|
int sfp;
|
2022-07-17 12:42:28 +00:00
|
|
|
|
struct sockaddr_in s_add, c_add;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
int sin_size;
|
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
char *server = "server";
|
|
|
|
|
|
2022-03-15 14:34:40 +00:00
|
|
|
|
typedef struct kClient {
|
2022-07-17 12:42:28 +00:00
|
|
|
|
int fp;
|
|
|
|
|
int auth_complete;
|
|
|
|
|
int begin_auth;
|
|
|
|
|
sasl_conn_t *conn;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
} kClient;
|
|
|
|
|
|
|
|
|
|
int listen_port() {
|
2022-07-17 12:42:28 +00:00
|
|
|
|
unsigned short portnum = 2345;
|
|
|
|
|
|
|
|
|
|
sfp = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
|
if (-1 == sfp) {
|
|
|
|
|
printf("socket fail ! \n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 填充服务器端口地址信息,以便下面使用此地址和端口监听 */
|
|
|
|
|
bzero(&s_add, sizeof(struct sockaddr_in));
|
|
|
|
|
s_add.sin_family = AF_INET;
|
|
|
|
|
s_add.sin_addr.s_addr = htonl(INADDR_ANY); /* 这里地址使用全0,即所有 */
|
|
|
|
|
s_add.sin_port = htons(portnum);
|
|
|
|
|
/* 使用bind进行绑定端口 */
|
|
|
|
|
if (-1 == bind(sfp, (struct sockaddr *)(&s_add), sizeof(struct sockaddr))) {
|
|
|
|
|
printf("bind fail !\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/* 开始监听相应的端口 */
|
|
|
|
|
if (-1 == listen(sfp, 5)) {
|
|
|
|
|
printf("listen fail !\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
printf("Hello,welcome to my server !\n");
|
|
|
|
|
return 0;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kClient *createClient(int fp) {
|
2022-07-17 12:42:28 +00:00
|
|
|
|
kClient *c = malloc(sizeof(kClient));
|
|
|
|
|
c->fp = fp;
|
|
|
|
|
c->auth_complete = -1;
|
|
|
|
|
c->begin_auth = 0;
|
|
|
|
|
c->conn = NULL;
|
|
|
|
|
return c;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int auth_client(kClient *c) {
|
2022-07-17 12:42:28 +00:00
|
|
|
|
if (!c->begin_auth) {
|
|
|
|
|
int result = sasl_server_new(server, "hadoop.test.com", "TEST.COM", NULL, NULL, NULL, 0, &c->conn);
|
|
|
|
|
if (result != SASL_OK) {
|
|
|
|
|
printf("Allocating sasl connection state, %s\n", sasl_errdetail(c->conn));
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *mech = "GSSAPI";
|
|
|
|
|
char buffer[1024] = {0};
|
|
|
|
|
int client_len = readTicket(c, buffer);
|
|
|
|
|
char *out;
|
|
|
|
|
unsigned len = 0;
|
|
|
|
|
buffer[client_len] = '\n';
|
|
|
|
|
printf("ticket=%s, len=%d\n", buffer, client_len);
|
|
|
|
|
int result = sasl_server_start(c->conn, mech, buffer, client_len, &out, &len);
|
|
|
|
|
if (result != SASL_OK && result != SASL_CONTINUE) {
|
|
|
|
|
printf("auth failed ,%s, result=%d\n", sasl_errdetail(c->conn), result);
|
|
|
|
|
write(c->fp, "auth failed\n", 11);
|
|
|
|
|
close(c->fp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
printf("sasl_server_start ok\n");
|
|
|
|
|
while (result == SASL_CONTINUE) {
|
|
|
|
|
writeTicket(c, out, len);
|
|
|
|
|
client_len = readTicket(c, buffer);
|
|
|
|
|
result = sasl_server_step(c->conn, buffer, client_len, &out, &len);
|
|
|
|
|
if (result != SASL_OK && result != SASL_CONTINUE) {
|
|
|
|
|
printf("auth failed ,%s\n", sasl_errdetail(c->conn));
|
|
|
|
|
write(c->fp, "auth failed\n", 11);
|
|
|
|
|
close(c->fp);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
printf("sasl_server_start ok");
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
int readTicket(kClient *c, char *ticket) {
|
|
|
|
|
char len_str[10] = {0};
|
|
|
|
|
int recbytes;
|
|
|
|
|
if (-1 == (recbytes = read(c->fp, len_str, 25))) {
|
|
|
|
|
printf("read len fail !\n");
|
|
|
|
|
close(c->fp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
int len = atoi(len_str);
|
|
|
|
|
printf("read len=%s\n", len_str);
|
|
|
|
|
if (-1 == (recbytes = read(c->fp, ticket, len))) {
|
|
|
|
|
printf("read data fail !\n");
|
|
|
|
|
close(c->fp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void writeTicket(kClient *c, char *data, unsigned len) {
|
|
|
|
|
char len_str[10] = {0};
|
|
|
|
|
sprintf(len_str, "%d", len);
|
|
|
|
|
if (-1 == write(c->fp, len_str, 10)) {
|
|
|
|
|
printf("write failed\n");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (-1 == write(c->fp, data, len)) {
|
|
|
|
|
printf("write failed\n");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
void readQuery(kClient *c) {
|
|
|
|
|
char buffer[1024] = {0};
|
|
|
|
|
int recbytes;
|
|
|
|
|
/* 这里使用write向客户端发送信息,也可以尝试使用其他函数实现 */
|
|
|
|
|
if (-1 == write(c->fp, "need_auth", 9)) {
|
|
|
|
|
printf("write fail!\n");
|
|
|
|
|
close(c->fp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-03-15 14:34:40 +00:00
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
if (auth_client(c) != 0) {
|
|
|
|
|
printf("auth failed!\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close(c->fp);
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
int init_sasl() {
|
|
|
|
|
int result = sasl_server_init(NULL, server);
|
|
|
|
|
if (result != SASL_OK) {
|
|
|
|
|
printf("Initializing libsasl");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2022-03-15 14:34:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
int main() {
|
|
|
|
|
if (listen_port() != 0) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
init_sasl();
|
|
|
|
|
while (1) {
|
|
|
|
|
sin_size = sizeof(struct sockaddr_in);
|
|
|
|
|
int nfp = accept(sfp, (struct sockaddr *)(&c_add), &sin_size);
|
|
|
|
|
if (-1 == nfp) {
|
|
|
|
|
printf("accept fail !\r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2022-03-15 14:34:40 +00:00
|
|
|
|
|
2022-07-17 12:42:28 +00:00
|
|
|
|
printf("accept ok!\nServer start get connect from %#x : %#x\n", ntohl(c_add.sin_addr.s_addr), ntohs(c_add.sin_port));
|
|
|
|
|
kClient *c = createClient(nfp);
|
|
|
|
|
readQuery(c);
|
|
|
|
|
}
|
|
|
|
|
close(sfp);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|