168 lines
3.6 KiB
C
168 lines
3.6 KiB
C
|
||
#include <stdio.h>
|
||
#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>
|
||
|
||
int sfp;
|
||
struct sockaddr_in s_add,c_add;
|
||
int sin_size;
|
||
|
||
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 && sasl_server_new("sample", "DOMAIN.COM",
|
||
"DOMAIN.COM", "127.0.0.1", "127.0.0.1", NULL,
|
||
0, &c->conn) == SASL_OK) {
|
||
printf("Allocating sasl connection state");
|
||
return 1;
|
||
}
|
||
const char *mech = "GSSAPI";
|
||
int recbytes;
|
||
char buffer[1024]={0};
|
||
if ((recbytes = read(c->fp, buffer, 1024)) == -1) {
|
||
printf("read failed\n");
|
||
close(c->fp);
|
||
return 1;
|
||
}
|
||
buffer[recbytes] = '\0';
|
||
char *out;
|
||
unsigned len = 0;
|
||
int result = sasl_server_start(c->conn, mech, buffer, recbytes, &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);
|
||
}
|
||
while (result == SASL_CONTINUE) {
|
||
if (write(c->fp, out, len) == -1) {
|
||
printf("write failed\n");
|
||
return 1;
|
||
}
|
||
if (recbytes = read(c->fp, buffer, 1024)) {
|
||
printf("write failed\n");
|
||
return 1;
|
||
}
|
||
result = sasl_server_step(c->conn, buffer, recbytes, &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;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
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;
|
||
}
|
||
printf("write ok!\n");
|
||
while (1) {
|
||
if(-1 == (recbytes = read(c->fp,buffer,1024))) {
|
||
printf("read data fail !\n");
|
||
close(c->fp);
|
||
}
|
||
if (c->auth_complete != 1 && auth_client(c) != 0) {
|
||
printf("auth failed!\n");
|
||
break;
|
||
}
|
||
if(-1 == write(c->fp,"need_auth",9)) {
|
||
printf("write fail!\n");
|
||
break;
|
||
}
|
||
}
|
||
close(c->fp);
|
||
}
|
||
|
||
|
||
int init_sasl() {
|
||
int result = sasl_server_init(NULL, "sample");
|
||
if (result != SASL_OK) {
|
||
printf("Initializing libsasl");
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
if (listen_port() != 0 && init_sasl() != 0)
|
||
{
|
||
return 1;
|
||
}
|
||
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;
|
||
}
|
||
|
||
|