Ejemplo n.º 1
0
/**
 *do_mkd - 创建目录
 *@sess:会话结构体
 */
void ftpproto::do_mkd(session_t* sess)
{
	if (mkdir(sess->arg,0777) < 0)//0777为权限  0777&umask
	{//创建目录失败(没有写入权限时好像也可以写入)
		ftp_reply(sess,FTP_FILEFAIL,"Create directory operation failed.");//响应
		return;
	}
	char text[4096] = {0};
	if (sess->arg[0] == '/')//如果是绝对路径
	{
		 sprintf(text,"%s created.",sess->arg);
	}
	else//是相对路径
	{
		char dir[4096+1] = {0};
		//获取当前路径
		getcwd(dir,4096);
		if (dir[strlen(dir) - 1] == '/')//最后一个字符是否等于斜杠
		{
			sprintf(text,"%s%s created.",dir,sess->arg);
		}
		else
		{
			sprintf(text,"%s/%s created.",dir,sess->arg);
		}
	}
	ftp_reply(sess,FTP_MKDIROK,text);//响应
}
Ejemplo n.º 2
0
void do_cmd_mkd(session_t *pses)
{
    if(mkdir(pses->arg, 0777) < 0)
    {
        ftp_reply(pses->ctrl_fd, FTP_FILEFAIL, "Create directory operation failed.");
        return;
    }
    char sendbuf[PATH_MAX + 1] = {0};
    if(pses->arg[0] == '/')
    {
        //绝对路径
        sprintf(sendbuf, "\"%s\" created.",pses->arg);
    }
    else
    {
        //相对路径
        char dir[PATH_MAX + 1] = {0};
        getcwd(dir, PATH_MAX);
        if(dir[strlen(dir) - 1] != '/')
        {
            dir[strlen(dir) - 1]  = '/';
            dir[strlen(dir)] = '\0';
        }
        sprintf(sendbuf, "\"%s%s\" created.", dir,pses->arg);
    }
    ftp_reply(pses->ctrl_fd, FTP_MKDIROK, sendbuf);
}
Ejemplo n.º 3
0
static void do_mkd(session_t *sess)
{
	if(mkdir(sess->arg, 0777) < 0)
	{
		ftp_reply(sess, FTP_FILEFAIL, "Create directory operation failed.");
		return;
	}

	char text[1024] = {0};

	if(sess->arg[0] == '/')
		sprintf(text, "%s created", sess->arg);	
	else
	{
		char dir[1024 + 1] = {0};
		getcwd(dir, 1024);
		
		if(dir[strlen(dir) - 1] == '/')
			sprintf(text, "%s%s created", dir, sess->arg);
		else
			sprintf(text, "%s/%s created", dir, sess->arg);

	}
	ftp_reply(sess, FTP_MKDIROK, text);
}
Ejemplo n.º 4
0
void do_site_chmod(session_t *sess, char *args)
{
    if (strlen(args) == 0)
    {
        ftp_reply(sess, FTP_BADCMD, "SITE CHMOD needs 2 arguments.");
        return;
    }

    char perm[100] = {0};
    char file[100] = {0};
    str_split(args , perm, file, ' ');
    if (strlen(file) == 0)
    {
        ftp_reply(sess, FTP_BADCMD, "SITE CHMOD needs 2 arguments.");
        return;
    }

    unsigned int mode = str_octal_to_uint(perm);
    if (chmod(file, mode) < 0)
    {
        ftp_reply(sess, FTP_CHMODOK, "SITE CHMOD command failed.");
    }
    else
    {
        ftp_reply(sess, FTP_CHMODOK, "SITE CHMOD command ok.");
    }
}
Ejemplo n.º 5
0
static void do_pass(session_t* sess)
{
	struct passwd* pw = getpwuid(sess->uid);
	if(pw == NULL)
	{
		ftp_reply(sess, FTP_LOGINERR, "Login incorrect.");
		return;
	}

	struct spwd* sp = getspnam(pw->pw_name);
	if(sp == NULL)
	{
		ftp_reply(sess, FTP_LOGINERR, "Login incorrect.");
		return;
	}

	char* encrypted_pass = crypt(sess->arg, sp->sp_pwdp);
	if(strcmp(encrypted_pass, sp->sp_pwdp) != 0)
	{	
		ftp_reply(sess, FTP_LOGINERR, "Login incorrect.");
		return;
	}

	signal(SIGURG, handle_sigurg);
	activate_sigurg(sess->ctrl_fd);

	//change to login user
	setegid(pw->pw_gid);
	seteuid(pw->pw_uid);
	chdir(pw->pw_dir);
	umask(tunable_local_umask);

	ftp_reply(sess, FTP_LOGINOK, "Login successful.");
}
Ejemplo n.º 6
0
static void do_cdup(session_t *sess)
{
	if(chdir("..") < 0)
        {
                ftp_reply(sess, FTP_FILEFAIL, "Failed to change directory.");
                return;
        }
        ftp_reply(sess, FTP_CWDOK, "Directory successful changed.");
}
Ejemplo n.º 7
0
/**
 *handle_ftp - ftp服务进程的处理函数
 *@sess:会话结构体
 *主要完成从ftp客户端读取命令,解析并调用响应函数执行
 */
void ftpproto::handle_ftp(session_t* sess)
{
	LCWFTPD_LOG(DEBUG,"Hello handle_ftp");
	ftp_reply(sess,FTP_GREET,"(lcwftpd 1.0 welcome you!!!by LinChuangwei.)");
	ftp_commands_map_init();//初始化map
	LCWFTPD_LOG(DEBUG,"All supported commands:");
	for(it = commandsmap.begin();it != commandsmap.end();it++)
	{
		std::cout << it->first <<" ";
	}
	std::cout << std::endl;
	
	while(1)
	{
	    //三个保存命令的数组清空
		memset(sess->cmdline,0,sizeof(sess->cmdline));
		memset(sess->cmd,0,sizeof(sess->cmd));
		memset(sess->arg,0,sizeof(sess->arg));
		//读取命令到cmdline
		ret = lcw_systools.readline(sess->ctrl_fd,sess->cmdline,MAX_COMMAND);
		LCWFTPD_LOG(DEBUG,"ctrl_fd:%d",sess->ctrl_fd);
		LCWFTPD_LOG(DEBUG,"ret:%d",ret);
		if (-1 == ret)//读取错误
		{
			LCWFTPD_LOG(ERROR,"lcw_systools.readline");
		}
		else if (0 == ret)//等于0表示断开了连接	
		{
			LCWFTPD_LOG(ERROR,"client %s disconnect",sess->ip);
		}
		//USER scut_lcw\r\n 空格前面看成命令,之后看成参数	
		//首先要去除/r/n
		lcw_ftpstr.str_trim_crlf(sess->cmdline);
		LCWFTPD_LOG(DEBUG,"cmdline:%s",sess->cmdline);
		//根据空格分割字符串
		lcw_ftpstr.str_split(sess->cmdline,sess->cmd,sess->arg,' ');
		//将命令转换为大写
		lcw_ftpstr.str_upper(sess->cmd);

		LCWFTPD_LOG(DEBUG,"cmd:%s",sess->cmd);
		LCWFTPD_LOG(DEBUG,"arg:%s",sess->arg);

		it = commandsmap.find(sess->cmd);//根据命令查找相应的执行函数
		if (it != commandsmap.end())
		{//存在和命令相对应的函数
			// LCWFTPD_LOG(DEBUG,"执行命令");
			(this->*(it->second))(sess);//执行命令
		}
		else
		{
			// LCWFTPD_LOG(DEBUG,"没有执行命令");
			// 500
			ftp_reply(sess,FTP_BADCMD,"Sorry! Unknown command");
		}

	}
}
Ejemplo n.º 8
0
static void do_rmd(session_t *sess)
{
	if(rmdir(sess->arg) < 0)
	{
		ftp_reply(sess, FTP_FILEFAIL, "Remove directory operation failed.");
		return;
	}
	ftp_reply(sess, FTP_RMDIROK, "Delete operation successful.");
}
Ejemplo n.º 9
0
void do_cmd_dele(session_t *pses)
{
    if(unlink(pses->arg) < 0)
    {
        ftp_reply(pses->ctrl_fd, FTP_FILEFAIL, "Delete operation failed.");
        return;
    }
    ftp_reply(pses->ctrl_fd, FTP_DELEOK, "Delete operation successful.");
}
Ejemplo n.º 10
0
void do_cmd_rmd(session_t *pses)
{
    if(rmdir(pses->arg) < 0)
    {
        ftp_reply(pses->ctrl_fd, FTP_FILEFAIL, "Remove directory operation failed.");
        return;
    }
    ftp_reply(pses->ctrl_fd, FTP_RMDIROK, "Remove directory operation successful.");
}
Ejemplo n.º 11
0
static void do_dele(session_t *sess)
{
	if(unlink(sess->arg) < 0)
	{
		ftp_reply(sess, FTP_FILEFAIL, "Delete operation failed.");
		return;
	}
	ftp_reply(sess, FTP_DELEOK, "Delete operation successful.");
}
Ejemplo n.º 12
0
void do_cmd_cdup(session_t *pses)
{
    if(chdir("..") < 0)
    {
        ftp_reply(pses->ctrl_fd, FTP_FILEFAIL, "Failed to change directory.");
        return;
    }
    ftp_reply(pses->ctrl_fd, FTP_CWDOK, "Directory successfully changed.");
}
Ejemplo n.º 13
0
void handle_child(session_t *pses)
{
    if(pses == NULL)
        handle_error_str("do_cmd_user: pses is NULL.");

    ftp_reply(pses->ctrl_fd, FTP_GREET, "(Mftp 0.1)");      //220
    int iret;
    while(true)
    {
        memset(pses->cmdline, 0, MAX_COMMAND_LINE);
        memset(pses->cmd, 0, MAX_COMMAND);
        memset(pses->arg, 0, MAX_ARG);
        iret = recvline(pses->ctrl_fd, pses->cmdline, MAX_COMMAND_LINE);//接收命令行
        if(iret == -1)
            handle_error("recvline");
        else if(iret == 0)
            handle_error("recvline");

        //去掉\r\n
        str_trim_crlf(pses->cmdline);
        //分割命令和参数
        str_split(pses->cmdline, pses->cmd, pses->arg, ' ');
        //将命令转换成大写
        str_upper(pses->cmd);

#ifdef _DEBUG_
        printf("cmd = [%s] arg = [%s]\n", pses->cmd,pses->arg);
#endif
        //处理ftp命令
        int len = ARRAYLEN(ctrl_cmds);
        int i = 0;
        for(i = 0; i < len; i++)
        {
            if(strcmp(ctrl_cmds[i].cmd, pses->cmd) == 0)
            {
                if(ctrl_cmds[i].cmd_handler != NULL)
                {
                    (*ctrl_cmds[i].cmd_handler)(pses);
                    //等价于ctrl_cmds[i].cmd_handler(pses);
                }
                else
                {
                    ftp_reply(pses->ctrl_fd, FTP_COMMANDNOTIMPL, "Unimplement command.");   //502
                }
                break;
            }
        }

        if(i >= len)
        {
            //没找到命令
            ftp_reply(pses->ctrl_fd, FTP_BADCMD, "Unknown command.");
        }

    }
}
Ejemplo n.º 14
0
/**
 *do_dele - 删除文件
 *@sess:会话结构体
 */
void ftpproto::do_dele(session_t* sess)
{
	//使用unlink删除文件
	if (unlink(sess->arg) < 0)
	{
		ftp_reply(sess,FTP_FILEFAIL,"Delete operation failed.");
		return;
	}
	ftp_reply(sess,FTP_DELEOK,"Delete operation successful.");
}
Ejemplo n.º 15
0
/**
 *do_cdup - 返回上层目录
 *@sess:会话结构体
 */
void ftpproto::do_cdup(session_t* sess)
{
	//更改到上层路径
	if (chdir("..") < 0)//这里好像也是可以切换到root的????
	{//更改路径失败
		ftp_reply(sess,FTP_FILEFAIL,"Failed to change directory.");
		return;
	}
	ftp_reply(sess,FTP_CWDOK,"Directory successful changed.");
}
Ejemplo n.º 16
0
/**
 *do_cwd - 改变当前路径
 *@sess:会话结构体
 */
void ftpproto::do_cwd(session_t* sess)
{
	//更改路径,此时路径已经存放于arg中
	if (chdir(sess->arg) < 0)//这里好像也是可以切换到root的????
	{//更改路径失败
		ftp_reply(sess,FTP_FILEFAIL,"Failed to change directory.");
		return;
	}
	ftp_reply(sess,FTP_CWDOK,"Directory successful changed.");
}
Ejemplo n.º 17
0
void limit_num_clients(session_t *sess)
{
    if (max_clients > 0 && sess->curr_clients > max_clients) {
        ftp_reply(sess, FTP_TOO_MANY_USERS, "There are too many users, please try again later");
        exit(EXIT_FAILURE);        
    }
    if (max_per_ip > 0 && sess->curr_ip_clients > max_per_ip) {
        ftp_reply(sess, FTP_IP_LIMIT, "There are too many connections from your ip.");
        exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 18
0
static void do_user(session_t* sess)
{
	struct passwd* pw = getpwnam(sess->arg);
	if(pw == NULL)
	{
		ftp_reply(sess, FTP_LOGINERR, "Login incorrect.");
		return;
	}

	sess->uid = pw->pw_uid;
	ftp_reply(sess, FTP_GIVEPWORD, "Please specify the password.");	
}
Ejemplo n.º 19
0
static void do_nlst(session_t *sess)
{
	if(get_transfer_fd(sess) == 0)
                return;

        ftp_reply(sess, FTP_DATACONN, "Here comes the directory listing.");

        list_common(sess, 0);
        close(sess->data_fd);
        sess->data_fd = -1;

        ftp_reply(sess, FTP_TRANSFEROK, "Directory send OK.");
}
Ejemplo n.º 20
0
static void do_rnto(session_t *sess)
{
	if(sess->rnfr_name == NULL)
	{
		ftp_reply(sess, FTP_NEEDRNFR, "RNFR required first.");
		return;
	}
	
	rename(sess->rnfr_name, sess->arg);
	ftp_reply(sess, FTP_RENAMEOK, "Rename successful.");
	
	free(sess->rnfr_name);
	sess->rnfr_name = NULL;
}
Ejemplo n.º 21
0
/**
 *do_user - 发送用户命令以供登陆
 *@sess:会话结构体
 */
void ftpproto::do_user(session_t* sess)
{
	LCWFTPD_LOG(DEBUG,"do_user");
	//USER scut_lcw
	struct passwd* pw = getpwnam(sess->arg);//根据用户名获取登陆相关的结构体
	if (pw == NULL)//用户不存在	
	{
		ftp_reply(sess,FTP_LOGINERR,"Oh no~Login incorrect.");
        return;
	}
	sess->uid = pw->pw_uid;//保存用户id
	//331
	ftp_reply(sess,FTP_GIVEPWORD,"Hi~Please specify the password.");
}
Ejemplo n.º 22
0
/**
 *do_rnto - 文件重命名,在rnfr后接收到,改后的文件名
 *@sess:会话结构体
 */
void ftpproto::do_rnto(session_t* sess)
{
	if (sess->rnfr_name == NULL)
	{
		//之前没有收到过RNFR命令
		ftp_reply(sess,FTP_NEEDRNFR,"RNFR required first.");
		return;
	}
	//arg保存的是改后的文件名
	rename(sess->rnfr_name,sess->arg);//重命名
	ftp_reply(sess,FTP_RENAMEOK,"Rename successful.");
	free(sess->rnfr_name);//释放内存
	sess->rnfr_name = NULL;
}
Ejemplo n.º 23
0
//获取目录详细清单
void do_cmd_list(session_t *pses)
{
    //创建数据连接
    if(get_transfer_fd(pses) < 0)
        return;
    //150
    ftp_reply(pses->ctrl_fd, FTP_DATACONN, "Here comes the directory listing.");
    //传输列表
    getdirlist(pses,1);
    //关闭数据套接字
    close(pses->data_fd);
    pses->data_fd = -1;
    //226
    ftp_reply(pses->ctrl_fd, FTP_TRANSFEROK, "Directory send OK.");
}
Ejemplo n.º 24
0
Archivo: main.c Proyecto: JnuSimba/UNP
void check_clients_limit(session_t* sess)
{
	if (tunable_max_clients > 0 && sess->num_clients > tunable_max_clients)
	{
		ftp_reply(sess, FTP_TOO_MANY_USERS, "There are too many connected users, Please try later.");
		exit(EXIT_FAILURE);
	}

	if (tunable_max_per_ip > 0 && sess->num_this_ip > tunable_max_per_ip)
	{
		ftp_reply(sess, FTP_TOO_MANY_USERS, 
			"There are too many connections from your internet address, Please try later.");
		exit(EXIT_FAILURE);
	}
}
Ejemplo n.º 25
0
void do_cmd_pass(session_t *pses)
{
    if(pses == NULL)
        handle_error_str("do_cmd_user: pses is NULL.");
    //收到密码后,开始用户验证
    //根据用户uid获取用户信息
    struct passwd *pw = getpwuid(pses->uid);    //尝试获取要登陆用户的信息
    if(pw == NULL)
    {
        //用户不存在
        ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530
        return;
    }
    //根据用户名字获取密码信息
    struct spwd *sp = getspnam(pw->pw_name);
    if(sp == NULL)
    {
        //用户不存在
        ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530
        return;
    }

    //将明文密码进行加密
    struct crypt_data data;
    data.initialized = 0;
    char *encrupted_pass = crypt_r(pses->arg, sp->sp_pwdp,&data);

    //加密结果对比
    if(strcmp(encrupted_pass, sp->sp_pwdp) != 0)
    {
        //验证失败
        ftp_reply(pses->ctrl_fd, FTP_LOGINERR, "Login incorrect."); //530
        return;
    }
    //密码验证成功
    ftp_reply(pses->ctrl_fd, FTP_LOGINOK, "Login successful."); //230

    //更改umask
    umask(tunable_local_umask);
    //更改进程属性
    if(setegid(pw->pw_gid) < 0)
        handle_error("setegid");
    if(seteuid(pw->pw_uid) < 0)
        handle_error("seteuid");
    //更改当前工作目录到用户家目录
    if(chdir(pw->pw_dir) < 0)
        handle_error("chdir");
}
Ejemplo n.º 26
0
/**
 *do_rnfr - 文件重命名,先发送的是rnfr,要重命名的文件名
 *@sess:会话结构体
 */
void ftpproto::do_rnfr(session_t* sess)
{//保存要重命名的文件名
	sess->rnfr_name = (char*)malloc(strlen(sess->arg) + 1);
	memset(sess->rnfr_name,0,strlen(sess->arg) + 1);
	memcpy(sess->rnfr_name,sess->arg,strlen(sess->arg) + 1);
	ftp_reply(sess,FTP_RNFROK,"Ready for RNTO.");
}
Ejemplo n.º 27
0
static void do_rnfr(session_t *sess)
{
	sess->rnfr_name = (char*)malloc(strlen(sess->arg) + 1);
	memset(sess->rnfr_name, 0, strlen(sess->arg) + 1);
	strcpy(sess->rnfr_name, sess->arg);
	ftp_reply(sess, FTP_RNFROK, "Ready for RNTO.");
}
Ejemplo n.º 28
0
static void do_list(session_t *sess)
{
	if(get_transfer_fd(sess) == 0)
		return;

	ftp_reply(sess, FTP_DATACONN, "Here comes the directory listing.");

	//transfer list	
	list_common(sess, 1);

	//client will still wait the data from server if the fd do not closed
	close(sess->data_fd);
	sess->data_fd = -1;

	ftp_reply(sess, FTP_TRANSFEROK, "Directory send OK.");
}
Ejemplo n.º 29
0
int get_transfer_fd(session_t* sess)
{
	//check have received port or pasv command before
	if(!port_active(sess) && !pasv_active(sess))
	{
		ftp_reply(sess, FTP_BADSENDCONN, "Use PORT or PASV first.");
		return 0;
	}

	int ret = 1;
	if(port_active(sess))
	{
		if(get_port_fd(sess) == 0)
			ret = 0;		
	}

	if(pasv_active(sess))
	{
		if(get_pasv_fd(sess) == 0)
                        ret = 0;
	}

	if(sess->port_addr)
	{
		free(sess->port_addr);
		sess->port_addr = NULL;
	}	

	if(ret) 
		start_data_alarm();

	return ret;
}
Ejemplo n.º 30
0
void handle_alarm_timeout(int aig)
{
	shutdown(p_sess->ctrl_fd, SHUT_RD);
	ftp_reply(p_sess, FTP_IDLE_TIMEOUT, "Timeout.");
	shutdown(p_sess->ctrl_fd, SHUT_WR);
	exit(EXIT_FAILURE);
}