修改: images/new_serialnum.odg 修改: images/new_serialnum.png 修改: serial.md Signed-off-by: Xu, Shunxuan <sxxu@linx-info.com>
7.0 KiB
新版Linx_serialnum设计说明书
1 引言
1.1 编写目的
本文档为新版序列号设计说明文档,作为编码、文档编写、及测试的依据。
1.2 项目概述
-
为便于技术支持的实施,修改添加序列号不需重启即可生效的机制。
-
修改新版序列号的key,原序列号在新系统中将不再适用。
-
原序列号只有在开机启动时才会触发检测/proc/cmdline中序列号是否正确,正确则网络可启用。新添加的序列号检测机制,当触发linxsn_trigger时,会调用函数检测/etc/default/grub中配置的序列号,若正确则网络可启用。
2 总体设计
-
原有机制的兼容
保留原有的开机启动检测内核参数(/proc/cmdline)中的序列号是否正确的检测机制。
-
更换原序列号的加密密钥key
由于序列号生成工具外流,导致对外安装的系统管理缺失。故需将序列号工具进行后台管理,更换密钥key,只有通过odoo进行申请,才会由后台工具生成可用序列号。
-
添加开机状态下添加序列号生效机制
由于序列号配置后需要重启系统才能生效,导致实施时间拉长,降低效率。为提高实施效率及查看序列号信息,添加序列号检测记录/proc/linxsn和不需重启系统的序列号生效机制。
-
添加生成虚拟机序列号
通过uuid加密换算出的序列号,便于管理虚拟机系统安装。
-
添加虚拟机序列号检测
添加虚拟机序列号检测机制:若为虚拟机,则序列号为通过uuid进行生成,相对应的要添加虚拟机序列号检测。(原序列号类型分为:时间序列号和mac地址永久序列号)
-
无root模式下的配置问题
在无root模式下,需sysadmin用户可对序列号进行修改及触发生效。
2.1 总体结构图
总体结构框架图:
检测序列号详解图:
添加需求及限制条件:(待补充)
-
在/proc/linxsn中记录序列号、为时间序列号(到期时间)或者永久序列号。
-
当检测为时间序列号时,检测出时间何时到期,打印提示。
-
添加虚拟机序列号检测(新类型序列号,检测为虚拟机,则通过uuid生成序列号)。序列号会有三种类型,即:时间序列号、mac地址永久序列号、虚拟机序列号。
2.2 运行环境
该软件系统的运行环境:Linx-6.0.42.41
3 功能模块设计实现
逐个说明各个模块的实现设计。
3.1 cmdline内核参数检测机制
原有序列号检测机制:开机启动网络时,检测/proc/cmdline内核参数中的序列号。获取到序列号后,通过解密检测序列号是否正确。(可参考内核序列号的pantch:linx_serial.patch)
// __setup这条宏在Linux Kernel中使用最多的地方就是定义处理Kernel的启动参数的函数及数据结构,宏定义如下:
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)
截取如下为获取/proc/cmdline中的序列号:
static int __init linxsn_setup(char *str)
{
unsigned int len;
memset(linxsn_buf, 0, LINXSN_LEN + 1);
len = strlen(str);
if ((len == LINXSN_LEN)||(len == OLD_LINXSN_LEN)) {
strcpy(linxsn_buf, str);
} else {
printk(KERN_WARNING "linx serial number length does \
not match, the length shuld be %d instead of %d", LINXSN_LEN, len);
}
linx_debug("linxsn_buf: %s", linxsn_buf);
return 1;
}
__setup("linx_serial=", linxsn_setup);
3.2 获取配置文件序列号参数
内核中打开文件函数:filp_open()在kernel中可以打开文件,其原形如下:
struct file* filp_open(const char* filename, int open_mode, int mode);
该函数返回strcut file*结构指针,供后继函数操作使用,该返回值用IS_ERR()来检验其有效性。
参数说明
filename: 表明要打开或创建文件的名称(包括路径部分)。在内核中打开的文件时需要注意打开的时机,很容易出现需要打开文件的驱动很早就加载并打开文件,但需要打开的文件所在设备还没有挂载到文件系统中,而导致打开失败。
open_mode: 文件的打开方式,其取值与标准库中的open相应参数类似,可以取O_CREAT,O_RDWR,O_RDONLY等。
mode: 创建文件时使用,设置创建文件的读写权限,其它情况可以匆略设为0
3.3 触发检测机制
proc文件的创建。创建方法是调用以下函数:
static inline struct proc_dir_entry *proc_create\
(const char *name, mode_t mode,struct proc_dir_entry *parent, const struct file_operations *proc_fops);
/*
name就是要创建的文件名。
mode是文件的访问权限,以UGO的模式表示。
parent与proc_mkdir中的parent类似。也是父文件夹的proc_dir_entry对象。
proc_fops就是该文件的操作函数。
*/
mytest_proc_fops的定义。
static const struct file_operations mytest_proc_fops = {
.open = mytest_proc_open,
.read = seq_read,
.write = mytest_proc_write, //做此函数去判断写入的触发值,正确则调用函数处理
.llseek = seq_lseek,
.release = single_release,
};
3.4 网络ioctl调用检测序列号机制
在网络的ioctl函数中,添加序列号检测,通过判断检测序列号的返回值,确定网络是否可用。
查看下述代码,只需在触发检测中,检测序列号正确则调用函数设置check_linxsn_flag=1即可。
diff -Nurp linux-2.6.32.41.orig//net/ipv4/devinet.c linux-2.6.32.41/net/ipv4/devinet.c
--- linux-2.6.32.41.orig//net/ipv4/devinet.c 2013-06-19 01:12:17.000000000 +0000
+++ linux-2.6.32.41/net/ipv4/devinet.c 2013-06-19 01:50:08.000000000 +0000
@@ -62,6 +62,19 @@
#include <net/rtnetlink.h>
#include <net/net_namespace.h>
+#ifdef CONFIG_LINX_SERIAL
+#include <linux/security.h>
+
+/*
+ * check_linxsn_flag
+ * 0: need first linx_serial_check
+ * 1: linxsn check correct
+ * 2: linxsn check incorrect
+ *
+ */
+static int check_linxsn_flag = 0;
+#endif
+
static struct ipv4_devconf ipv4_devconf = {
.data = {
[NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
@@ -590,6 +603,19 @@ int devinet_ioctl(struct net *net, unsig
char *colon;
int ret = -EFAULT;
int tryaddrmatch = 0;
+#ifdef CONFIG_LINX_SERIAL
+ if (check_linxsn_flag == 0) {
+ ret = linx_serial_check();
+ if (ret == -1) {
+ check_linxsn_flag = 2;
+ printk(KERN_INFO "linx serial number check failed.");
+ return -EINVAL;
+ }
+ check_linxsn_flag = 1;
+ } else if (check_linxsn_flag == 2) {
+ return -EINVAL;
+ }
+#endif
/*
* Fetch the caller's info block into kernel space

