miniftpd项目总结(二)

  1. 增加ftpcodes.h文件
  2. 命令映射
  3. 鉴权登录
  4. 其他杂项命令的实现
    1. 增加ftp中一些规定的回复命令的宏定义

    2. 映射机制,其实就是一个表(结构体数组),表中的元素是结构体(字符串+函数指针实现),函数指针的结构都是一样的:返回值为void,参数为session,这样才能够统一处理。解析完命令之后,遍历表执行相应的操作。要处理的问题;有的命令没有,有的命令有却没有实现,有的命令有并且也实现了(miniftp中实现的部分)。

    3. 鉴权登录的实现,主要依靠下面两个函数:

static void do_user(session_t *sess);//查验用户
static void do_pass(session_t *sess);//查验密码
//鉴权登录 系统命令实现
static void do_user(session_t *sess)
{
	struct passwd *pw = getpwnam(sess->arg);
	if(pw != NULL)
		sess->uid = pw->pw_uid;

	//331 Please specify the password.
	ftp_reply(sess, FTP_GIVEPWORD, "Please specify the password.");
}

通过getpwnam()函数,取用户名的密码结构体pw。结构体不为空,则将用户uid存入session的会话结构体中,给cli回复FTP_GIVEPWORD命令。
在这里插入图片描述

static void do_pass(session_t *sess)
{
	struct passwd *pw = getpwuid(sess->uid);
	if(pw == NULL)
	{
		//530 Login incorrect.
		ftp_reply(sess, FTP_LOGINERR, "Login incorrect.");
		return;
	}

	struct spwd *spw = getspnam(pw->pw_name);

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

	setegid(pw->pw_gid);//设置gid
	seteuid(pw->pw_uid);//设置uid
	chdir(pw->pw_dir);//改变当前目录

	//230 Login successful.
	ftp_reply(sess, FTP_LOGINOK, "Login successful.");
}

通过getpwuid()函数取uid对应的pw(密码结构体),通过getspnam()函数取该用户对应的spw(影子密码结构体)。通过crypt()函数对cli的明文密码加密,加密方式应该为DES加密(密钥为spw->sp_pwdp),将函数的返回值与sp_pwdp比较,若相同则密码正确。
在这里插入图片描述
crypt(const char *key, const char *salt)函数的第一个参数是明文,第二个参数是用来加密的密钥,返回值就是加密后的密文。
salt这个字符串如果以 $ 1 $ 开头,以$结尾,那么这表示让crypt用MD5的方式加密。默认的加密方式是DES加密方法,salt只能取前两个字符,多余的字符会被丢弃,用DES加密出来的密文前两个字符就是密钥,后面紧跟着的就是真正的密文。
主线必须由root用户启动,下面是实现方式:


	if(getuid() != 0)
	{
		fprintf(stderr, "miniftpd: must be started as root\n");
		exit(EXIT_FAILURE);
	}

通过getuid()函数的返回值判断是否是root用户。

4根据现有的ftpd服务器和客户端之间的交流,来驱动我们自己的服务器设计。例如:syst feat pwd type

PS:项目中好多功能的实现,都调用了系统函数。要求我们对Linux的各种API都能够熟练掌握,不熟悉的函数可以使用man在系统中查询

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值