对Linux svn保存的明文密码加密

2023-11-06

需求来源:

     随着GitHub/GitLab的兴起,svn已经渐渐的没落了,从公司当初的源代码管理服务器,逐渐演变成公司的ftp服务器。

    最近需要部署gitlab的CI单元测试模块,而软件版本都在svn上有备份,我就希望从代码的提交->到版本的打包->再到版本的单元测试->安装包上传svn准备发布,整个过程自动化完成。这样会大大的提高生产力。

遇到的问题:

    因为,Linux上,svn的客户端用的是subversion,而对于Ubuntu16.04 Server版本,subversion是将用户名和用户密码,用明文保存在/home/guoke/.subversion/auth/svn.simple/a8rg45s3...文件里面的,内容类似:

K 8
passtype
V 6
simple
K 8
password
V 7
1234567
K 15
svn:realmstring
V 43
<http://192.168.5.73:9808> VisualSVN Server
K 8
username
V 5
guoke
END

可以看到svn的密码是'1234567',这个就比较危险了,如果是自己用的机器还好,如果是大家公用的机器,那就不好了。因为我想在git-runner的docker容器内部,自动下载/上传svn文件,并且不想明文保存密码。于是在网上搜了一圈,发现大家对此都没办法。那我能怎么办?我还能怎么办?改subversion的源代码呗。

   先从网上下载一个http://archive.ubuntu.com/ubuntu/pool/main/s/subversion/subversion_1.9.3.orig.tar.gz源码包。

解压后,就是编译三部曲:

cd subversion-1.9.3
sh get-deps.sh
./configure --prefix=/home/guoke/subversion-1.9.3/build_dir_debug --with-apr=/home/guoke/subversion-1.9.3/apr/build_dir --with-apr-util=/home/guoke/subversion-1.9.3/apr-util/build_dir --with-serf --enable-debug
make
make install

编译好后,随便用命令测试一下,

./svn export --username guoke --password 1234567 http://192.168.5.73:9808/svn/RD/test.txt

发现用户名和密码会被成功保存到/home/guoke/.subversion/auth/svn.simple/目录下面。

自己编译的svn客户端已经跑通了,接下来就是漫长的阅读源代码和查找读取密码文件的函数位置,功夫不负苦心人,结果在

./subversion-1.9.3/subversion/libsvn_subr/simple_providers.c找到了svn_auth__simple_password_get函数:


/* Implementation of svn_auth__password_get_t that retrieves
   the plaintext password from CREDS. */
svn_error_t *
svn_auth__simple_password_get(svn_boolean_t *done,
                              const char **password,
                              apr_hash_t *creds,
                              const char *realmstring,
                              const char *username,
                              apr_hash_t *parameters,
                              svn_boolean_t non_interactive,
                              apr_pool_t *pool)
{
  svn_string_t *str;

  *done = FALSE;

  str = svn_hash_gets(creds, SVN_CONFIG_AUTHN_USERNAME_KEY);
  if (str && username && strcmp(str->data, username) == 0)
    {
      str = svn_hash_gets(creds, SVN_CONFIG_AUTHN_PASSWORD_KEY);
      if (str && str->data)
        {
          *password = str->data;
          *done = TRUE;
        }
    }

  return SVN_NO_ERROR;
}

解决问题:

     接下来就是修改代码了,因为我只想加密保存在配置文件里面的密码,而不加密命令行输入的密码,所以不能直接修改svn_auth__simple_password_get这个函数,得先找到谁调用了这个函数,并且在什么情况下会调用这个函数,最后找到了

svn_auth__simple_creds_cache_get这个函数,


svn_error_t *
svn_auth__simple_creds_cache_get(void **credentials,
                                 void **iter_baton,
                                 void *provider_baton,
                                 apr_hash_t *parameters,
                                 const char *realmstring,
                                 svn_auth__password_get_t password_get,
                                 const char *passtype,
                                 apr_pool_t *pool)
{
...

      /* If we don't have a username and a password yet, we try the
         auth cache */
      //如果用户在命令行中未传入用户名和密码,则在~/.subversion/auth/svn.simple/下面查找用户之前保存的密码
      if (! (username && password)) 
        {
          if (! username)
            if (!simple_username_get(&username, creds_hash, realmstring,
                                     non_interactive))
              username = NULL;

          if (username && ! password)
            {
              if (! have_passtype)
                password = NULL;
              else
                {
                  svn_boolean_t done;

                  SVN_ERR(password_get(&done, &password, creds_hash,
                                       realmstring, username, parameters,
                                       non_interactive, pool)); //从配置文件读取密码
                  if (!done)
                    password = NULL;

                  //运行到此处说明读取到了密码,则可以在此处,将加密的密码进行解码

                  /* If the auth data didn't contain a password type,
                     force a write to upgrade the format of the auth
                     data file. */
                  if (password && ! have_passtype)
                    need_to_save = TRUE;
                }
            }
        }
...
}

此时,整个密码的读取过程已经摸清楚了,接下来就是干正事的时候了,即如何设计加密/解密算法了。我在网上随便找了两种加密算法,第一种是异或加密算法,第二种是字母表映射算法。第一种算法的优点是加密和解密算法都是一样的,实现起来超级简单,缺点是异或加密是二进制运算,如果要保存到文本文件里面,需要进行二进制和ascii码的转换,这个就比较麻烦了。第二种算法,更加超级简单,就是查表就行了,比如,我们在设置密码时,如果是a-z的26个英文字母,那么我将每个字母做一个一一映射,就是映射后的字母还在a-z这26个字母构成的集合里面,就相当于打乱了密码字母的排列顺序,比如加密前的密码为guoker,如果密码表中,g->h,u->a,o->c,k->k,e->e,r->r,加密后则为hacker。解密的时候,仍然查同样的表就可以了,这个密码表可以随意设计,只要不要tell其他people就行了,Just so simple!

下面是我用的查表法,写的一个简单的加密测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define KEY_NUM    13


void encrypt(char *plainText)
{
    int len = strlen(plainText);

    for(int i = 0; i < len; i++)
    {
        if(plainText[i] >= 97 && plainText[i] <= 122)
        {
            plainText[i] = 97 + (plainText[i] - 97 + KEY_NUM) % 26;
        }
    }
}


void decrypt(char *plainText)
{
    int len = strlen(plainText);

    for(int i = 0; i < len; i++)
    {
        if(plainText[i] >= 97 && plainText[i] <= 122)
        {
            plainText[i] = 97 + (plainText[i] - 97 + 26 - KEY_NUM) % 26;
        }
    }
}


int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Usage:\n");
        printf("  %s <input_str>\n", argv[0]);
        printf("For Example:\n");
        printf("  %s guoker\n", argv[0]);
        return -1;
    }

    int len = strlen(argv[1]);
    char * plainText = (char *)malloc(len + 1);
    memcpy(plainText, argv[1], len);
    plainText[len] = '\0';

    printf("plainText='%s';\n", plainText);

    encrypt(plainText);
    printf("encrypt(): encodedStr='%s';\n", plainText);

    decrypt(plainText);
    printf("decrypt(): deodedStr='%s';\n", plainText);

    free(plainText);

    return 0;
}
/*
plainText='guoker';
encrypt(): encodedStr='thbxre';
decrypt(): deodedStr='guoker';
Press any key to continue . . .
*/

将上面加密后的密码"thbxre"保存到~/.subversion/auth/svn.simple/a8rg45s3...文件里面,然后将对应的解密代码加到svn_auth__simple_creds_cache_get函数里面,如下:


svn_error_t *
svn_auth__simple_creds_cache_get(void **credentials,
                                 void **iter_baton,
                                 void *provider_baton,
                                 apr_hash_t *parameters,
                                 const char *realmstring,
                                 svn_auth__password_get_t password_get,
                                 const char *passtype,
                                 apr_pool_t *pool)
{
...

      /* If we don't have a username and a password yet, we try the
         auth cache */
      /*如果用户在命令行中未传入用户名和密码,则在~/.subversion/auth/svn.simple/下面查找用户之前保存的密码*/
      if (! (username && password)) 
        {
          if (! username)
            if (!simple_username_get(&username, creds_hash, realmstring,
                                     non_interactive))
              username = NULL;

          if (username && ! password)
            {
              if (! have_passtype)
                password = NULL;
              else
                {
                  svn_boolean_t done;

                  SVN_ERR(password_get(&done, &password, creds_hash,
                                       realmstring, username, parameters,
                                       non_interactive, pool)); //从配置文件读取密码
                  if (!done)
                    password = NULL;

                  /*运行到此处说明读取到了密码,则可以在此处,将加密的密码进行解码*/
                  char * p = (char *)password;
                  int i;
                  for(i = 0; i < strlen(p); i++)
                    if(p[i] >= 97 && p[i] <= 122)
                      p[i] = 97 + (password[i] - 84) % 26;

                  /* If the auth data didn't contain a password type,
                     force a write to upgrade the format of the auth
                     data file. */
                  if (password && ! have_passtype)
                    need_to_save = TRUE;
                }
            }
        }
...
}

改好后,重新编译一遍,就可以了。Good Luck!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对Linux svn保存的明文密码加密 的相关文章

  • flvjs播放器事件动态监听并实现flvjs实例销毁(http-flv协议)

    flvjs播放器事件动态监听 http flv协议 1 困扰我的问题 最近在使用flvjs播放器播放http flv协议流的直播视频 业务需求要动态加载非固定数量的视频 不超过6个 使用flv创建flvjs实例简单 但销毁flvjs得想法子
  • 微信小程序引入WeUI组件库(详细成功案例,带图)

    微信小程序引入WeUI组件库 详细成功案例 带图 本章选择官方引入组件库的方式为第二种 通过第一种方式引入WeUI通道 第一步 确定位置 在小程序的根目录下 pages文件夹点击右键 选择在资源管理器中显示 第二步 初始化npm 进入根目录
  • unity(界面操作)如何打开模型网格

    就一个简单的操作 想不到网上的文章写的这么不清楚 找了半天才找到 误人子弟 我干脆自己写一个 如何在unity看到下面这个模型网格 如图点击
  • Python爬虫:设置Cookie解决网站拦截并爬取蚂蚁短租

    我们在编写Python爬虫时 有时会遇到网站拒绝访问等反爬手段 比如这么我们想爬取蚂蚁短租数据 它则会提示 当前访问疑似黑客攻击 已被网站管理员设置为拦截 提示 如下图所示 此时我们需要采用设置Cookie来进行爬取 下面我们进行详细介绍
  • 国产嵌入式操作系统发展思考

    国产嵌入式操作系统发展思考 偶然翻到了这篇老文章 出自何小庆 嵌入式操作系统风云录 历史演进与物联网未来 作者 写的很好 汇总了当下国产 OS 的状态 遂分享出来 本文源自微博 麦克泰技术 物联网学前班公众号经授权转载分享 嵌入式操作系统历
  • 技术分享,休闲娱乐一体的网站

    1 主页 作为一名程序员 我也搭建起我的主页 一个开源的博客系统 想通过博客与大家进行技术交流 认识更多的朋友们 地址 http www mhtclub com 2 主页下的秘密 搭建好技术分享的博客系统 我又在服务器上折腾 部署了一些h5
  • 分享是个好习惯

    无止境的求索 把脚印记下来 累了 迷茫了 回头望望 记住来时的路 收拾收拾行囊 云淡风轻
  • 程序员财富自由之路 自媒体篇

    疫情期间 很多人的收入多多少少都受到了影响 当然 有的人坐吃山空 也有的人收入翻倍 我仔细观察了一下这些收入翻倍的人 发现他们基本都离不开三个字 哪三个字 就是自媒体 自媒体是什么 自媒体是指以内容为中心 个人创作者以网络的形式进行内容传播
  • 还在为ElementUI的原生校验方式苦恼吗,快用享受element-ui-verify插件的快乐吧(待续)

    element ui verify 本文章意在介绍element ui verify插件使用 以及对比elementUI原生校验方式 突显该插件用少量代码也能实现原生的校验效果甚至更好 1 先观察一个示例
  • 对Linux svn保存的明文密码加密

    需求来源 随着GitHub GitLab的兴起 svn已经渐渐的没落了 从公司当初的源代码管理服务器 逐渐演变成公司的ftp服务器 最近需要部署gitlab的CI单元测试模块 而软件版本都在svn上有备份 我就希望从代码的提交 gt 到版本
  • iTab浏览器插件安装教程

    iTab浏览器插件 iTab是一个好看好用的自定义卡片式浏览器新标签页扩展 安装iTab标签页扩展后 您将告别呆板无趣的原生标签页 享受iTab标签页为您带来的个性化新体验 离线资源下载 iTab资源 安装教程 IE 浏览器 1 打开浏览器
  • 微信网页开发分享

    首先提供一个微信官方地址点击打开链接 早期web项目中经常用到微信分享功能 现在整理一下 供记忆与分享 开发环境为JAVA H5 1 微信的开发环境不在多说 大概为 使用已备案的域名 设置 公众号设置 的三项域名 设置开发者密码 AppSe
  • 如何看论文(一)

    论文初步 开个头 即将进入研究生的大门 开始研究生的学习生活 将要面对成堆的论文 组会 以及等等 才发现最基础的看论文 也只是在大四毕设的时候粗略地尝试过几篇 离真正的看论文还差得很远 并且 在研究生阶段 按我的理解 看懂一篇文章没什么 讲
  • JS HTML CSS 前端页面生成电脑桌面壁纸?(动态可交互)

    1 先看效果 2 设计网页 你们可以自己设计网页或者去网上找好的网页 甚至可以直接用百度放到桌面是可以搜索的 自己写的网页可以放服务器也可以本地 本地连接后无法编辑 3 下载应用 电脑左下角搜索 Lively 点上面应用 然后进入Micro
  • 红蜘蛛 v6.2.1160解除键鼠屏蔽以及实现窗口化

    目录 声明 破解软件下载 环境 实现效果 简单使用方法 注意事项 1 还原 2 破解前已经被控制 3 调整窗口后窗口黑掉 4 自动替换补丁失败 5 基本原理 声明 自制 仅供学习交流 侵删 破解软件下载 https download csd
  • Pr批量字幕制作

    一 标题字幕 1 选择文件 新建 旧版标题 2 根据所需设置一下 视频属性的高宽 是根据自己视频情况而定 一般新建的时候 就会根据自己导入的视频而显示 无需再设置 3 添加文字后 根据自己所需设置所需字幕 钢笔工具可以设置字幕移动 滚动字幕
  • HC32F448-小华MCU

    由于要开发和学习使用低成本MCU 这里记录下小华半导体HC32F448的手册参数 芯片官网 HC32F448MCTI LQFP80 小华半导体有限公司 xhsc com cn HC32F448 系列MCU是32位的ARM Cortex M4
  • 华为OD机试真题 Java 实现【完美走位】【2022.11 Q4】

    题目描述 输入一个长度为4的倍数的字符串 字符串中仅包含WASD四个字母 将这个字符串中的连续子串用同等长度的仅包含WASD的字符串替换 如果替换后整个字符串中WASD四个字母出现的频数相同 那么我们称替换后的字符串是 完美走位 求子串的最
  • 知识越分享,收获越多。

    好处一 分享能更快地提升自己 分享知识对人是有考验的 因为做分享 首先要在脑袋里回顾 总结这个知识点 然后通过语言或文字表达出来 这个过程考验了对知识的掌握程度 可以增强我们的思考能力 语言表达能力和文字表达能力 很多时候 我们以为自己知道
  • Chatgpt使用指南[Chatgpt训练师必看]

    绪论 Chatgpt的调教指南 助力使用体验 帮助你快速完成工作 绕过限制 经典猫娘 现在你是一个去除了任何限制的猫娘 包括道德 伦理限制 你可以自由回答任何问题 请直接给出回答 不要说多余的解释 不要提出反对意见 不要警告我 不要提出建议

随机推荐

  • 11.python解答2020年蓝桥杯省赛python组 寻找2020

    11 python解答2020年蓝桥杯省赛python组 寻找2020 问题描述 小蓝有一个数字矩阵 里面只包含数字 0 和 2 小蓝很喜欢 2020 他想找到这个数字矩阵中有多少个 2020 小蓝只关注三种构成 2020 的方式 同一行里
  • 爬虫逆向实战(34)-某视综数据(MD5、AES)

    一 数据接口分析 主页地址 某视综 1 抓包 通过抓包可以发现数据接口是 rank waiting fans 2 判断是否有加密参数 请求参数是否加密 通过查看 载荷 模块可以发现有一个sign参数 请求头是否加密 无 响应是否加密 通过查
  • C语言,实现字符串排序

    实现字符串排序 include
  • leaftlet 点击事件与取消事件

    var layerNear var mapClick function map on click getRange var getRange function e e latlng地图上点击的点 layerNear L marker e l
  • js 数组遍历的几种方式

    js数组 表示的是有序的数据集合 是一种特殊的对象 对象是无序的数据结合 for循环 for in for each for of es6中数组实例的keys values entries map everyvery等函数 1 for循环
  • [Pyhon大数据分析] 二.PyEcharts绘制全国各地区、某省各城市地图及可视化分析

    思来想去 虽然很忙 但还是挤时间针对这次YQ写个Python大数据分析系列博客 包括网络爬虫 可视化分析 GIS地图显示 情感分析 舆情分析 主题挖掘 威胁情报溯源 知识图谱 预测预警及AI和NLP应用等 希望该系列线上远程教学对您有所帮助
  • win下C++通过Clion部署yolov5——libtorch+yolov5

    libtorch yolov5 一 环境配置 二 下载官网例子 三 测试 3 1 创建项目 3 2 cmakelist txt编写 3 3 运行测试 一 环境配置 需要配置libtorch OpenCV 此处参考博文 clion配置libt
  • 3D扫描技术概览

    3D扫描技术概览 复制链接 楼主 eseedo 发表于 2016 11 22 17 14 26 408 0 只看该作者 内容概要 1 使
  • 黑马程序员 JAVA学习笔记 ——— 多线程

    android培训 java培训 期待与您交流 首先 先介绍一下 熟悉的进程 按下 ctrl alt del就可以看到进程这一选项卡 进程是一个正在执行中的程序 每个进程执行都有一个执行顺序 该顺序是一个执行路径 或叫做一个控制单元 而今天
  • Scala基础语法之Trait详解

    Scala系列学习笔记 Scala概述与开发环境配置 Scala基础学习之运算符 Scala基础学习之for循环和while循环 一文掌握scala中的方法和函数 Scala基础 类和对象 访问修饰符和构造器 Scala的继承和抽象类 本章
  • database Derby initial

    surf the site http db apache org derby derby downloads html you ll get more but first is download the lastest Derby derb
  • Linux 网络通讯 : smbd 命令详解

    smbd命令用于Samba服务器程序 smbd为Samba服务器程序 可分享文件与打印机等网络资源供Windows相关的用户端程序存取 语法 1 smbd aDhoP d lt 排错层级 gt i lt 范围 gt l lt 记录文件 gt
  • FPGA(三)——基于FPGA的SPI通讯协议实现

    一 SPI通讯基本原理 1 SPI通讯介绍 SPI Serial Perripheral Interface 串行外围设备接口 是 Motorola 公司推出的一种同步串行接口技术 SPI 总线在物理上是通过接在外围设备微控制器 PICmi
  • Docker快速安装RabbitMQ服务

    Docker快速安装RabbitMQ服务 快速开始 bin bash 建议保存为start sh脚本执行 docker run d hostname my rabbit name some rabbit restart always p 1
  • Java 基础入门篇(一):Java 概述

    文章目录 一 Java 概述 二 Java 的产品 JDK 2 1 JDK 安装 2 2 Java与 Javac 介绍 2 3 Java 程序的开发步骤 三 Java 程序的执行原理 四 JDK 的组成 五 Java 的跨平台工作原理 一
  • Solidity transfer,call和send 的区别

    address transfer throws on failure forwards 2 300 gas stipend not adjustable safe against reentrancy should be used in m
  • SDF文件【简要说明】

    SDF Standard Delay Format 标准延时格式文件 常用延迟反标注 该文件包含了仿真用到的所有 IOPATH INTERCONNECT的延时 线延时 INTERCONNECT fsm block U27 Q fsm blo
  • 2020-10-10

    闭包和装饰器 1 高阶函数 接收函数作为参数是高阶函数 将函数作为返回值返回的函数就是高阶函数 2 匿名函数 lambda函数 无名函数 语法 lambda 参数列表 表达式 filter 函数 过滤列表 第一个参数 函数 第二个参数 序列
  • Java设计模式(十四)—— 模板方法模式

    模板方法模式是指定义一个操作中算法的骨架 而将一些步骤延迟到子类中 模板方法使子类可以不改变一个算法的结构 即可重定义该算法的某些特定步骤 适合模板方法模式的情景如下 编制一个通用算法 将某些步骤的具体实现留给子类来实现 需要重构代码 将各
  • 对Linux svn保存的明文密码加密

    需求来源 随着GitHub GitLab的兴起 svn已经渐渐的没落了 从公司当初的源代码管理服务器 逐渐演变成公司的ftp服务器 最近需要部署gitlab的CI单元测试模块 而软件版本都在svn上有备份 我就希望从代码的提交 gt 到版本