// 函数目的:执行用户认证请求,处理认证流程并与认证服务通信
// 返回值:0表示成功,非0表示失败
__int64 panSwalAuthenticate(
__int64 alloc_ptr, // 内存分配器指针
int is_cms_auth, // 是否为CMS认证(1=是,0=否)
char *username, // 用户名
_BYTE *password, // 密码(可能为空)
__int64 protocol, // 协议类型
__int64 ip_address, // IP地址
__int64 accessible_vsys, // 可访问的虚拟系统(可能为空)
__int64 auth_result, // 认证结果存储结构
char *error_buf, // 错误信息缓冲区
unsigned int error_buf_size, // 错误缓冲区大小
__int64 client_info, // 客户端信息(可选)
__int64 extra_params, // 额外参数(可选)
__int64 *response_xml // 响应XML存储指针(可选)
) {
// 初始化变量
char *auth_request_xml = NULL;
char *sanitized_extra = NULL;
char *debug_request_xml = NULL;
char role_str[32] = {0};
int socket_fd = -1;
void *response_data = NULL;
int response_len = 0;
int result = 1; // 默认失败
// 清理错误缓冲区
*error_buf = 0;
// 处理可访问VSYS列表
if (accessible_vsys) {
// 复制VSYS列表到缓冲区
char *vsys_buf = create_string_buffer(alloc_ptr, strlen(accessible_vsys)+1);
if (!vsys_buf) {
set_error(error_buf, "Could not allocate buffer for VSYS names");
goto cleanup;
}
if (append_string(vsys_buf, accessible_vsys)) {
set_error(error_buf, "Could not copy VSYS names");
goto cleanup;
}
}
// 创建认证请求XML缓冲区
auth_request_xml = create_string_buffer(alloc_ptr, 1025);
debug_request_xml = create_string_buffer(alloc_ptr, 1025);
if (!auth_request_xml || !debug_request_xml) {
set_error(error_buf, "Could not allocate string buffers");
goto cleanup;
}
// 转义额外参数中的特殊字符
if (extra_params) {
sanitized_extra = xmlURIEscapeStr(extra_params, "\"' =");
}
// 构建认证请求XML
if (is_cms_auth) {
// CMS认证模式
get_role_string(*(int*)(auth_result+64), role_str, sizeof(role_str));
if (accessible_vsys && *accessible_vsys) {
// 包含VSYS列表的请求
append_xml(auth_request_xml,
"<auth-request username=\"%s\" cms-client=\"yes\" is-vsys-admin=\"yes\" "
"ip-address=\"%s\" protocol=\"%s\" role=\"%s\" %s",
username, ip_address, protocol, role_str, sanitized_extra);
if (client_info) {
append_xml(auth_request_xml, " client=\"%s\"", client_info);
}
append_xml(auth_request_xml, ">");
append_xml(auth_request_xml, "<vsys>");
// 添加每个VSYS
char *vsys = strtok(accessible_vsys, ",");
while (vsys) {
append_xml(auth_request_xml, "<member>%s</member>", vsys);
vsys = strtok(NULL, ",");
}
append_xml(auth_request_xml, "</vsys></auth-request>");
} else {
// 不包含VSYS列表的请求
append_xml(auth_request_xml,
"<auth-request username=\"%s\" cms-client=\"yes\" "
"ip-address=\"%s\" protocol=\"%s\" role=\"%s\" %s",
username, ip_address, protocol, role_str, sanitized_extra);
if (client_info) {
append_xml(auth_request_xml, " client=\"%s\"", client_info);
}
append_xml(auth_request_xml, "></auth-request>");
}
}
else if (password && *password) {
// 密码认证模式
append_xml(auth_request_xml,
"<auth-request username=\"%s\" passwd=\"%s\" "
"ip-address=\"%s\" protocol=\"%s\" %s",
username, password, ip_address, protocol, sanitized_extra);
// 创建调试用的请求(隐藏密码)
append_xml(debug_request_xml,
"<auth-request username=\"%s\" passwd=\"****\" "
"ip-address=\"%s\" protocol=\"%s\" %s",
username, ip_address, protocol, sanitized_extra);
if (client_info) {
append_xml(auth_request_xml, " client=\"%s\"", client_info);
append_xml(debug_request_xml, " client=\"%s\"", client_info);
}
append_xml(auth_request_xml, "></auth-request>");
append_xml(debug_request_xml, "></auth-request>");
}
else {
// 无密码认证模式
append_xml(auth_request_xml,
"<auth-request username=\"%s\" "
"ip-address=\"%s\" protocol=\"%s\" %s",
username, ip_address, protocol, sanitized_extra);
// 调试请求与认证请求相同
append_xml(debug_request_xml,
"<auth-request username=\"%s\" "
"ip-address=\"%s\" protocol=\"%s\" %s",
username, ip_address, protocol, sanitized_extra);
if (client_info) {
append_xml(auth_request_xml, " client=\"%s\"", client_info);
append_xml(debug_request_xml, " client=\"%s\"", client_info);
}
append_xml(auth_request_xml, "></auth-request>");
append_xml(debug_request_xml, "></auth-request>");
}
// 记录调试信息
if (log_level >= 800) {
log_debug("Auth request: %s", debug_request_xml);
}
// 连接到认证服务(本地127.0.0.1:10000)
socket_fd = connect_to_auth_service(0x7F000001, 10000);
if (socket_fd < 0) {
set_connection_error(error_buf);
goto cleanup;
}
// 发送请求并获取响应
response_data = send_and_receive(socket_fd, auth_request_xml, strlen(auth_request_xml), &response_len);
if (!response_data) {
goto close_socket;
}
// 可选: 保存原始响应XML
if (response_xml) {
*response_xml = create_string_buffer(alloc_ptr, response_len+1);
append_string(*response_xml, response_data);
}
// 记录响应调试信息
if (log_level >= 800) {
log_debug("Auth response: %s", response_data);
}
// 解析XML响应
xmlDocPtr doc = xmlReadMemory(response_data, response_len, "noname.xml", NULL, 0);
if (!doc) {
set_error(error_buf, "Error parsing XML response");
goto close_socket;
}
xmlNodePtr root = xmlDocGetRootElement(doc);
if (!root) {
set_error(error_buf, "Could not get root element");
goto free_doc;
}
// 处理认证响应
parse_auth_response(alloc_ptr, root, auth_result, error_buf, error_buf_size);
// 检查是否认证成功
if (strcmp((char*)(auth_result+132), "success") == 0) {
// 认证成功
strncpy(error_buf, (char*)(auth_result+420), error_buf_size);
result = 0;
}
free_doc:
xmlFreeDoc(doc);
close_socket:
close_socket(socket_fd);
cleanup:
// 释放所有资源
if (sanitized_extra) xmlFree(sanitized_extra);
if (auth_request_xml) free_string_buffer(auth_request_xml);
if (debug_request_xml) free_string_buffer(debug_request_xml);
if (response_data) free(response_data);
if (vsys_buf) free_string_buffer(vsys_buf);
return result;
}