Git Product home page Git Product logo

flamingo's People

Contributors

balloonwj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flamingo's Issues

网络故障

您好。注册的时候出现网络故障,服务器端的chatserver的端口号不是8888,请问怎么解决?

编写语言

您用java 编写的该软件 为什么要归类到c++中去?
还有好多文档打开是空的?
我看你这个里面确实有 c++ 也有java 两个可以混用?我是菜鸟 求指教?

mysqlclient not found

ubuntu
我已安装mysql-server mysql-client
但还是在cmake步骤提示:
CMake Error at CMakeLists.txt:14 (MESSAGE):
mysqlclient not found
如何是好?

TimerQueue中的doTimer()函数

`
void TimerQueue::doTimer()
{
loop_->assertInLoopThread();

Timestamp now(Timestamp::now());

for (auto iter = timers_.begin(); iter != timers_.end(); )
{
    //if (iter->first <= now)
    if (iter->second->expiration() <= now)
    {
        //LOGD("time: %lld", iter->second->expiration().microSecondsSinceEpoch());
        iter->second->run();
        if (iter->second->getRepeatCount() == 0)
        {
            iter = timers_.erase(iter);
        }
        else
        {
            ++iter;
        }
    }
    else
    {
        break;
    }           
}

`
在TimerQueue中的doTimer()函数中,最外层的else里面应该是continue而不是break吧

fileserver程序崩溃问题

问题描述:A发送文件给B,同时C发送文件给D,其中任何一组发送完成都会导致fileserver服务崩溃。
问题原因:FileServer::onDisconnected 函数逻辑错误,任何会话完成传输都会清理掉其他会话。
我的解决方法:

void FileServer::onDisconnected(const std::shared_ptr<TcpConnection>& conn)
{
    std::lock_guard<std::mutex> guard(m_sessionMutex);
    for (auto iter = m_sessions.begin(); iter != m_sessions.end(); ++iter)
    {
        if ((*iter)->getConnectionPtr() == NULL)
        {
            LOGE("connection is NULL");
            continue;
        }
        if ((*iter)->getConnectionPtr() == conn)
        {
            //用户下线
            m_sessions.erase(iter);
            //bUserOffline = true;
            LOGI("client disconnected: %s", conn->peerAddress().toIpPort().c_str());
            break;
        }
    }    
}

handleEventWithGuard 函数疑惑

4142819
这个函数这里怎么这样设计, void Channel::handleEvent(Timestamp receiveTime)这个里面直接调用handleEventWithGuard不行么? 为啥还要加个shared

flamingo bug反馈页面

##########flamingo bug反馈页面###################
注意:反馈bug时请说明flamingo的代码来源和终端类型(服务器、pc、还是安卓),并说清楚出现bug的步骤。

数据传输协议的包头部分为什么不需要考虑byte order?

您好,我最近在学习这款开源框架的源代码。有个疑问是为什么数据传输协议里的包头部分可以直接拷贝内存而不需要转换字节序?

服务端代码:ChatSession::onLoad()

//取包头信息
chat_msg_header header;
memcpy(&header, pBuffer->peek(), sizeof(chat_msg_header));

客户端代码:IUSocket::Login()

msg header;
memset(&header, 0, sizeof(header));
header.compressflag = 1;
header.originsize = outbuf.length();
header.compresssize = strDestBuf.length();

//std::string strX;
//if (!::UncompressBuf(strDestBuf, strX, header.originsize))
//{
//    int x = 0;
//}

std::string strSendBuf;
strSendBuf.append((const char*)&header, sizeof(header));
strSendBuf.append(strDestBuf);

客户端发送图片功能不可用

起了两个客户端,一个客户端A,一个客户端B
客户端A向客户端B发送图片文件,客户端A的日志显示upload文件成功,在imgserver上面的imgcache目录下也看到了md命名的文件

但是客户端B下载文件失败,客户端失败日志如下:
[2019-04-10 15:37:13:0378][INFO][ThreadID: 3236260][bool __thiscall CIUSocket::ConnectToImgServer(int):428]Connect to img server:118.24.67.107, port:20002 successfully.
[2019-04-10 15:37:13:0378][Error][ThreadID: 3236260][bool __thiscall CIUSocket::SendOnImgPort(const char *,__int64,int):674]Send data error, disconnect img server:118.24.67.107, port:20002, socket errorCode: 10057.
[2019-04-10 15:37:13:0378][Error][ThreadID: 3236260][void __thiscall CIUSocket::CloseImgServerConnection(void):787]Disconnect img server:118.24.67.107, port:20002.
[2019-04-10 15:37:13:0378][Error][ThreadID: 3236260][long thiscall CImageTaskThread::DownloadImage(const char *,const wchar_t *,int,struct HWND *,void *):617]Failed to download image: E:\chenqw\Bin\Users\15877860558\ChatImage\cc665afa6d80769676618de0c53fdb6c.jpg.

仔细看了一下源代码,上传和下载的逻辑都调用同样的接口发起connect 为什么会上传成功 下载失败? 是不是imgserver处理的有问题?

Directory traversal vulnerability exists in uploaded and downloaded files

Directory traversal

Through code audit, it is found that the file download function in flamingo has a problem with directory traversal. Through this vulnerability, files can be downloaded anywhere on the server through the directory.

Test environment

mysql> select version(); 
+-------------------------+ 
| version()        | 
+-------------------------+ 
| 5.7.32-0ubuntu0.16.04.1 | 
+-------------------------+ 
1 row in set (0.02 sec) 

Vulnerability analysis

Flamingo is a C/S mode communication software.User A sends the file to user B. The server saves the file in A specific folder of the server and waits for User B to receive it. After User B sends the receive request, the server sends the corresponding file to user B.

When uploading files, use the result of file md5 encoding as the file name (unfortunately, the encryption process is on the client side).

The base directory of the cache file is hard-coded in the configuration file, and the corresponding file path is directly spliced ​​through the base directory and the md5 result. The file has no identification for a specific user, all files exist together, and there is no distinction between different users (that is, the server does not know who the file belongs to, and it can be downloaded as long as the correct file path is provided to the server).

Poc

From the simple analysis above, it can be seen that this file transfer function has a lot of security issues. Only the most serious problems are demonstrated here.

It can be seen from the declaration of the onDownloadFileResponse function in FileSession.cpp

string filename = m_strFileBaseDir;
filename += filemd5;
m_fp = fopen(filename.c_str(), "rb+");

Since the download path is directly spliced ​​by the base directory and the md5 result, as long as the file name can be controlled, the file name of the form ../../../pwd.txt can be used to achieve directory traversal and download any file .

Flamingo's problem is that MD5 encryption is done on the client side, and because the communication protocol is open source, it is easy to forge.

Find the location where the client sends the download command and tamper with the file name.

Add the following statement to the filetaskThread.cpp

image

2
3
4

During the test, it is found that when the tampered file path does not exist, the server will first create the file, then write the contents of the sent file, and then download it for the recipient.So using this vulnerability can also achieve arbitrary location write (can be multi-level directory traversal).

5

Send the file again here.The file is written on Desktop.

6

windows客户端bug

CIUSocket::ConnectToFileServer和CIUSocket::ConnectToImgServer中select等待写事件时:
FD_SET(m_hSocket, &writeset);
应该是:
FD_SET(m_hFileSocket , &writeset);

make的时候报错

up主你好,我用的系统是centos7.4 MySQL用的是8.0,mysql 文件夹在/usr/include下,make报错,请问跟mysql的版本有关吗
image

win10兼容

WIN10截图不能保存 新建群没反应

安卓客户端无法使用

安装客户端,无法修改和保存服务器地址,收取信息错乱,对方发送到图片,显示空白消息,对方发送表情,收到的不同的表情,发送消息给对方无法接收。

There are security risks in the operation of the server on the database

issue 1

Vulnerability

There is a SQL injection vulnerability in the UserManager::addUser method.
The related business corresponding to the method is the registered account.
userid,username, nickname can be controlled, no filtering measures, and directly execute the entire SQL statement.

Looking at the code, it is found that the client does not encrypt the transmission data, and the registration information is returned to the server in clear text. Therefore, it can be injected directly in the client registration window.

bool UserManager::addUser(User& u) 
{
    ……
    ……
    ……
  char sql[256] = { 0 }; 
  snprintf(sql, 256, "INSERT INTO t_user(f_user_id, f_username, f_nickname, f_password, f_register_time) VALUES(%d, '%s', '%s', '%s', NOW())", m_baseUserId.load(), u.username.c_str(), u.nickname.c_str(), u.password.c_str()); 
  if (!pConn->execute(sql)) 
  { 
    LOGW("insert user error, sql: %s", sql); 
    return false; 
  }
    ……
    ……
}

Poc

payload:ad','ad','ads',sleep(10));# or ad','ad','ads',user());#

image-20201127181759303

image-20201127181736841
image-20201127181306241

issue 2

Vulnerability

There is a SQL injection vulnerability in the UserManager::updateUserTeamInfoInDbAndMemory method.

newteaminfo can be controlled

bool UserManager::updateUserTeamInfoInDbAndMemory(int32_t userid, const std::string& newteaminfo)
{
    ……
    ……
    std::ostringstream osSql;
    osSql << "UPDATE t_user SET f_teaminfo='"
        << newteaminfo << "' WHERE f_user_id="
        << userid;
    if (!pConn->execute(osSql.str().c_str()))
    {
        LOGE("Update Team Info error, sql: %s", osSql.str().c_str());
        return false;
    }
    ……
    ……
}

Poc

The client has an input length limit, but the defense of the client is invalid. Hard code the payload into the program.

payload: 1"}]' or updatexml(2,concat(0x7e,version()),0) or'

image-20201127185848277

image-20201127175641422

issue 3

Vulnerability

There is a SQL injection vulnerability in the UserManager::addGroup method.

groupname can be controlled

bool UserManager::addGroup(const char* groupname, int32_t ownerid, int32_t& groupid)
{
    ……
    ……
    ++m_baseGroupId;
    char sql[256] = { 0 };
    snprintf(sql, 256, "INSERT INTO t_user(f_user_id, f_username, f_nickname, f_password, f_owner_id, f_register_time) VALUES(%d, '%d', '%s', '', %d,  NOW())", m_baseGroupId.load(), m_baseGroupId.load(), groupname, ownerid);
    if (!pConn->execute(sql))
    {
        LOGE("insert group error, sql: %s", sql);
        return false;
    }
	……
    ……
        
}    

Create a group chat function can trigger this function.
image-20201126161703629

payload: 1','','1',version());#

The client has an input length limit, but the defense of the client is invalid. Hard code the payload into the program.

Find the place where the client sends the json, and hard code the payload in.
image-20201127173507099

image-20201127173537619

issue 4

Vulnerability

There is a SQL injection vulnerability in the UserManager::updateUserInfoInDb method.

bool UserManager::updateUserInfoInDb(int32_t userid, const User& newuserinfo)
{
    ……
    ……
    std::ostringstream osSql;
    osSql << "UPDATE t_user SET f_nickname='"        
          << newuserinfo.nickname << "', f_facetype=" 
          << newuserinfo.facetype << ", f_customface='" 
          << newuserinfo.customface << "', f_gender=" 
          << newuserinfo.gender << ", f_birthday=" 
          << newuserinfo.birthday << ", f_signature='" 
          << newuserinfo.signature << "', f_address='" 
          << newuserinfo.address << "', f_phonenumber='" 
          << newuserinfo.phonenumber << "', f_mail='" 
          << newuserinfo.mail << "' WHERE f_user_id=" 
          << userid;
    if (!pConn->execute(osSql.str().c_str()))
    {
        LOGE("UpdateUserInfo error, sql: %s", osSql.str().c_str());
        return false;
    }

	……
    ……
}

Poc

payload:1' or updatexml(2,concat(0x7e,version()),0) or'

image-20201127172802358
image-20201127172602931

请问一下,对于ByteBuffer makeSpace函数会经常把数据往前移动,也就是说拷贝,这个会比较费吗?

image

上图中的

 void makeSpace(size_t len)
        {
            //kCheapPrepend为保留的空间
            if (writableBytes() + prependableBytes() < len + kCheapPrepend)
            {
                // FIXME: move readable data
                m_buffer.resize(m_writerIndex + len);
            }
            else
            {
                // move readable data to the front, make space inside buffer
                //assert(kCheapPrepend < readerIndex_);
                if (kCheapPrepend >= m_readerIndex)
                    return;

                size_t readable = readableBytes();
                std::copy(begin() + m_readerIndex,
                    begin() + m_writerIndex,
                    begin() + kCheapPrepend);
                m_readerIndex = kCheapPrepend;
                m_writerIndex = m_readerIndex + readable;
            }
        }

应该在收包的过程中,这种copy数据应该是很常发生的

建议:注册和登录机制

你好 开发人员

建议使用这种登录机制

  • 只能通过验证码登录,邮箱接收手机号验证码
  • 给用户一个随机电话号码。 您可以创建自己的区号示例 有几个未使用的前缀。 三位数前缀太多,二位数前缀是三个; +23、+83、+89……

编译时报错,静态断言.怎么搞...

报错:
flamingoserver/base/fileutil.cpp:89:2: error: static assertion failed: sizeof(off_t) not 8
static_assert(sizeof(off_t) == 8, "sizeof(off_t) not 8");
我用的是卡片机,大概得改源码才行了吧.

StringUtil::cut函数有bug

StringUtil::cut函数中,给substr2赋值时,应该偏移delimiterlength,而不是1,
源代码
substr2 = buf.substr(pos + 1);
应修改为
substr2 = buf.substr(pos + delimiterlength);

flamingo更新日志

2017.05.26

  1. 单聊窗口窗口抖动增加时间间隔限制(5秒);
  2. 窗口抖动改在支线程里面操作,避免因为Sleep导致主界面假死。

2017.05.27
1.服务器端增加配置文件,端口号和数据库账号改为可配置项;
2.服务器端增加异步日志;
3. 协议接口调整,统一在32位机器和64位机器上协议包字节数大小。

2017.06.07

  1. 增加同一个账号以同一个终端登录后会踢掉同一个账号同一个终端前面的登录;
  2. 修正发出去的群聊消息会发给自己导致群聊消息记录重复的bug;
  3. 修正有新用户加群时在该群聊对话框打开时,群成员列表不能实时刷新的bug。

2017.06.14

  1. 新增imgserver,聊天图片和头像图片改走专门的服务器imgserver,与原来的文件服务器分开;
  2. 支持大于4G以上的文件的传输;
  3. 加快客户端获取文件md5速度;
  4. 修正协议接口读取int64类型的实现错误;
  5. 修正直接关闭登录对话框程序崩溃的问题;
  6. 服务器端log日志目录可以自动创建;
  7. 客户端启动时,会自动删除过期日志;
  8. flamingo pc客户端网络设置界面增加设置图片服务器地址和端口号 编辑框;
  9. 修正pc客户端界面修改了服务器地址或端口号不能立即生效的bug。

2017.08.02

  1. 服务器由支持在线和离线两种状态改为支持在线、离线、隐身、忙碌、离开、手机在线等多种状态;
  2. 客户端增加修改在线状态接口(可在在线、隐身、离开、忙碌等状态之间切换),相应的界面暂且没做。

2017.10.24
服务器端更新:

  1. 发包抽象出一个单独的函数;
  2. 修正日志文件名和日志内容中的时间戳不正确的问题;
  3. 去掉无用的捕获SIGKILL信号的捕获指令。
  4. 修正聊天图片上传到文件服务目录下的bug;
  5. 大幅度优化服务器日志显示信息;
  6. 优化文件服务器功能.
    ==================
    客户端更新:
  7. 修正日志中中文乱码的问题;
  8. 修正了反复登录可能会崩溃的问题;
  9. 日志NORMAL信息改成INFO信息;
  10. 日志增加级别控制,在配置文件里面可配置.
  11. 心跳包可以在配置文件中配置启用;
  12. 优化文件上传与下载协议.
  13. 修正过期的log无法删除的bug.
  14. 修正托盘菜单项"关闭所有声音"不起作用的问题
  15. 增加断线重连机制,并在托盘提示正在重连。
  16. 程序标题设置为配置项
  17. 关于对话框标题和内容可以配置
    18.修正群聊窗口字体toolbar在群聊窗口尺寸改变时会遮挡群用户列表的问题。
  18. 新增好友浮动信息框。

2017.11.16

  1. 修正文件服务器因协议调整而出现只能上传418k大小的文件;
  2. 规划客户端好友分组信息。

2018.04.22

  1. 新增flamingo安卓版本
  2. 聊天通讯协议支持压缩和非压缩两种方式
  3. 规划pc版远程桌面功能
  4. 其他bug的修正

2018.08.21

  1. 修正服务端三处崩溃问题;
  2. 配置文件移至当前目录下的etc子目录下,各个配置文件名去掉“my”前缀;
  3. 各个服务名去掉“my”前缀;
  4. 数据库名由“myim”修改为“flamingo”,用户可使用提供的flamingoserver目录下rename_database.shell脚本将旧库数据迁移至新库。
  5. 其他一些优化。

2018.09.17

  1. 增加好友分组功能;
  2. 增加好友备注功能名功能;
  3. 修正其他一些bug。

2019.05.05

  1. 服务器支持 Windows 操作系统编译、调试和部署,可以直接使用 Visual Studio 2019 打开 FlamingoServer.sln 文件即可一键编译到底;
  2. 安卓版本实现了除发送图片以外的所有功能(发送图片功能下一版更新);
  3. 修正安卓版不能接收中文消息的问题;
  4. 服务器端网络库优化。
  5. 修改windows vs项目工程目录,避免与linux下编译生成的二进制文件冲突。

2019.05.22

  1. 修正修改备注成功后输出日志时写错的格式话参数引起的崩溃问题;
  2. 修正调用mysql接口时的内存泄漏问题;
  3. 修正EventLoop定时器接口不正确的问题;
  4. EventLoop定时器接口统一改成微秒;
  5. 同一个进程产生的不同的日志文件名中带有该进程的ID。

2019.06.18

  1. 修正客户端无法自动登陆的问题;
  2. 修正Windows版本服务器初始化时无法创建表的问题;
  3. 修正几处代码中的笔误;
  4. 默认关闭心跳包检测,减少日志输出。

2019.06.24

  1. 向Linux唤醒fd读写数据时改为read和write系统调用。

2019.06.26

  1. 修正无法群发消息的问题(不是群聊发送)。

2019.07.17

  1. 修正Windows平台发送图片和文件可能出错的问题;
  2. 发送图片和文件改成短连接,发送时建立连接,发送完毕关闭连接;
  3. 修正网络库在Windows平台上接收字节数超过1024出错的问题。

2019.10.10

  1. 统一函数大小写;
  2. 部分智能指针从 std::shared_ptr 替换成 std::unique_ptr。

2020.04.01

  1. 通信协议优化;
  2. 修正部分笔误。

chatserver无法运行

你好,我这边fileserve和imgserver都正常,就是chatserver无法运行,没有错误提示;
P.S.数据库表是手动建的,版本:CentOS Linux release 7.5.1804 (Core),gcc version 4.8.5

疑问

Field.cpp里面 m_strValue,m_strFieldName 不都是类的私有变量吗,你这里直接这样写f.m_strValue, f.m_strFieldName是不是有问题。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.