#include #include #include #include #include #include #include #include int sfp; struct sockaddr_in s_add, c_add; int sin_size; char *server = "server"; typedef struct kClient { int fp; int auth_complete; int begin_auth; sasl_conn_t *conn; } kClient; int listen_port() { 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; } kClient *createClient(int fp) { kClient *c = malloc(sizeof(kClient)); c->fp = fp; c->auth_complete = -1; c->begin_auth = 0; c->conn = NULL; return c; } int auth_client(kClient *c) { if (!c->begin_auth) { int result = sasl_server_new(server, "hadoop.test.hadoop.com", "TEST.HADOOP.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; } 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; } } 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; } if (auth_client(c) != 0) { printf("auth failed!\n"); return; } close(c->fp); } int init_sasl() { int result = sasl_server_init(NULL, server); if (result != SASL_OK) { printf("Initializing libsasl"); return 1; } return 0; } 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; } 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; }