├── .gitattributes
├── .gitignore
├── CMakeLists.txt
├── LICENSE.MD
├── README.MD
├── RetroSpy.SQL
├── RetroSpy.db
├── common
├── CMakeLists.txt
├── Defines.h
├── Helper.cpp
├── Helper.h
├── Helper_Base64.cpp
├── Helper_Query.cpp
├── Helper_Random.cpp
├── TemplateStringServer.cpp
├── TemplateStringServer.h
├── chc_endian.cpp
├── chc_endian.h
├── md5.c
└── md5.h
├── natneg
├── CMakeLists.txt
├── Client.cpp
├── Client.h
├── ClientManager.cpp
├── ClientManager.h
├── NNServer.cpp
├── NNServer.h
└── NNTypes.h
├── peerchat
├── CMakeLists.txt
├── Cache.cpp
├── Cache.h
├── IRCChannel.cpp
├── IRCChannel.h
├── IRCClient.cpp
├── IRCClient.h
├── PeerChatServer.cpp
├── PeerChatServer.h
└── Structs.h
├── playersearch
├── CMakeLists.txt
├── PSServer.cpp
└── PSServer.h
├── playerspy
├── CMakeLists.txt
├── Client.cpp
├── Client.h
├── ClientManager.cpp
├── ClientManager.h
├── PYServer.cpp
├── PYServer.h
└── Types.h
└── queryreport2
├── CMakeLists.txt
├── QR2Server.cpp
└── QR2Server.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 |
19 | # Fortran module files
20 | *.mod
21 | *.smod
22 |
23 | # Compiled Static libraries
24 | *.lai
25 | *.la
26 | *.a
27 | *.lib
28 |
29 | # Executables
30 | *.exe
31 | *.out
32 | *.app
33 |
34 | ## Ignore Visual Studio temporary files, build results, and
35 | ## files generated by popular Visual Studio add-ons.
36 | ##
37 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.userosscache
43 | *.sln.docstates
44 |
45 | # User-specific files (MonoDevelop/Xamarin Studio)
46 | *.userprefs
47 |
48 | # Build results
49 | [Dd]ebug/
50 | [Dd]ebugPublic/
51 | [Rr]elease/
52 | [Rr]eleases/
53 | x64/
54 | x86/
55 | bld/
56 | [Bb]in/
57 | [Oo]bj/
58 | [Ll]og/
59 |
60 | # Visual Studio 2015/2017 cache/options directory
61 | .vs/
62 | # Uncomment if you have tasks that create the project's static files in wwwroot
63 | #wwwroot/
64 |
65 | # Visual Studio 2017 auto generated files
66 | Generated\ Files/
67 |
68 | # MSTest test Results
69 | [Tt]est[Rr]esult*/
70 | [Bb]uild[Ll]og.*
71 |
72 | # NUNIT
73 | *.VisualState.xml
74 | TestResult.xml
75 |
76 | # Build Results of an ATL Project
77 | [Dd]ebugPS/
78 | [Rr]eleasePS/
79 | dlldata.c
80 |
81 | # Benchmark Results
82 | BenchmarkDotNet.Artifacts/
83 |
84 | # .NET Core
85 | project.lock.json
86 | project.fragment.lock.json
87 | artifacts/
88 | **/Properties/launchSettings.json
89 |
90 | # StyleCop
91 | StyleCopReport.xml
92 |
93 | # Files built by Visual Studio
94 | *_i.c
95 | *_p.c
96 | *_i.h
97 | *.ilk
98 | *.meta
99 | *.obj
100 | *.pch
101 | *.pdb
102 | *.pgc
103 | *.pgd
104 | *.rsp
105 | *.sbr
106 | *.tlb
107 | *.tli
108 | *.tlh
109 | *.tmp
110 | *.tmp_proj
111 | *.log
112 | *.vspscc
113 | *.vssscc
114 | .builds
115 | *.pidb
116 | *.svclog
117 | *.scc
118 |
119 | # Chutzpah Test files
120 | _Chutzpah*
121 |
122 | # Visual C++ cache files
123 | ipch/
124 | *.aps
125 | *.ncb
126 | *.opendb
127 | *.opensdf
128 | *.sdf
129 | *.cachefile
130 | *.VC.db
131 | *.VC.VC.opendb
132 |
133 | # Visual Studio profiler
134 | *.psess
135 | *.vsp
136 | *.vspx
137 | *.sap
138 |
139 | # Visual Studio Trace Files
140 | *.e2e
141 |
142 | # TFS 2012 Local Workspace
143 | $tf/
144 |
145 | # Guidance Automation Toolkit
146 | *.gpState
147 |
148 | # ReSharper is a .NET coding add-in
149 | _ReSharper*/
150 | *.[Rr]e[Ss]harper
151 | *.DotSettings.user
152 |
153 | # JustCode is a .NET coding add-in
154 | .JustCode
155 |
156 | # TeamCity is a build add-in
157 | _TeamCity*
158 |
159 | # DotCover is a Code Coverage Tool
160 | *.dotCover
161 |
162 | # AxoCover is a Code Coverage Tool
163 | .axoCover/*
164 | !.axoCover/settings.json
165 |
166 | # Visual Studio code coverage results
167 | *.coverage
168 | *.coveragexml
169 |
170 | # NCrunch
171 | _NCrunch_*
172 | .*crunch*.local.xml
173 | nCrunchTemp_*
174 |
175 | # MightyMoose
176 | *.mm.*
177 | AutoTest.Net/
178 |
179 | # Web workbench (sass)
180 | .sass-cache/
181 |
182 | # Installshield output folder
183 | [Ee]xpress/
184 |
185 | # DocProject is a documentation generator add-in
186 | DocProject/buildhelp/
187 | DocProject/Help/*.HxT
188 | DocProject/Help/*.HxC
189 | DocProject/Help/*.hhc
190 | DocProject/Help/*.hhk
191 | DocProject/Help/*.hhp
192 | DocProject/Help/Html2
193 | DocProject/Help/html
194 |
195 | # Click-Once directory
196 | publish/
197 |
198 | # Publish Web Output
199 | *.[Pp]ublish.xml
200 | *.azurePubxml
201 | # Note: Comment the next line if you want to checkin your web deploy settings,
202 | # but database connection strings (with potential passwords) will be unencrypted
203 | *.pubxml
204 | *.publishproj
205 |
206 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
207 | # checkin your Azure Web App publish settings, but sensitive information contained
208 | # in these scripts will be unencrypted
209 | PublishScripts/
210 |
211 | # NuGet Packages
212 | *.nupkg
213 | # The packages folder can be ignored because of Package Restore
214 | **/[Pp]ackages/*
215 | # except build/, which is used as an MSBuild target.
216 | !**/[Pp]ackages/build/
217 | # Uncomment if necessary however generally it will be regenerated when needed
218 | #!**/[Pp]ackages/repositories.config
219 | # NuGet v3's project.json files produces more ignorable files
220 | *.nuget.props
221 | *.nuget.targets
222 |
223 | # Microsoft Azure Build Output
224 | csx/
225 | *.build.csdef
226 |
227 | # Microsoft Azure Emulator
228 | ecf/
229 | rcf/
230 |
231 | # Windows Store app package directories and files
232 | AppPackages/
233 | BundleArtifacts/
234 | Package.StoreAssociation.xml
235 | _pkginfo.txt
236 | *.appx
237 |
238 | # Visual Studio cache files
239 | # files ending in .cache can be ignored
240 | *.[Cc]ache
241 | # but keep track of directories ending in .cache
242 | !*.[Cc]ache/
243 |
244 | # Others
245 | ClientBin/
246 | ~$*
247 | *~
248 | *.dbmdl
249 | *.dbproj.schemaview
250 | *.jfm
251 | *.pfx
252 | *.publishsettings
253 | orleans.codegen.cs
254 |
255 | # Since there are multiple workflows, uncomment next line to ignore bower_components
256 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
257 | #bower_components/
258 |
259 | # RIA/Silverlight projects
260 | Generated_Code/
261 |
262 | # Backup & report files from converting an old project file
263 | # to a newer Visual Studio version. Backup files are not needed,
264 | # because we have git ;-)
265 | _UpgradeReport_Files/
266 | Backup*/
267 | UpgradeLog*.XML
268 | UpgradeLog*.htm
269 |
270 | # SQL Server files
271 | *.mdf
272 | *.ldf
273 | *.ndf
274 |
275 | # Business Intelligence projects
276 | *.rdl.data
277 | *.bim.layout
278 | *.bim_*.settings
279 |
280 | # Microsoft Fakes
281 | FakesAssemblies/
282 |
283 | # GhostDoc plugin setting file
284 | *.GhostDoc.xml
285 |
286 | # Node.js Tools for Visual Studio
287 | .ntvs_analysis.dat
288 | node_modules/
289 |
290 | # TypeScript v1 declaration files
291 | typings/
292 |
293 | # Visual Studio 6 build log
294 | *.plg
295 |
296 | # Visual Studio 6 workspace options file
297 | *.opt
298 |
299 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
300 | *.vbw
301 |
302 | # Visual Studio LightSwitch build output
303 | **/*.HTMLClient/GeneratedArtifacts
304 | **/*.DesktopClient/GeneratedArtifacts
305 | **/*.DesktopClient/ModelManifest.xml
306 | **/*.Server/GeneratedArtifacts
307 | **/*.Server/ModelManifest.xml
308 | _Pvt_Extensions
309 |
310 | # Paket dependency manager
311 | .paket/paket.exe
312 | paket-files/
313 |
314 | # FAKE - F# Make
315 | .fake/
316 |
317 | # JetBrains Rider
318 | .idea/
319 | *.sln.iml
320 |
321 | # CodeRush
322 | .cr/
323 |
324 | # Python Tools for Visual Studio (PTVS)
325 | __pycache__/
326 | *.pyc
327 |
328 | # Cake - Uncomment if you are using it
329 | # tools/**
330 | # !tools/packages.config
331 |
332 | # Tabs Studio
333 | *.tss
334 |
335 | # Telerik's JustMock configuration file
336 | *.jmconfig
337 |
338 | # BizTalk build output
339 | *.btp.cs
340 | *.btm.cs
341 | *.odx.cs
342 | *.xsd.cs
343 |
344 | # OpenCover UI analysis results
345 | OpenCover/
346 |
347 | # Azure Stream Analytics local run output
348 | ASALocalRun/
349 |
350 | *.idb
351 |
352 | # SQLite database
353 | RetroSpySqlite3.db
354 |
355 | # Vs2008 projects
356 | [Dd]ebug_VS2008
357 | [Rr]elease_VS2008
358 |
359 | # MySQL specific
360 | VERSION.dep
361 | errmsg.sys
362 | libmysql_exports.def
363 | libmysql_dummy.c
364 | api_test.c
365 | sql_state.h
366 | mysqld_error.h
367 | mysqld_errname.h
368 | info_macros.cmake
369 | mysql_version.h
370 | config.h
371 | my_config.h
372 | INFO_SRC
373 | CPackConfig.cmake
374 | CPackSourceConfig.cmake
375 | mysqlclient_depends.c
376 | versioninfo_dll.rc
377 | versioninfo_exe.rc
378 | mysqld_ername.h
379 | INFO_BIN
380 | *-serverlog.txt
381 | *-servertrace.txt
382 | RetroSpy.ini
383 | build_*
384 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.1)
2 | project("RetroSpyServer")
3 |
4 | # Add definitions for w32 build that dosen't support _WIN32 macro
5 | if (WIN32)
6 | add_definitions("-DWIN32 -D__WIN32__ -D_CRT_SECURE_NO_WARNINGS")
7 | endif()
8 |
9 | # Set -fPIC to allow compiling retrospy shared library with libuv
10 | if (NOT WIN32)
11 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
13 | endif()
14 |
15 | # Set CMake output directory
16 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
17 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
18 |
19 | # RetroSpy projects
20 | add_subdirectory("common")
21 | add_subdirectory("playersearch")
22 | add_subdirectory("playerspy")
23 | add_subdirectory("queryreport2")
24 | add_subdirectory("natneg")
25 | add_subdirectory("peerchat")
26 |
--------------------------------------------------------------------------------
/LICENSE.MD:
--------------------------------------------------------------------------------
1 | GNU AFFERO GENERAL PUBLIC LICENSE
2 | Version 3, 19 November 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU Affero General Public License is a free, copyleft license for
11 | software and other kinds of works, specifically designed to ensure
12 | cooperation with the community in the case of network server software.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | our General Public Licenses are intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users.
19 |
20 | When we speak of free software, we are referring to freedom, not
21 | price. Our General Public Licenses are designed to make sure that you
22 | have the freedom to distribute copies of free software (and charge for
23 | them if you wish), that you receive source code or can get it if you
24 | want it, that you can change the software or use pieces of it in new
25 | free programs, and that you know you can do these things.
26 |
27 | Developers that use our General Public Licenses protect your rights
28 | with two steps: (1) assert copyright on the software, and (2) offer
29 | you this License which gives you legal permission to copy, distribute
30 | and/or modify the software.
31 |
32 | A secondary benefit of defending all users' freedom is that
33 | improvements made in alternate versions of the program, if they
34 | receive widespread use, become available for other developers to
35 | incorporate. Many developers of free software are heartened and
36 | encouraged by the resulting cooperation. However, in the case of
37 | software used on network servers, this result may fail to come about.
38 | The GNU General Public License permits making a modified version and
39 | letting the public access it on a server without ever releasing its
40 | source code to the public.
41 |
42 | The GNU Affero General Public License is designed specifically to
43 | ensure that, in such cases, the modified source code becomes available
44 | to the community. It requires the operator of a network server to
45 | provide the source code of the modified version running there to the
46 | users of that server. Therefore, public use of a modified version, on
47 | a publicly accessible server, gives the public access to the source
48 | code of the modified version.
49 |
50 | An older license, called the Affero General Public License and
51 | published by Affero, was designed to accomplish similar goals. This is
52 | a different license, not a version of the Affero GPL, but Affero has
53 | released a new version of the Affero GPL which permits relicensing under
54 | this license.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | TERMS AND CONDITIONS
60 |
61 | 0. Definitions.
62 |
63 | "This License" refers to version 3 of the GNU Affero General Public License.
64 |
65 | "Copyright" also means copyright-like laws that apply to other kinds of
66 | works, such as semiconductor masks.
67 |
68 | "The Program" refers to any copyrightable work licensed under this
69 | License. Each licensee is addressed as "you". "Licensees" and
70 | "recipients" may be individuals or organizations.
71 |
72 | To "modify" a work means to copy from or adapt all or part of the work
73 | in a fashion requiring copyright permission, other than the making of an
74 | exact copy. The resulting work is called a "modified version" of the
75 | earlier work or a work "based on" the earlier work.
76 |
77 | A "covered work" means either the unmodified Program or a work based
78 | on the Program.
79 |
80 | To "propagate" a work means to do anything with it that, without
81 | permission, would make you directly or secondarily liable for
82 | infringement under applicable copyright law, except executing it on a
83 | computer or modifying a private copy. Propagation includes copying,
84 | distribution (with or without modification), making available to the
85 | public, and in some countries other activities as well.
86 |
87 | To "convey" a work means any kind of propagation that enables other
88 | parties to make or receive copies. Mere interaction with a user through
89 | a computer network, with no transfer of a copy, is not conveying.
90 |
91 | An interactive user interface displays "Appropriate Legal Notices"
92 | to the extent that it includes a convenient and prominently visible
93 | feature that (1) displays an appropriate copyright notice, and (2)
94 | tells the user that there is no warranty for the work (except to the
95 | extent that warranties are provided), that licensees may convey the
96 | work under this License, and how to view a copy of this License. If
97 | the interface presents a list of user commands or options, such as a
98 | menu, a prominent item in the list meets this criterion.
99 |
100 | 1. Source Code.
101 |
102 | The "source code" for a work means the preferred form of the work
103 | for making modifications to it. "Object code" means any non-source
104 | form of a work.
105 |
106 | A "Standard Interface" means an interface that either is an official
107 | standard defined by a recognized standards body, or, in the case of
108 | interfaces specified for a particular programming language, one that
109 | is widely used among developers working in that language.
110 |
111 | The "System Libraries" of an executable work include anything, other
112 | than the work as a whole, that (a) is included in the normal form of
113 | packaging a Major Component, but which is not part of that Major
114 | Component, and (b) serves only to enable use of the work with that
115 | Major Component, or to implement a Standard Interface for which an
116 | implementation is available to the public in source code form. A
117 | "Major Component", in this context, means a major essential component
118 | (kernel, window system, and so on) of the specific operating system
119 | (if any) on which the executable work runs, or a compiler used to
120 | produce the work, or an object code interpreter used to run it.
121 |
122 | The "Corresponding Source" for a work in object code form means all
123 | the source code needed to generate, install, and (for an executable
124 | work) run the object code and to modify the work, including scripts to
125 | control those activities. However, it does not include the work's
126 | System Libraries, or general-purpose tools or generally available free
127 | programs which are used unmodified in performing those activities but
128 | which are not part of the work. For example, Corresponding Source
129 | includes interface definition files associated with source files for
130 | the work, and the source code for shared libraries and dynamically
131 | linked subprograms that the work is specifically designed to require,
132 | such as by intimate data communication or control flow between those
133 | subprograms and other parts of the work.
134 |
135 | The Corresponding Source need not include anything that users
136 | can regenerate automatically from other parts of the Corresponding
137 | Source.
138 |
139 | The Corresponding Source for a work in source code form is that
140 | same work.
141 |
142 | 2. Basic Permissions.
143 |
144 | All rights granted under this License are granted for the term of
145 | copyright on the Program, and are irrevocable provided the stated
146 | conditions are met. This License explicitly affirms your unlimited
147 | permission to run the unmodified Program. The output from running a
148 | covered work is covered by this License only if the output, given its
149 | content, constitutes a covered work. This License acknowledges your
150 | rights of fair use or other equivalent, as provided by copyright law.
151 |
152 | You may make, run and propagate covered works that you do not
153 | convey, without conditions so long as your license otherwise remains
154 | in force. You may convey covered works to others for the sole purpose
155 | of having them make modifications exclusively for you, or provide you
156 | with facilities for running those works, provided that you comply with
157 | the terms of this License in conveying all material for which you do
158 | not control copyright. Those thus making or running the covered works
159 | for you must do so exclusively on your behalf, under your direction
160 | and control, on terms that prohibit them from making any copies of
161 | your copyrighted material outside their relationship with you.
162 |
163 | Conveying under any other circumstances is permitted solely under
164 | the conditions stated below. Sublicensing is not allowed; section 10
165 | makes it unnecessary.
166 |
167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
168 |
169 | No covered work shall be deemed part of an effective technological
170 | measure under any applicable law fulfilling obligations under article
171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
172 | similar laws prohibiting or restricting circumvention of such
173 | measures.
174 |
175 | When you convey a covered work, you waive any legal power to forbid
176 | circumvention of technological measures to the extent such circumvention
177 | is effected by exercising rights under this License with respect to
178 | the covered work, and you disclaim any intention to limit operation or
179 | modification of the work as a means of enforcing, against the work's
180 | users, your or third parties' legal rights to forbid circumvention of
181 | technological measures.
182 |
183 | 4. Conveying Verbatim Copies.
184 |
185 | You may convey verbatim copies of the Program's source code as you
186 | receive it, in any medium, provided that you conspicuously and
187 | appropriately publish on each copy an appropriate copyright notice;
188 | keep intact all notices stating that this License and any
189 | non-permissive terms added in accord with section 7 apply to the code;
190 | keep intact all notices of the absence of any warranty; and give all
191 | recipients a copy of this License along with the Program.
192 |
193 | You may charge any price or no price for each copy that you convey,
194 | and you may offer support or warranty protection for a fee.
195 |
196 | 5. Conveying Modified Source Versions.
197 |
198 | You may convey a work based on the Program, or the modifications to
199 | produce it from the Program, in the form of source code under the
200 | terms of section 4, provided that you also meet all of these conditions:
201 |
202 | a) The work must carry prominent notices stating that you modified
203 | it, and giving a relevant date.
204 |
205 | b) The work must carry prominent notices stating that it is
206 | released under this License and any conditions added under section
207 | 7. This requirement modifies the requirement in section 4 to
208 | "keep intact all notices".
209 |
210 | c) You must license the entire work, as a whole, under this
211 | License to anyone who comes into possession of a copy. This
212 | License will therefore apply, along with any applicable section 7
213 | additional terms, to the whole of the work, and all its parts,
214 | regardless of how they are packaged. This License gives no
215 | permission to license the work in any other way, but it does not
216 | invalidate such permission if you have separately received it.
217 |
218 | d) If the work has interactive user interfaces, each must display
219 | Appropriate Legal Notices; however, if the Program has interactive
220 | interfaces that do not display Appropriate Legal Notices, your
221 | work need not make them do so.
222 |
223 | A compilation of a covered work with other separate and independent
224 | works, which are not by their nature extensions of the covered work,
225 | and which are not combined with it such as to form a larger program,
226 | in or on a volume of a storage or distribution medium, is called an
227 | "aggregate" if the compilation and its resulting copyright are not
228 | used to limit the access or legal rights of the compilation's users
229 | beyond what the individual works permit. Inclusion of a covered work
230 | in an aggregate does not cause this License to apply to the other
231 | parts of the aggregate.
232 |
233 | 6. Conveying Non-Source Forms.
234 |
235 | You may convey a covered work in object code form under the terms
236 | of sections 4 and 5, provided that you also convey the
237 | machine-readable Corresponding Source under the terms of this License,
238 | in one of these ways:
239 |
240 | a) Convey the object code in, or embodied in, a physical product
241 | (including a physical distribution medium), accompanied by the
242 | Corresponding Source fixed on a durable physical medium
243 | customarily used for software interchange.
244 |
245 | b) Convey the object code in, or embodied in, a physical product
246 | (including a physical distribution medium), accompanied by a
247 | written offer, valid for at least three years and valid for as
248 | long as you offer spare parts or customer support for that product
249 | model, to give anyone who possesses the object code either (1) a
250 | copy of the Corresponding Source for all the software in the
251 | product that is covered by this License, on a durable physical
252 | medium customarily used for software interchange, for a price no
253 | more than your reasonable cost of physically performing this
254 | conveying of source, or (2) access to copy the
255 | Corresponding Source from a network server at no charge.
256 |
257 | c) Convey individual copies of the object code with a copy of the
258 | written offer to provide the Corresponding Source. This
259 | alternative is allowed only occasionally and noncommercially, and
260 | only if you received the object code with such an offer, in accord
261 | with subsection 6b.
262 |
263 | d) Convey the object code by offering access from a designated
264 | place (gratis or for a charge), and offer equivalent access to the
265 | Corresponding Source in the same way through the same place at no
266 | further charge. You need not require recipients to copy the
267 | Corresponding Source along with the object code. If the place to
268 | copy the object code is a network server, the Corresponding Source
269 | may be on a different server (operated by you or a third party)
270 | that supports equivalent copying facilities, provided you maintain
271 | clear directions next to the object code saying where to find the
272 | Corresponding Source. Regardless of what server hosts the
273 | Corresponding Source, you remain obligated to ensure that it is
274 | available for as long as needed to satisfy these requirements.
275 |
276 | e) Convey the object code using peer-to-peer transmission, provided
277 | you inform other peers where the object code and Corresponding
278 | Source of the work are being offered to the general public at no
279 | charge under subsection 6d.
280 |
281 | A separable portion of the object code, whose source code is excluded
282 | from the Corresponding Source as a System Library, need not be
283 | included in conveying the object code work.
284 |
285 | A "User Product" is either (1) a "consumer product", which means any
286 | tangible personal property which is normally used for personal, family,
287 | or household purposes, or (2) anything designed or sold for incorporation
288 | into a dwelling. In determining whether a product is a consumer product,
289 | doubtful cases shall be resolved in favor of coverage. For a particular
290 | product received by a particular user, "normally used" refers to a
291 | typical or common use of that class of product, regardless of the status
292 | of the particular user or of the way in which the particular user
293 | actually uses, or expects or is expected to use, the product. A product
294 | is a consumer product regardless of whether the product has substantial
295 | commercial, industrial or non-consumer uses, unless such uses represent
296 | the only significant mode of use of the product.
297 |
298 | "Installation Information" for a User Product means any methods,
299 | procedures, authorization keys, or other information required to install
300 | and execute modified versions of a covered work in that User Product from
301 | a modified version of its Corresponding Source. The information must
302 | suffice to ensure that the continued functioning of the modified object
303 | code is in no case prevented or interfered with solely because
304 | modification has been made.
305 |
306 | If you convey an object code work under this section in, or with, or
307 | specifically for use in, a User Product, and the conveying occurs as
308 | part of a transaction in which the right of possession and use of the
309 | User Product is transferred to the recipient in perpetuity or for a
310 | fixed term (regardless of how the transaction is characterized), the
311 | Corresponding Source conveyed under this section must be accompanied
312 | by the Installation Information. But this requirement does not apply
313 | if neither you nor any third party retains the ability to install
314 | modified object code on the User Product (for example, the work has
315 | been installed in ROM).
316 |
317 | The requirement to provide Installation Information does not include a
318 | requirement to continue to provide support service, warranty, or updates
319 | for a work that has been modified or installed by the recipient, or for
320 | the User Product in which it has been modified or installed. Access to a
321 | network may be denied when the modification itself materially and
322 | adversely affects the operation of the network or violates the rules and
323 | protocols for communication across the network.
324 |
325 | Corresponding Source conveyed, and Installation Information provided,
326 | in accord with this section must be in a format that is publicly
327 | documented (and with an implementation available to the public in
328 | source code form), and must require no special password or key for
329 | unpacking, reading or copying.
330 |
331 | 7. Additional Terms.
332 |
333 | "Additional permissions" are terms that supplement the terms of this
334 | License by making exceptions from one or more of its conditions.
335 | Additional permissions that are applicable to the entire Program shall
336 | be treated as though they were included in this License, to the extent
337 | that they are valid under applicable law. If additional permissions
338 | apply only to part of the Program, that part may be used separately
339 | under those permissions, but the entire Program remains governed by
340 | this License without regard to the additional permissions.
341 |
342 | When you convey a copy of a covered work, you may at your option
343 | remove any additional permissions from that copy, or from any part of
344 | it. (Additional permissions may be written to require their own
345 | removal in certain cases when you modify the work.) You may place
346 | additional permissions on material, added by you to a covered work,
347 | for which you have or can give appropriate copyright permission.
348 |
349 | Notwithstanding any other provision of this License, for material you
350 | add to a covered work, you may (if authorized by the copyright holders of
351 | that material) supplement the terms of this License with terms:
352 |
353 | a) Disclaiming warranty or limiting liability differently from the
354 | terms of sections 15 and 16 of this License; or
355 |
356 | b) Requiring preservation of specified reasonable legal notices or
357 | author attributions in that material or in the Appropriate Legal
358 | Notices displayed by works containing it; or
359 |
360 | c) Prohibiting misrepresentation of the origin of that material, or
361 | requiring that modified versions of such material be marked in
362 | reasonable ways as different from the original version; or
363 |
364 | d) Limiting the use for publicity purposes of names of licensors or
365 | authors of the material; or
366 |
367 | e) Declining to grant rights under trademark law for use of some
368 | trade names, trademarks, or service marks; or
369 |
370 | f) Requiring indemnification of licensors and authors of that
371 | material by anyone who conveys the material (or modified versions of
372 | it) with contractual assumptions of liability to the recipient, for
373 | any liability that these contractual assumptions directly impose on
374 | those licensors and authors.
375 |
376 | All other non-permissive additional terms are considered "further
377 | restrictions" within the meaning of section 10. If the Program as you
378 | received it, or any part of it, contains a notice stating that it is
379 | governed by this License along with a term that is a further
380 | restriction, you may remove that term. If a license document contains
381 | a further restriction but permits relicensing or conveying under this
382 | License, you may add to a covered work material governed by the terms
383 | of that license document, provided that the further restriction does
384 | not survive such relicensing or conveying.
385 |
386 | If you add terms to a covered work in accord with this section, you
387 | must place, in the relevant source files, a statement of the
388 | additional terms that apply to those files, or a notice indicating
389 | where to find the applicable terms.
390 |
391 | Additional terms, permissive or non-permissive, may be stated in the
392 | form of a separately written license, or stated as exceptions;
393 | the above requirements apply either way.
394 |
395 | 8. Termination.
396 |
397 | You may not propagate or modify a covered work except as expressly
398 | provided under this License. Any attempt otherwise to propagate or
399 | modify it is void, and will automatically terminate your rights under
400 | this License (including any patent licenses granted under the third
401 | paragraph of section 11).
402 |
403 | However, if you cease all violation of this License, then your
404 | license from a particular copyright holder is reinstated (a)
405 | provisionally, unless and until the copyright holder explicitly and
406 | finally terminates your license, and (b) permanently, if the copyright
407 | holder fails to notify you of the violation by some reasonable means
408 | prior to 60 days after the cessation.
409 |
410 | Moreover, your license from a particular copyright holder is
411 | reinstated permanently if the copyright holder notifies you of the
412 | violation by some reasonable means, this is the first time you have
413 | received notice of violation of this License (for any work) from that
414 | copyright holder, and you cure the violation prior to 30 days after
415 | your receipt of the notice.
416 |
417 | Termination of your rights under this section does not terminate the
418 | licenses of parties who have received copies or rights from you under
419 | this License. If your rights have been terminated and not permanently
420 | reinstated, you do not qualify to receive new licenses for the same
421 | material under section 10.
422 |
423 | 9. Acceptance Not Required for Having Copies.
424 |
425 | You are not required to accept this License in order to receive or
426 | run a copy of the Program. Ancillary propagation of a covered work
427 | occurring solely as a consequence of using peer-to-peer transmission
428 | to receive a copy likewise does not require acceptance. However,
429 | nothing other than this License grants you permission to propagate or
430 | modify any covered work. These actions infringe copyright if you do
431 | not accept this License. Therefore, by modifying or propagating a
432 | covered work, you indicate your acceptance of this License to do so.
433 |
434 | 10. Automatic Licensing of Downstream Recipients.
435 |
436 | Each time you convey a covered work, the recipient automatically
437 | receives a license from the original licensors, to run, modify and
438 | propagate that work, subject to this License. You are not responsible
439 | for enforcing compliance by third parties with this License.
440 |
441 | An "entity transaction" is a transaction transferring control of an
442 | organization, or substantially all assets of one, or subdividing an
443 | organization, or merging organizations. If propagation of a covered
444 | work results from an entity transaction, each party to that
445 | transaction who receives a copy of the work also receives whatever
446 | licenses to the work the party's predecessor in interest had or could
447 | give under the previous paragraph, plus a right to possession of the
448 | Corresponding Source of the work from the predecessor in interest, if
449 | the predecessor has it or can get it with reasonable efforts.
450 |
451 | You may not impose any further restrictions on the exercise of the
452 | rights granted or affirmed under this License. For example, you may
453 | not impose a license fee, royalty, or other charge for exercise of
454 | rights granted under this License, and you may not initiate litigation
455 | (including a cross-claim or counterclaim in a lawsuit) alleging that
456 | any patent claim is infringed by making, using, selling, offering for
457 | sale, or importing the Program or any portion of it.
458 |
459 | 11. Patents.
460 |
461 | A "contributor" is a copyright holder who authorizes use under this
462 | License of the Program or a work on which the Program is based. The
463 | work thus licensed is called the contributor's "contributor version".
464 |
465 | A contributor's "essential patent claims" are all patent claims
466 | owned or controlled by the contributor, whether already acquired or
467 | hereafter acquired, that would be infringed by some manner, permitted
468 | by this License, of making, using, or selling its contributor version,
469 | but do not include claims that would be infringed only as a
470 | consequence of further modification of the contributor version. For
471 | purposes of this definition, "control" includes the right to grant
472 | patent sublicenses in a manner consistent with the requirements of
473 | this License.
474 |
475 | Each contributor grants you a non-exclusive, worldwide, royalty-free
476 | patent license under the contributor's essential patent claims, to
477 | make, use, sell, offer for sale, import and otherwise run, modify and
478 | propagate the contents of its contributor version.
479 |
480 | In the following three paragraphs, a "patent license" is any express
481 | agreement or commitment, however denominated, not to enforce a patent
482 | (such as an express permission to practice a patent or covenant not to
483 | sue for patent infringement). To "grant" such a patent license to a
484 | party means to make such an agreement or commitment not to enforce a
485 | patent against the party.
486 |
487 | If you convey a covered work, knowingly relying on a patent license,
488 | and the Corresponding Source of the work is not available for anyone
489 | to copy, free of charge and under the terms of this License, through a
490 | publicly available network server or other readily accessible means,
491 | then you must either (1) cause the Corresponding Source to be so
492 | available, or (2) arrange to deprive yourself of the benefit of the
493 | patent license for this particular work, or (3) arrange, in a manner
494 | consistent with the requirements of this License, to extend the patent
495 | license to downstream recipients. "Knowingly relying" means you have
496 | actual knowledge that, but for the patent license, your conveying the
497 | covered work in a country, or your recipient's use of the covered work
498 | in a country, would infringe one or more identifiable patents in that
499 | country that you have reason to believe are valid.
500 |
501 | If, pursuant to or in connection with a single transaction or
502 | arrangement, you convey, or propagate by procuring conveyance of, a
503 | covered work, and grant a patent license to some of the parties
504 | receiving the covered work authorizing them to use, propagate, modify
505 | or convey a specific copy of the covered work, then the patent license
506 | you grant is automatically extended to all recipients of the covered
507 | work and works based on it.
508 |
509 | A patent license is "discriminatory" if it does not include within
510 | the scope of its coverage, prohibits the exercise of, or is
511 | conditioned on the non-exercise of one or more of the rights that are
512 | specifically granted under this License. You may not convey a covered
513 | work if you are a party to an arrangement with a third party that is
514 | in the business of distributing software, under which you make payment
515 | to the third party based on the extent of your activity of conveying
516 | the work, and under which the third party grants, to any of the
517 | parties who would receive the covered work from you, a discriminatory
518 | patent license (a) in connection with copies of the covered work
519 | conveyed by you (or copies made from those copies), or (b) primarily
520 | for and in connection with specific products or compilations that
521 | contain the covered work, unless you entered into that arrangement,
522 | or that patent license was granted, prior to 28 March 2007.
523 |
524 | Nothing in this License shall be construed as excluding or limiting
525 | any implied license or other defenses to infringement that may
526 | otherwise be available to you under applicable patent law.
527 |
528 | 12. No Surrender of Others' Freedom.
529 |
530 | If conditions are imposed on you (whether by court order, agreement or
531 | otherwise) that contradict the conditions of this License, they do not
532 | excuse you from the conditions of this License. If you cannot convey a
533 | covered work so as to satisfy simultaneously your obligations under this
534 | License and any other pertinent obligations, then as a consequence you may
535 | not convey it at all. For example, if you agree to terms that obligate you
536 | to collect a royalty for further conveying from those to whom you convey
537 | the Program, the only way you could satisfy both those terms and this
538 | License would be to refrain entirely from conveying the Program.
539 |
540 | 13. Remote Network Interaction; Use with the GNU General Public License.
541 |
542 | Notwithstanding any other provision of this License, if you modify the
543 | Program, your modified version must prominently offer all users
544 | interacting with it remotely through a computer network (if your version
545 | supports such interaction) an opportunity to receive the Corresponding
546 | Source of your version by providing access to the Corresponding Source
547 | from a network server at no charge, through some standard or customary
548 | means of facilitating copying of software. This Corresponding Source
549 | shall include the Corresponding Source for any work covered by version 3
550 | of the GNU General Public License that is incorporated pursuant to the
551 | following paragraph.
552 |
553 | Notwithstanding any other provision of this License, you have
554 | permission to link or combine any covered work with a work licensed
555 | under version 3 of the GNU General Public License into a single
556 | combined work, and to convey the resulting work. The terms of this
557 | License will continue to apply to the part which is the covered work,
558 | but the work with which it is combined will remain governed by version
559 | 3 of the GNU General Public License.
560 |
561 | 14. Revised Versions of this License.
562 |
563 | The Free Software Foundation may publish revised and/or new versions of
564 | the GNU Affero General Public License from time to time. Such new versions
565 | will be similar in spirit to the present version, but may differ in detail to
566 | address new problems or concerns.
567 |
568 | Each version is given a distinguishing version number. If the
569 | Program specifies that a certain numbered version of the GNU Affero General
570 | Public License "or any later version" applies to it, you have the
571 | option of following the terms and conditions either of that numbered
572 | version or of any later version published by the Free Software
573 | Foundation. If the Program does not specify a version number of the
574 | GNU Affero General Public License, you may choose any version ever published
575 | by the Free Software Foundation.
576 |
577 | If the Program specifies that a proxy can decide which future
578 | versions of the GNU Affero General Public License can be used, that proxy's
579 | public statement of acceptance of a version permanently authorizes you
580 | to choose that version for the Program.
581 |
582 | Later license versions may give you additional or different
583 | permissions. However, no additional obligations are imposed on any
584 | author or copyright holder as a result of your choosing to follow a
585 | later version.
586 |
587 | 15. Disclaimer of Warranty.
588 |
589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
597 |
598 | 16. Limitation of Liability.
599 |
600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
608 | SUCH DAMAGES.
609 |
610 | 17. Interpretation of Sections 15 and 16.
611 |
612 | If the disclaimer of warranty and limitation of liability provided
613 | above cannot be given local legal effect according to their terms,
614 | reviewing courts shall apply local law that most closely approximates
615 | an absolute waiver of all civil liability in connection with the
616 | Program, unless a warranty or assumption of liability accompanies a
617 | copy of the Program in return for a fee.
618 |
619 | END OF TERMS AND CONDITIONS
620 |
621 | How to Apply These Terms to Your New Programs
622 |
623 | If you develop a new program, and you want it to be of the greatest
624 | possible use to the public, the best way to achieve this is to make it
625 | free software which everyone can redistribute and change under these terms.
626 |
627 | To do so, attach the following notices to the program. It is safest
628 | to attach them to the start of each source file to most effectively
629 | state the exclusion of warranty; and each file should have at least
630 | the "copyright" line and a pointer to where the full notice is found.
631 |
632 |
633 | Copyright (C)
634 |
635 | This program is free software: you can redistribute it and/or modify
636 | it under the terms of the GNU Affero General Public License as published
637 | by the Free Software Foundation, either version 3 of the License, or
638 | (at your option) any later version.
639 |
640 | This program is distributed in the hope that it will be useful,
641 | but WITHOUT ANY WARRANTY; without even the implied warranty of
642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
643 | GNU Affero General Public License for more details.
644 |
645 | You should have received a copy of the GNU Affero General Public License
646 | along with this program. If not, see .
647 |
648 | Also add information on how to contact you by electronic and paper mail.
649 |
650 | If your software can interact with users remotely through a computer
651 | network, you should also make sure that it provides a way for users to
652 | get its source. For example, if your program is a web application, its
653 | interface could display a "Source" link that leads users to an archive
654 | of the code. There are many ways you could offer source, and different
655 | solutions will be better for different programs; see section 13 for the
656 | specific requirements.
657 |
658 | You should also get your employer (if you work as a programmer) or school,
659 | if any, to sign a "copyright disclaimer" for the program, if necessary.
660 | For more information on this, and how to apply and follow the GNU AGPL, see
661 | .
662 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # RetroSpy Server
2 |
3 | RetroSpy is a GameSpy Project that aims to create GameSpy 2011/2012 services.
4 |
5 | The server is written in C++ and could be considered as the spiritual successor to OpenSpy Core since most of the modules are based from it.
6 |
7 | See the [wiki](https://github.com/GameProgressive/RetroSpyServer/wiki) for more information about compiling and creating a RetroSpy Server.
8 |
9 | ### Cloning submodules
10 | ```
11 | git submodule init
12 | cd libuv-cmake
13 | git submodule init
14 | cd ../mysql-connector-cpp
15 | git submodule init
16 | cd ..
17 | git submodule update --recursive --remote
18 | ```
19 |
20 | ### Special thanks
21 | * [Luigi Auriemma](http://aluigi.altervista.org/papers.htm) for his papers about gamespy that was used as a reference
22 | * [OpenSpy](https://github.com/Masaq-/Openspy-Core) for the architecture and the portions of code of the modules
23 | * [MySQL](https://www.mysql.com/) for their database server and C++ connector used in RetroSpy
24 | * [libUV](http://libuv.org/) for their awesome asyncrous I/O library that is used on the Server
25 |
--------------------------------------------------------------------------------
/RetroSpy.SQL:
--------------------------------------------------------------------------------
1 | -- --------------------------------------------------------
2 | -- Host: 127.0.0.1
3 | -- Versione server: 10.2.14-MariaDB - mariadb.org binary distribution
4 | -- S.O. server: Win64
5 | -- HeidiSQL Versione: 9.5.0.5196
6 | -- --------------------------------------------------------
7 |
8 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
9 | /*!40101 SET NAMES utf8mb4 */;
10 | /*!50503 SET NAMES utf8mb4 */;
11 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
12 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
13 |
14 |
15 | -- Dump della struttura del database retrospy
16 | CREATE DATABASE IF NOT EXISTS `retrospy` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
17 | USE `retrospy`;
18 |
19 | -- Dump della struttura di tabella retrospy.addrequests
20 | CREATE TABLE IF NOT EXISTS `addrequests` (
21 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
22 | `profileid` int(10) unsigned NOT NULL DEFAULT 0,
23 | `targetid` int(11) unsigned NOT NULL DEFAULT 0,
24 | `syncrequested` varchar(255) NOT NULL DEFAULT '',
25 | `reason` varchar(255) NOT NULL DEFAULT '',
26 | PRIMARY KEY (`id`),
27 | UNIQUE KEY `id` (`id`),
28 | KEY `FK_addrequests_profiles` (`profileid`),
29 | KEY `FK_addrequests_profiles_2` (`targetid`),
30 | CONSTRAINT `FK_addrequests_profiles` FOREIGN KEY (`profileid`) REFERENCES `profiles` (`profileid`),
31 | CONSTRAINT `FK_addrequests_profiles_2` FOREIGN KEY (`targetid`) REFERENCES `profiles` (`profileid`)
32 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
33 |
34 | -- Dump dei dati della tabella retrospy.addrequests: ~0 rows (circa)
35 | /*!40000 ALTER TABLE `addrequests` DISABLE KEYS */;
36 | /*!40000 ALTER TABLE `addrequests` ENABLE KEYS */;
37 |
38 | -- Dump della struttura di tabella retrospy.blocked
39 | CREATE TABLE IF NOT EXISTS `blocked` (
40 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
41 | `targetid` int(10) unsigned NOT NULL,
42 | `profileid` int(10) unsigned NOT NULL,
43 | PRIMARY KEY (`id`),
44 | UNIQUE KEY `id` (`id`),
45 | KEY `FK_blocked_profiles` (`profileid`),
46 | KEY `FK_blocked_profiles_2` (`targetid`),
47 | CONSTRAINT `FK_blocked_profiles` FOREIGN KEY (`profileid`) REFERENCES `profiles` (`profileid`),
48 | CONSTRAINT `FK_blocked_profiles_2` FOREIGN KEY (`targetid`) REFERENCES `profiles` (`profileid`)
49 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
50 |
51 | -- Dump dei dati della tabella retrospy.blocked: ~0 rows (circa)
52 | /*!40000 ALTER TABLE `blocked` DISABLE KEYS */;
53 | /*!40000 ALTER TABLE `blocked` ENABLE KEYS */;
54 |
55 | -- Dump della struttura di tabella retrospy.friends
56 | CREATE TABLE IF NOT EXISTS `friends` (
57 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
58 | `profileid` int(10) unsigned NOT NULL DEFAULT 0,
59 | `targetid` int(10) unsigned NOT NULL DEFAULT 0,
60 | PRIMARY KEY (`id`),
61 | UNIQUE KEY `id` (`id`),
62 | KEY `FK_friends_profiles` (`profileid`),
63 | KEY `FK_friends_profiles_2` (`targetid`),
64 | CONSTRAINT `FK_friends_profiles` FOREIGN KEY (`profileid`) REFERENCES `profiles` (`profileid`),
65 | CONSTRAINT `FK_friends_profiles_2` FOREIGN KEY (`targetid`) REFERENCES `profiles` (`profileid`)
66 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
67 |
68 | -- Dump dei dati della tabella retrospy.friends: ~0 rows (circa)
69 | /*!40000 ALTER TABLE `friends` DISABLE KEYS */;
70 | /*!40000 ALTER TABLE `friends` ENABLE KEYS */;
71 |
72 | -- Dump della struttura di tabella retrospy.messages
73 | CREATE TABLE IF NOT EXISTS `messages` (
74 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
75 | `from` int(10) unsigned NOT NULL,
76 | `to` int(10) unsigned NOT NULL,
77 | `date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
78 | `message` varchar(200) NOT NULL,
79 | PRIMARY KEY (`id`),
80 | UNIQUE KEY `id` (`id`),
81 | KEY `FK_messages_profiles` (`from`),
82 | KEY `FK_messages_profiles_2` (`to`),
83 | CONSTRAINT `FK_messages_profiles` FOREIGN KEY (`from`) REFERENCES `profiles` (`profileid`),
84 | CONSTRAINT `FK_messages_profiles_2` FOREIGN KEY (`to`) REFERENCES `profiles` (`profileid`)
85 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
86 |
87 | -- Dump dei dati della tabella retrospy.messages: ~0 rows (circa)
88 | /*!40000 ALTER TABLE `messages` DISABLE KEYS */;
89 | /*!40000 ALTER TABLE `messages` ENABLE KEYS */;
90 |
91 | -- Dump della struttura di tabella retrospy.profiles
92 | CREATE TABLE IF NOT EXISTS `profiles` (
93 | `profileid` int(11) unsigned NOT NULL AUTO_INCREMENT,
94 | `userid` int(11) unsigned NOT NULL DEFAULT 0,
95 | `sesskey` int(11) DEFAULT NULL,
96 | `uniquenick` varchar(20) NOT NULL DEFAULT '''''',
97 | `nick` varchar(30) NOT NULL DEFAULT '''''',
98 | `firstname` varchar(30) NOT NULL DEFAULT '''''',
99 | `lastname` varchar(30) NOT NULL DEFAULT '''''',
100 | `publicmask` int(11) NOT NULL DEFAULT 0,
101 | `deleted` tinyint(1) NOT NULL DEFAULT 0,
102 | `latitude` float NOT NULL DEFAULT 0,
103 | `longitude` float NOT NULL DEFAULT 0,
104 | `aim` varchar(50) DEFAULT '0',
105 | `picture` int(11) DEFAULT 0,
106 | `occupationid` int(11) DEFAULT 0,
107 | `incomeid` int(11) DEFAULT 0,
108 | `industryid` int(11) DEFAULT 0,
109 | `marriedid` int(11) DEFAULT 0,
110 | `childcount` int(11) DEFAULT 0,
111 | `interests1` int(11) DEFAULT 0,
112 | `ownership1` int(11) DEFAULT 0,
113 | `connectiontype` int(11) DEFAULT 0,
114 | `sex` enum('MALE','FEMALE','PAT') DEFAULT 'PAT',
115 | `zipcode` varchar(10) DEFAULT '00000',
116 | `countrycode` varchar(2) DEFAULT '0',
117 | `homepage` varchar(75) DEFAULT '0',
118 | `birthday` int(11) DEFAULT 0,
119 | `birthmonth` int(11) DEFAULT 0,
120 | `birthyear` int(11) DEFAULT 0,
121 | `location` varchar(127) DEFAULT '0',
122 | `icq` int(11) DEFAULT 0,
123 | PRIMARY KEY (`profileid`),
124 | UNIQUE KEY `profileid` (`profileid`),
125 | UNIQUE KEY `uniquenick` (`uniquenick`),
126 | UNIQUE KEY `sesskey` (`sesskey`),
127 | KEY `FK_profiles_users` (`userid`),
128 | CONSTRAINT `FK_profiles_users` FOREIGN KEY (`userid`) REFERENCES `users` (`userid`)
129 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
130 |
131 | -- Dump dei dati della tabella retrospy.profiles: ~2 rows (circa)
132 | /*!40000 ALTER TABLE `profiles` DISABLE KEYS */;
133 | INSERT INTO `profiles` (`profileid`, `userid`, `sesskey`, `uniquenick`, `nick`, `firstname`, `lastname`, `publicmask`, `deleted`, `latitude`, `longitude`, `aim`, `picture`, `occupationid`, `incomeid`, `industryid`, `marriedid`, `childcount`, `interests1`, `ownership1`, `connectiontype`, `sex`, `zipcode`, `countrycode`, `homepage`, `birthday`, `birthmonth`, `birthyear`, `location`, `icq`) VALUES
134 | (2, 1, NULL, 'SpyGuy', 'SpyGuy', 'Spy', 'Guy', 0, 0, 40.7142, -74.0064, 'spyguy@aim.com', 0, 0, 0, 0, 0, 0, 0, 0, 3, 'MALE', '10001', 'US', 'https://www.gamespy.com/', 20, 3, 1980, 'New York', 0),
135 | (3, 1, NULL, 'SpyGuy2', 'SpyGuy2', 'Spy', 'Guy', 0, 0, 40.7142, -74.0064, 'spyguy@aim.com', 0, 0, 0, 0, 0, 0, 0, 0, 3, 'MALE', '10001', 'US', 'https://www.gamespy.com/', 20, 3, 1980, 'New York', 0);
136 | /*!40000 ALTER TABLE `profiles` ENABLE KEYS */;
137 |
138 | -- Dump della struttura di tabella retrospy.users
139 | CREATE TABLE IF NOT EXISTS `users` (
140 | `userid` int(11) unsigned NOT NULL AUTO_INCREMENT,
141 | `email` varchar(50) NOT NULL,
142 | `password` varchar(32) NOT NULL,
143 | `deleted` tinyint(1) NOT NULL DEFAULT 0,
144 | `emailverified` tinyint(1) NOT NULL DEFAULT 0,
145 | PRIMARY KEY (`userid`),
146 | UNIQUE KEY `userid` (`userid`)
147 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
148 |
149 | -- Dump dei dati della tabella retrospy.users: ~0 rows (circa)
150 | /*!40000 ALTER TABLE `users` DISABLE KEYS */;
151 | INSERT INTO `users` (`userid`, `email`, `password`, `deleted`, `emailverified`) VALUES
152 | (1, 'spyguy@gamespy.com', '0000', 0, 1);
153 | /*!40000 ALTER TABLE `users` ENABLE KEYS */;
154 |
155 | /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
156 | /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
157 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
158 |
--------------------------------------------------------------------------------
/RetroSpy.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GameProgressive/RetroSpyServerCXX/f9936f676a31a486cf2c78187c9e6bccb584f7f7/RetroSpy.db
--------------------------------------------------------------------------------
/common/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(SOURCES
2 | ${CMAKE_CURRENT_LIST_DIR}/chc_endian.cpp
3 | ${CMAKE_CURRENT_LIST_DIR}/chc_endian.h
4 | ${CMAKE_CURRENT_LIST_DIR}/Helper.cpp
5 | ${CMAKE_CURRENT_LIST_DIR}/Helper.h
6 | ${CMAKE_CURRENT_LIST_DIR}/Helper_Base64.cpp
7 | ${CMAKE_CURRENT_LIST_DIR}/Helper_Query.cpp
8 | ${CMAKE_CURRENT_LIST_DIR}/Helper_Random.cpp
9 | ${CMAKE_CURRENT_LIST_DIR}/md5.c
10 | ${CMAKE_CURRENT_LIST_DIR}/md5.h
11 | ${CMAKE_CURRENT_LIST_DIR}/TemplateStringServer.cpp
12 | ${CMAKE_CURRENT_LIST_DIR}/TemplateStringServer.h
13 | )
14 |
15 | add_library(RetroSpyCommon STATIC ${SOURCES})
16 | target_link_libraries(RetroSpyCommon MDK)
17 |
18 |
--------------------------------------------------------------------------------
/common/Defines.h:
--------------------------------------------------------------------------------
1 | #ifndef _RETROSPY_DEFINES_HEADER_
2 | #define _RETROSPY_DEFINES_HEADER_
3 |
4 | #include
5 |
6 | typedef enum _GPEnum
7 | {
8 | // Callbacks
9 | ////////////
10 | GP_ERROR = 0,
11 | GP_RECV_BUDDY_REQUEST,
12 | GP_RECV_BUDDY_STATUS,
13 | GP_RECV_BUDDY_MESSAGE,
14 | GP_RECV_BUDDY_UTM,
15 | GP_RECV_GAME_INVITE,
16 | GP_TRANSFER_CALLBACK,
17 | GP_RECV_BUDDY_AUTH,
18 | GP_RECV_BUDDY_REVOKE,
19 |
20 | // Global States.
21 | /////////////////
22 | GP_INFO_CACHING = 0x0100,
23 | GP_SIMULATION,
24 | GP_INFO_CACHING_BUDDY_AND_BLOCK_ONLY,
25 |
26 | // Blocking
27 | ///////////
28 | GP_BLOCKING = 1,
29 | GP_NON_BLOCKING = 0,
30 |
31 | // Firewall
32 | ///////////
33 | GP_FIREWALL = 1,
34 | GP_NO_FIREWALL = 0,
35 |
36 | // Check Cache
37 | //////////////
38 | GP_CHECK_CACHE = 1,
39 | GP_DONT_CHECK_CACHE = 0,
40 |
41 | // Is Valid Email.
42 | // PANTS|02.15.00
43 | //////////////////
44 | GP_VALID = 1,
45 | GP_INVALID = 0,
46 |
47 | // Fatal Error.
48 | ///////////////
49 | GP_FATAL = 1,
50 | GP_NON_FATAL = 0,
51 |
52 | // Sex
53 | //////
54 | GP_MALE = 0x0500,
55 | GP_FEMALE,
56 | GP_PAT,
57 |
58 | // Profile Search.
59 | //////////////////
60 | GP_MORE = 0x0600,
61 | GP_DONE,
62 |
63 | // Set Info
64 | ///////////
65 | GP_NICK = 0x0700,
66 | GP_UNIQUENICK,
67 | GP_EMAIL,
68 | GP_PASSWORD,
69 | GP_FIRSTNAME,
70 | GP_LASTNAME,
71 | GP_ICQUIN,
72 | GP_HOMEPAGE,
73 | GP_ZIPCODE,
74 | GP_COUNTRYCODE,
75 | GP_BIRTHDAY,
76 | GP_SEX,
77 | GP_CPUBRANDID,
78 | GP_CPUSPEED,
79 | GP_MEMORY,
80 | GP_VIDEOCARD1STRING,
81 | GP_VIDEOCARD1RAM,
82 | GP_VIDEOCARD2STRING,
83 | GP_VIDEOCARD2RAM,
84 | GP_CONNECTIONID,
85 | GP_CONNECTIONSPEED,
86 | GP_HASNETWORK,
87 | GP_OSSTRING,
88 | GP_AIMNAME, // PANTS|03.20.01
89 | GP_PIC,
90 | GP_OCCUPATIONID,
91 | GP_INDUSTRYID,
92 | GP_INCOMEID,
93 | GP_MARRIEDID,
94 | GP_CHILDCOUNT,
95 | GP_INTERESTS1,
96 |
97 | // New Profile.
98 | ///////////////
99 | GP_REPLACE = 1,
100 | GP_DONT_REPLACE = 0,
101 |
102 | // Is Connected.
103 | ////////////////
104 | GP_CONNECTED = 1,
105 | GP_NOT_CONNECTED = 0,
106 |
107 | // Public mask.
108 | ///////////////
109 | GP_MASK_NONE = 0x00000000,
110 | GP_MASK_HOMEPAGE = 0x00000001,
111 | GP_MASK_ZIPCODE = 0x00000002,
112 | GP_MASK_COUNTRYCODE = 0x00000004,
113 | GP_MASK_BIRTHDAY = 0x00000008,
114 | GP_MASK_SEX = 0x00000010,
115 | GP_MASK_EMAIL = 0x00000020,
116 | GP_MASK_ALL = 0xFFFFFFFF,
117 |
118 | // Status
119 | /////////
120 | GP_OFFLINE = 0,
121 | GP_ONLINE = 1,
122 | GP_PLAYING = 2,
123 | GP_STAGING = 3,
124 | GP_CHATTING = 4,
125 | GP_AWAY = 5,
126 |
127 | // Session flags
128 | /////////////////
129 | GP_SESS_IS_CLOSED = 0x00000001,
130 | GP_SESS_IS_OPEN = 0x00000002,
131 | GP_SESS_HAS_PASSWORD = 0x00000004,
132 | GP_SESS_IS_BEHIND_NAT = 0x00000008,
133 | GP_SESS_IS_RANKED = 0x000000010,
134 |
135 |
136 | // CPU Brand ID
137 | ///////////////
138 | GP_INTEL = 1,
139 | GP_AMD,
140 | GP_CYRIX,
141 | GP_MOTOROLA,
142 | GP_ALPHA,
143 |
144 | // Connection ID.
145 | /////////////////
146 | GP_MODEM = 1,
147 | GP_ISDN,
148 | GP_CABLEMODEM,
149 | GP_DSL,
150 | GP_SATELLITE,
151 | GP_ETHERNET,
152 | GP_WIRELESS,
153 |
154 | // Transfer callback type.
155 | // *** the transfer is ended when these types are received
156 | //////////////////////////
157 | GP_TRANSFER_SEND_REQUEST = 0x800, // arg->num == numFiles
158 | GP_TRANSFER_ACCEPTED,
159 | GP_TRANSFER_REJECTED, // ***
160 | GP_TRANSFER_NOT_ACCEPTING, // ***
161 | GP_TRANSFER_NO_CONNECTION, // ***
162 | GP_TRANSFER_DONE, // ***
163 | GP_TRANSFER_CANCELLED, // ***
164 | GP_TRANSFER_LOST_CONNECTION, // ***
165 | GP_TRANSFER_ERROR, // ***
166 | GP_TRANSFER_THROTTLE, // arg->num == Bps
167 | GP_FILE_BEGIN,
168 | GP_FILE_PROGRESS, // arg->num == numBytes
169 | GP_FILE_END,
170 | GP_FILE_DIRECTORY,
171 | GP_FILE_SKIP,
172 | GP_FILE_FAILED, // arg->num == error
173 |
174 | // GP_FILE_FAILED error
175 | ///////////////////////
176 | GP_FILE_READ_ERROR = 0x900,
177 | GP_FILE_WRITE_ERROR,
178 | GP_FILE_DATA_ERROR,
179 |
180 | // Transfer Side.
181 | /////////////////
182 | GP_TRANSFER_SENDER = 0xA00,
183 | GP_TRANSFER_RECEIVER,
184 |
185 | // UTM send options.
186 | ////////////////////
187 | GP_DONT_ROUTE = 0xB00, // only send direct
188 |
189 | // Quiet mode flags.
190 | ////////////////////
191 | GP_SILENCE_NONE = 0x00000000,
192 | GP_SILENCE_MESSAGES = 0x00000001,
193 | GP_SILENCE_UTMS = 0x00000002,
194 | GP_SILENCE_LIST = 0x00000004, // includes requests, auths, and revokes
195 | GP_SILENCE_ALL = 0xFFFFFFFF,
196 |
197 | // Flags for checking if newer version of status info is supported
198 | GP_NEW_STATUS_INFO_SUPPORTED = 0xC00,
199 | GP_NEW_STATUS_INFO_NOT_SUPPORTED = 0xC01,
200 |
201 | // Error codes that can occur while creating a new user.
202 | GP_NEWUSER = 512, // 0x200, There was an error creating a new user.
203 | GP_NEWUSER_BAD_NICK = 513, // 0x201, A profile with that nick already exists.
204 | GP_NEWUSER_BAD_PASSWORD = 514, // 0x202, The password does not match the email address.
205 | GP_NEWUSER_UNIQUENICK_INVALID = 515, // 0x203, The uniquenick is invalid.
206 | GP_NEWUSER_UNIQUENICK_INUSE = 516, // 0x204, The uniquenick is already in use.
207 |
208 | // Error codes that can occur while checking whether a user exists.
209 | GP_CHECK = 3584, // 0xE00, There was an error checking the user account.
210 | GP_CHECK_BAD_EMAIL = 3585, // 0xE01, No account exists with the provided e-mail address.
211 | GP_CHECK_BAD_NICK = 3586, // 0xE02, No such profile exists for the provided e-mail address.
212 | GP_CHECK_BAD_PASSWORD = 3587, // 0xE03, The password is incorrect.
213 |
214 | } GPEnum;
215 |
216 | #define GS_REQUEST_LEN 20
217 | #define GS_GAMENAME_LEN 64
218 | #define GP_EMAIL_LEN 51
219 | #define GP_PASSWORD_LEN 31
220 | #define GP_PASSWORDENC_LEN ((((GP_PASSWORD_LEN+2)*4)/3)+1)
221 | #define GP_PARTNERID_LEN sizeof(int)
222 | #define GP_NAMESPACEID_LEN sizeof(int)
223 | #define GP_NICK_LEN 31
224 | #define GP_UNIQUENICK_LEN 21
225 | #define GP_XOR_SEED 0x79707367 // "gspy"
226 | #define GP_STATUS_STRING_LEN 256
227 | #define GP_FIRSTNAME_LEN 31
228 | #define GP_LASTNAME_LEN 31
229 | #define GP_HOMEPAGE_LEN 76
230 | #define GP_ZIPCODE_LEN 11
231 | #define GP_COUNTRYCODE_LEN 3
232 | #define GP_AIMNAME_LEN 51
233 | #define GP_LOGIN_TICKET_LEN 25
234 | #define GP_LOCATION_STRING_LEN 256
235 | #define GS_PARTNER_ID 0
236 | #define GP_SERVERCHALL_LEN 11
237 | #define GP_AUTHTOKEN_LEN 256
238 | #define GP_PARTNERCHALLENGE_LEN 256
239 | #define GP_CLIENTCHALL_LEN 64
240 | #define GP_PLACE_LEN 128
241 |
242 | #define MD5_BUFFER_LEN 33
243 |
244 | typedef struct
245 | {
246 | char nick[GP_NICK_LEN];
247 | char uniquenick[GP_UNIQUENICK_LEN];
248 | char email[GP_EMAIL_LEN];
249 | char firstname[GP_FIRSTNAME_LEN];
250 | char lastname[GP_LASTNAME_LEN];
251 | char homepage[GP_HOMEPAGE_LEN];
252 | int icquin;
253 | char zipcode[GP_ZIPCODE_LEN];
254 | char countrycode[GP_COUNTRYCODE_LEN];
255 | float longitude; // negative is west, positive is east. (0, 0) means unknown.
256 | float latitude; // negative is south, positive is north. (0, 0) means unknown.
257 | char place[GP_PLACE_LEN]; // e.g., "USA|California|Irvine", "South Korea|Seoul", "Turkey"
258 | int birthday;
259 | int birthmonth;
260 | int birthyear;
261 | GPEnum sex;
262 | int publicmask;
263 | char aimname[GP_AIMNAME_LEN];
264 | int pic;
265 | int occupationid;
266 | int industryid;
267 | int incomeid;
268 | int marriedid;
269 | int childcount;
270 | int interests1;
271 | int ownership1;
272 | int conntypeid;
273 | } GPIInfoCache;
274 |
275 | #if _WIN32 && _MSC_VER
276 | #include
277 | #ifdef __cplusplus
278 | #define RetroSpyModuleStart extern "C" { __declspec(dllexport) int MDKModule(void* data) {
279 | #else
280 | #define RetroSpyModuleStart __declspec(dllexport) int MDKModule(void* data) {
281 | #endif
282 | #else
283 | #ifdef __cplusplus
284 | #define RetroSpyModuleStart extern "C" { int MDKModule(void* data) {
285 | #else
286 | #define RetroSpyModuleStart int MDKModule(void* data) {
287 | #endif
288 | #endif
289 | #ifdef __cplusplus
290 | #define RetroSpyModuleEnd Server->Run(); return ERROR_NONE; }}
291 | #else
292 | #define RetroSpyModuleEnd return ERROR_NONE; }
293 | #endif
294 | #endif
295 |
--------------------------------------------------------------------------------
/common/Helper.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | Foobar is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with Foobar. If not, see .
16 | */
17 | #include "Helper.h"
18 |
19 | #include "md5.h"
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | const char cvdallowed[] = "1234567890#"
27 | "_-`()$-=;/[]"
28 | "@+&%"
29 | "abcdefghijklmnopqrstuvwxyz"
30 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
31 |
32 |
33 | void gs_pass_decode(const char *in, char *out)
34 | {
35 | size_t pass_len = strlen(in), out_len = B64DecodeLen(in, 1), i = 0;
36 |
37 | RandSeed(GP_XOR_SEED);
38 | B64Decode(in, out, pass_len, &out_len, 1);
39 |
40 | for (; i < out_len; i++)
41 | out[i] ^= (char)(RandInt(0, 0xFF));
42 |
43 | out[out_len] = '\0';
44 | }
45 |
46 | void gs_pass_decode(std::string& str)
47 | {
48 | size_t pass_len = str.length(), out_len = B64DecodeLen(str.c_str(), 1), i = 0;
49 | char* out = (char*)malloc(out_len + 1);
50 |
51 | RandSeed(GP_XOR_SEED);
52 | B64Decode(str.c_str(), out, pass_len, &out_len, 1);
53 |
54 | for (; i < out_len; i++)
55 | out[i] ^= (char)(RandInt(0, 0xFF));
56 |
57 | out[out_len] = '\0';
58 |
59 | str = out;
60 | }
61 |
62 | bool charValid(char ch)
63 | {
64 | int i = 0;
65 | for (; i < sizeof(cvdallowed); i++)
66 | {
67 | if (cvdallowed[i] == ch)
68 | return true;
69 | }
70 |
71 | return false;
72 | }
73 |
74 | void gs_make_valid(char *name)
75 | {
76 | size_t i = 0;
77 | for (; i < strlen(name); i++)
78 | {
79 | if (!charValid(name[i]))
80 | name[i] = '_';
81 | }
82 | }
83 |
84 | void hash_md5(const char *what, size_t len, char *out)
85 | {
86 | unsigned char md5h[16];
87 | static const char hex[] = "0123456789abcdef";
88 | md5_context md5t;
89 | size_t i = 0;
90 |
91 | md5_starts(&md5t);
92 | md5_update(&md5t, (unsigned char *)what, (int)len);
93 | md5_finish(&md5t, md5h);
94 |
95 | for (i = 0; i < 16; i++) {
96 | *out++ = hex[md5h[i] >> 4];
97 | *out++ = hex[md5h[i] & 15];
98 | }
99 | *out = 0;
100 | }
101 |
102 | void gs_do_proof(char *out, const char *password, const char *token, const char *serverch, const char *clientch)
103 | {
104 | char passmd5[MD5_BUFFER_LEN], buffer[512];
105 | passmd5[0] = buffer[0] = 0;
106 |
107 | /* Hash the decrypted password */
108 | hash_md5(password, strlen(password), passmd5);
109 |
110 | /* Generate the buffer */
111 | snprintf(buffer, sizeof(buffer), "%s%s%s%s%s%s",
112 | passmd5,
113 | " ",
114 | token,
115 | serverch,
116 | clientch,
117 | passmd5);
118 |
119 | /* Hash the buffer */
120 | hash_md5(buffer, strlen(buffer), out);
121 | }
122 |
123 | bool user_to_emailnick(const char *buffer, char *lpEmail, size_t email_size, char *lpNick, size_t nick_size)
124 | {
125 | char *pch = NULL;
126 | size_t buffersize = 0, pos = 0;
127 |
128 | /* Check if the parametras are NULL */
129 | if (buffer == NULL)
130 | return false;
131 | if (lpEmail == NULL)
132 | return false;
133 | if (lpNick == NULL)
134 | return false;
135 |
136 | buffersize = strlen(buffer);
137 |
138 | /* Get @ position*/
139 | pch = (char*)strchr(buffer, '@');
140 |
141 | if (pch == NULL)
142 | return false; /* Dosen't exists */
143 |
144 | pos = pch - buffer;
145 |
146 | if (pos > nick_size)
147 | return false; /* Email readed too big to store into the buffer */
148 |
149 | if ((buffersize - pos) > email_size)
150 | return false; /* Nick readed too big to store into the buffer */
151 |
152 | strncpy(lpNick, buffer, pos);
153 | lpNick[pos] = '\0';
154 | strncpy(lpEmail, &buffer[pos + 1], buffersize-pos-1);
155 | lpEmail[buffersize - pos-1] = '\0';
156 |
157 | return true;
158 | }
159 |
160 | bool is_gs_valid(const char *base)
161 | {
162 | int len = strlen(base);
163 |
164 | if (base[0] != '\\')
165 | return false;
166 |
167 | if (strcmp(&base[len - 7], "\\final\\") != 0)
168 | return false;
169 |
170 | return true;
171 | }
172 |
173 | size_t get_gs_req(const char *base, char *out, size_t max_size)
174 | {
175 | char *pch = NULL;
176 | const char *in = &base[1];
177 | size_t pos = 0;
178 |
179 | pch = (char*)strstr(in, "\\");
180 |
181 | if (pch == NULL)
182 | return -1;
183 |
184 | pos = pch-in;
185 |
186 | if (max_size < pos)
187 | return -1;
188 |
189 | strncpy(out, in, pos);
190 | out[pos] = '\0';
191 |
192 | pos += 1; /* First \\ */
193 |
194 | if (in[pos] == '\\')
195 | return pos + 2; /* Double slash handling */
196 |
197 | return pos + 1;
198 | }
199 |
200 | bool get_gs_data(std::string input, std::string& out, const char* what)
201 | {
202 | char possible[1024];
203 | if (!get_gs_data(input.c_str(), what, possible, 1024))
204 | return false;
205 |
206 | out = possible;
207 | return true;
208 | }
209 |
210 | char* get_gs_data(const char *base, const char *what, char *out, size_t max_size)
211 | {
212 | char *pch = NULL, *bx = NULL;
213 | size_t i2 = 0, i = 0;
214 | bool bfound = false, bRun = true;
215 |
216 | out[0] = '\0';
217 |
218 | while (bRun)
219 | {
220 | char *tmp = NULL;
221 | bx = (char *)&base[i2];
222 |
223 | pch = strchr(bx, '\\');
224 |
225 | if (pch == NULL)
226 | break;
227 |
228 | i = pch - bx;
229 |
230 | tmp = (char*)malloc(i + 1);
231 |
232 | strncpy(tmp, bx, i);
233 | tmp[i] = '\0';
234 |
235 | if (bfound)
236 | {
237 | if (i < max_size)
238 | {
239 | strncpy(out, tmp, i);
240 | out[i] = '\0';
241 |
242 | free(tmp);
243 | }
244 |
245 | bRun = false;
246 | }
247 | else
248 | {
249 | if (strcmp(tmp, what) == 0)
250 | bfound = true;
251 | }
252 |
253 | if (bRun)
254 | {
255 | free(tmp);
256 | i2 += i + 1;
257 | }
258 | }
259 |
260 | return out;
261 | }
262 |
263 | bool match_mask_with_name2(const char *mask, const char *name)
264 | {
265 | const unsigned char *m = (unsigned char *)mask;
266 | const unsigned char *n = (unsigned char *)name;
267 | const unsigned char *ma = NULL;
268 | const unsigned char *na = (unsigned char *)name;
269 |
270 | while(true)
271 | {
272 | if (*m == '*')
273 | {
274 | while (*m == '*') /* collapse.. */
275 | m++;
276 | ma = m;
277 | na = n;
278 | }
279 |
280 | if (!*m)
281 | {
282 | if (!*n)
283 | return false;
284 | if (!ma)
285 | return true;
286 | for (m--; (m > (const unsigned char *)mask) && (*m == '?'); m--);
287 | if (*m == '*')
288 | return false;
289 | m = ma;
290 | n = ++na;
291 | } else
292 | if (!*n)
293 | {
294 | while (*m == '*') /* collapse.. */
295 | m++;
296 | return (*m != 0);
297 | }
298 |
299 | if ((tolower(*m) != tolower(*n)) && !((*m == '_') && (*n == ' ')) && (*m != '?'))
300 | {
301 | if (!ma)
302 | return true;
303 | m = ma;
304 | n = ++na;
305 | } else
306 | {
307 | m++;
308 | n++;
309 | }
310 | }
311 |
312 | return true;
313 | }
314 |
315 | bool match_mask_with_name(const char *mask, const char *name)
316 | {
317 | if (mask[0] == '*' && mask[1] == '!') {
318 | mask += 2;
319 | while (*name != '!' && *name)
320 | name++;
321 | if (!*name)
322 | return true;
323 | name++;
324 | }
325 |
326 | if (mask[0] == '*' && mask[1] == '@') {
327 | mask += 2;
328 | while (*name != '@' && *name)
329 | name++;
330 | if (!*name)
331 | return true;
332 | name++;
333 | }
334 |
335 | return match_mask_with_name2(mask,name);
336 | }
337 |
--------------------------------------------------------------------------------
/common/Helper.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #ifndef RETROSPYCOMMON_HELPER_H
18 | #define RETROSPYCOMMON_HELPER_H
19 |
20 | #include "Defines.h"
21 | #include
22 |
23 | #include
24 |
25 | // Base64
26 | void B64Decode(const char *input, char *output, size_t inlen, size_t * outlen, int encodingType);
27 | void B64Encode(const char *input, char *output, size_t inlen, int encodingType);
28 | size_t B64DecodeLen(const char *input, int encodingType);
29 |
30 | // Random
31 | void RandSeed(unsigned long seed);
32 | int RandInt(int low, int high);
33 |
34 | // Helper
35 | void gs_pass_decode(const char *buf, char *out);
36 | void gs_pass_decode(std::string& string);
37 | void gs_make_valid(char *name);
38 | void gs_do_proof(char *out, const char *password, const char *token, const char *serverch, const char *clientch);
39 | void hash_md5(const char *what, size_t len, char *out);
40 |
41 | // Database
42 | bool GetProfileIDFromNickEmailAndPass(CDatabase* c, const char *nick, const char *email, const char* pass, unsigned int* id);
43 | bool GetProfileIDFromNickEmail(CDatabase* c, const char *nick, const char *email, unsigned int* pid);
44 | void GetUniqueNickFromProfileID(CDatabase* c, unsigned int pid, char *unick, int size);
45 | bool GetProfileIDFromUniqueNick(CDatabase* db, const char *unick, unsigned int* out);
46 | void GetPasswordFromUserID(CDatabase* c, char *out, int out_len, unsigned int id);
47 | unsigned int GetUserIDFromProfileID(CDatabase* db, unsigned int id, unsigned int* out);
48 | int AssignSessionKeyFromProfileID(CDatabase* c, unsigned int id);
49 | void FreeSessionKey(CDatabase* c, unsigned int profileid);
50 | bool GetProfileInfo(CDatabase* c, unsigned int pid, GPIInfoCache *out, unsigned int *id_out);
51 | bool GetProfileIDFromSessKey(CDatabase* db, unsigned int seeskey, unsigned int* out);
52 | bool GetProfileIDFromAuthToken(CDatabase* db, const char* authtoken, unsigned int *out);
53 | bool GetUserIDFromEmail(CDatabase* db, const char* email, unsigned int* id);
54 | int RegisterUser(CDatabase* db, const char* email, const char* nick, const char* pass, unsigned int* userid);
55 |
56 | //String
57 | bool user_to_emailnick(const char *buffer, char *lpEmail, size_t email_size, char *lpNick, size_t nick_size);
58 | bool is_gs_valid(const char *base);
59 | size_t get_gs_req(const char *base, char *out, size_t max_size);
60 | char* get_gs_data(const char *base, const char *what, char *out, size_t max_size);
61 | bool get_gs_data(std::string base, std::string& out, const char* what);
62 |
63 | // Mask
64 | bool match_mask_with_name(const char *mask, const char *name);
65 | bool match_mask_with_name2(const char *mask, const char *name);
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/common/Helper_Base64.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #include "Helper.h"
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #include
24 |
25 | static void QuartToTrip(char *quart, char *trip, size_t inlen)
26 | {
27 | if (inlen >= 2)
28 | trip[0] = (char)(quart[0] << 2 | quart[1] >> 4);
29 | if (inlen >= 3)
30 | trip[1] = (char)((quart[1] & 0x0F) << 4 | quart[2] >> 2);
31 | if (inlen >= 4)
32 | trip[2] = (char)((quart[2] & 0x3) << 6 | quart[3]);
33 | }
34 |
35 | static void TripToQuart(const char *trip, char *quart, size_t inlen)
36 | {
37 | unsigned char triptemp[3];
38 | size_t i;
39 | for (i = 0; i < inlen; i++)
40 | {
41 | triptemp[i] = (unsigned char)trip[i];
42 | }
43 | while (i < 3) //fill the rest with 0
44 | {
45 | triptemp[i] = 0;
46 | i++;
47 | }
48 | quart[0] = (char)(triptemp[0] >> 2);
49 | quart[1] = (char)(((triptemp[0] & 3) << 4) | (triptemp[1] >> 4));
50 | quart[2] = (char)((triptemp[1] & 0x0F) << 2 | (triptemp[2] >> 6));
51 | quart[3] = (char)(triptemp[2] & 0x3F);
52 |
53 | }
54 |
55 | const char defaultEncoding[] = { '+','/','=' };
56 | const char alternateEncoding[] = { '[',']','_' };
57 | const char urlSafeEncodeing[] = { '-','_','=' };
58 |
59 | void B64Decode(const char *input, char *output, size_t inlen, size_t * outlen, int encodingType)
60 | {
61 | const char *encoding = 0;
62 | size_t readpos = 0;
63 | int writepos = 0;
64 | char block[4];
65 |
66 | //int outlen = -1;
67 | //int inlen = (int)strlen(input);
68 |
69 | // 10-31-2004 : Added by Saad Nader
70 | // now supports URL safe encoding
71 | ////////////////////////////////////////////////
72 | switch (encodingType)
73 | {
74 | case 1:
75 | encoding = alternateEncoding;
76 | break;
77 | case 2:
78 | encoding = urlSafeEncodeing;
79 | break;
80 | default: encoding = defaultEncoding;
81 | }
82 |
83 | assert(inlen >= 0);
84 | if (inlen <= 0)
85 | {
86 | if (outlen)
87 | *outlen = 0;
88 | output[0] = '\0';
89 | return;
90 | }
91 |
92 | // Break at end of string or padding character
93 | while (readpos < inlen && input[readpos] != encoding[2])
94 | {
95 | // 'A'-'Z' maps to 0-25
96 | // 'a'-'z' maps to 26-51
97 | // '0'-'9' maps to 52-61
98 | // 62 maps to encoding[0]
99 | // 63 maps to encoding[1]
100 | if (input[readpos] >= '0' && input[readpos] <= '9')
101 | block[readpos % 4] = (char)(input[readpos] - 48 + 52);
102 | else if (input[readpos] >= 'a' && input[readpos] <= 'z')
103 | block[readpos % 4] = (char)(input[readpos] - 71);
104 | else if (input[readpos] >= 'A' && input[readpos] <= 'Z')
105 | block[readpos % 4] = (char)(input[readpos] - 65);
106 | else if (input[readpos] == encoding[0])
107 | block[readpos % 4] = 62;
108 | else if (input[readpos] == encoding[1])
109 | block[readpos % 4] = 63;
110 |
111 | // padding or '\0' characters also mark end of input
112 | else if (input[readpos] == encoding[2])
113 | break;
114 | else if (input[readpos] == '\0')
115 | break;
116 | else
117 | {
118 | // (assert(0)); //bad input data
119 | if (outlen)
120 | *outlen = 0;
121 | output[0] = '\0';
122 | return; //invaid data
123 | }
124 |
125 | // every 4 bytes, convert QuartToTrip into destination
126 | if (readpos % 4 == 3) // zero based, so (3%4) means four bytes, 0-1-2-3
127 | {
128 | QuartToTrip(block, &output[writepos], 4);
129 | writepos += 3;
130 | }
131 | readpos++;
132 | }
133 |
134 | // Convert any leftover characters in block
135 | if ((readpos != 0) && (readpos % 4 != 0))
136 | {
137 | // fill block with pad (required for QuartToTrip)
138 | memset(&block[readpos % 4], encoding[2], (unsigned int)4 - (readpos % 4));
139 | QuartToTrip(block, &output[writepos], readpos % 4);
140 |
141 | // output bytes depend on the number of non-pad input bytes
142 | if (readpos % 4 == 3)
143 | writepos += 2;
144 | else
145 | writepos += 1;
146 | }
147 |
148 | if (outlen)
149 | *outlen = writepos;
150 | }
151 |
152 | void B64Encode(const char *input, char *output, size_t inlen, int encodingType)
153 | {
154 | const char *encoding;
155 | char *holdout = output;
156 | char *lastchar;
157 | size_t todo = inlen;
158 |
159 | // 10-31-2004 : Added by Saad Nader
160 | // now supports URL safe encoding
161 | ////////////////////////////////////////////////
162 | switch (encodingType)
163 | {
164 | case 1:
165 | encoding = alternateEncoding;
166 | break;
167 | case 2:
168 | encoding = urlSafeEncodeing;
169 | break;
170 | default: encoding = defaultEncoding;
171 | }
172 |
173 | //assume interval of 3
174 | while (todo > 0)
175 | {
176 | #ifdef _WIN32
177 | TripToQuart(input, output, min(todo, 3));
178 | #else
179 | TripToQuart(input, output, std::min(todo, 3));
180 | #endif
181 | output += 4;
182 | input += 3;
183 | todo -= 3;
184 | }
185 | lastchar = output;
186 | if (inlen % 3 == 1)
187 | lastchar -= 2;
188 | else if (inlen % 3 == 2)
189 | lastchar -= 1;
190 | *output = 0; //null terminate!
191 | while (output > holdout)
192 | {
193 | output--;
194 | if (output >= lastchar) //pad the end
195 | *output = encoding[2];
196 | else if (*output <= 25)
197 | *output = (char)(*output + 65);
198 | else if (*output <= 51)
199 | *output = (char)(*output + 71);
200 | else if (*output <= 61)
201 | *output = (char)(*output + 48 - 52);
202 | else if (*output == 62)
203 | *output = encoding[0];
204 | else if (*output == 63)
205 | *output = encoding[1];
206 | }
207 | }
208 |
209 | size_t B64DecodeLen(const char *input, int encodingType)
210 | {
211 | const char *encoding;
212 | const char *holdin = input;
213 |
214 | switch (encodingType)
215 | {
216 | case 1:
217 | encoding = alternateEncoding;
218 | break;
219 | case 2:
220 | encoding = urlSafeEncodeing;
221 | break;
222 | default: encoding = defaultEncoding;
223 | }
224 |
225 | while (*input)
226 | {
227 | if (*input == encoding[2])
228 | return (input - holdin) / 4 * 3 + (input - holdin - 1) % 4;
229 | input++;
230 | }
231 |
232 | return (input - holdin) / 4 * 3;
233 | }
234 |
--------------------------------------------------------------------------------
/common/Helper_Query.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | Foobar is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with Foobar. If not, see .
16 | */
17 | #include "Helper.h"
18 |
19 | #include
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | bool ExecuteFirstQuery(CDatabase* db, CResultSet *res, std::string query)
26 | {
27 | if (!res->ExecuteQuery(db, query))
28 | return false;
29 |
30 | if (!res->GotoFirstRow())
31 | return false;
32 |
33 | return true;
34 | }
35 |
36 | bool GetProfileIDFromNickEmail(CDatabase* db, const char *nick, const char *email, unsigned int* pid)
37 | {
38 | std::string query = "";
39 | std::string _email = email, _nick = nick;
40 | CResultSet *res = NULL;
41 |
42 | query = "SELECT profiles.profileid FROM profiles INNER JOIN"
43 | " users ON profiles.userid=users.userid WHERE"
44 | " users.email='";
45 | if (!mdk_escape_query_string(db, _email))
46 | return false;
47 | query += _email;
48 | query += "' AND profiles.nick='";
49 | if (!mdk_escape_query_string(db, _nick))
50 | return false;
51 | query += _nick;
52 | query += "'";
53 |
54 | res = new CResultSet();
55 | if (!ExecuteFirstQuery(db, res, query))
56 | {
57 | delete res;
58 | return false;
59 | }
60 |
61 | *pid = res->GetUIntFromRow(0);
62 |
63 | delete res;
64 | return true;
65 | }
66 |
67 | bool GetProfileIDFromNickEmailAndPass(CDatabase* c, const char *nick, const char *email, const char* pass, unsigned int* id)
68 | {
69 | std::string query = "";
70 | std::string _email = email, _nick = nick, _pass = pass;
71 | CResultSet* res = NULL;
72 |
73 | query = "SELECT profiles.profileid FROM profiles INNER JOIN"
74 | " users ON profiles.userid=users.userid WHERE"
75 | " users.email='";
76 |
77 | if (!mdk_escape_query_string(c, _email))
78 | return false;
79 |
80 | query += _email;
81 | query += "' AND profiles.nick='";
82 |
83 | if (!mdk_escape_query_string(c, _nick))
84 | return false;
85 |
86 | query += _nick;
87 | query += "' AND users.password='";
88 |
89 | if (!mdk_escape_query_string(c, _pass))
90 | return false;
91 |
92 | query += "'";
93 |
94 | res = new CResultSet();
95 |
96 | if (!ExecuteFirstQuery(c, res, query))
97 | {
98 | delete res;
99 | return false;
100 | }
101 |
102 | *id = res->GetUIntFromRow(0);
103 |
104 | delete res;
105 | return true;
106 | }
107 |
108 | bool GetUserIDFromEmail(CDatabase* db, const char* email, unsigned int* id)
109 | {
110 | std::string _email = email, query = "";
111 | CResultSet* res = NULL;
112 |
113 | if (!mdk_escape_query_string(db, _email))
114 | return false;
115 |
116 | query = "SELECT userid FROM users WHERE email='";
117 | query += _email;
118 | query += "'";
119 |
120 | res = new CResultSet();
121 | if (!ExecuteFirstQuery(db, res, query))
122 | {
123 | delete res;
124 | return false;
125 | }
126 |
127 | *id = res->GetUIntFromRow(0);
128 |
129 | delete res;
130 | return true;
131 | }
132 |
133 | void GetUniqueNickFromProfileID(CDatabase* db, unsigned int pid, char *unick, int size)
134 | {
135 | std::string query = "";
136 | CResultSet *res = new CResultSet();
137 |
138 | query = "SELECT uniquenick FROM profiles WHERE profileid='";
139 | query += std::to_string(pid);
140 | query += "'";
141 |
142 | if (!ExecuteFirstQuery(db, res, query))
143 | {
144 | delete res;
145 | return;
146 | }
147 |
148 | strncpy(unick, res->GetStringFromRow(0).c_str(), size);
149 | unick[size - 1] = '\0';
150 |
151 | delete res;
152 | }
153 |
154 | bool GetProfileIDFromUniqueNick(CDatabase* db, const char *unick, unsigned int* out)
155 | {
156 | std::string query = "", _unick = unick;
157 | CResultSet *res = new CResultSet();
158 |
159 | query = "SELECT profileid FROM profiles WHERE uniquenick='";
160 | if (!mdk_escape_query_string(db, _unick))
161 | {
162 | delete res;
163 | return false;
164 | }
165 | query += _unick;
166 | query += "'";
167 |
168 | if (!ExecuteFirstQuery(db, res, query))
169 | {
170 | delete res;
171 | return false;
172 | }
173 |
174 | *out = res->GetUIntFromRow(0);
175 |
176 | delete res;
177 | return true;
178 | }
179 |
180 | void GetPasswordFromUserID(CDatabase* db, char *out, int out_len, unsigned int id)
181 | {
182 | CResultSet *res = new CResultSet();
183 | char query[61];
184 | query[0] = 0;
185 |
186 | snprintf(query, sizeof(query), "SELECT password FROM users WHERE userid='%u'", id);
187 |
188 | if (!ExecuteFirstQuery(db, res, query))
189 | {
190 | delete res;
191 | return;
192 | }
193 |
194 | strncpy(out, res->GetStringFromRow(0).c_str(), out_len);
195 | out[out_len - 1] = '\0';
196 |
197 | delete res;
198 | }
199 |
200 | unsigned int GetUserIDFromProfileID(CDatabase* db, unsigned int id, unsigned int* out)
201 | {
202 | CResultSet *res = new CResultSet();
203 | char query[61];
204 | unsigned int ret = 0;
205 | query[0] = 0;
206 |
207 | snprintf(query, sizeof(query), "SELECT userid FROM profiles WHERE profileid='%u'", id);
208 |
209 | if (!ExecuteFirstQuery(db, res, query))
210 | {
211 | delete res;
212 | return false;
213 | }
214 |
215 | ret = res->GetUIntFromRow(0);
216 | *out = ret;
217 |
218 | delete res;
219 | return true;
220 | }
221 |
222 | int AssignSessionKeyFromProfileID(CDatabase* db, unsigned int profileid)
223 | {
224 | int ssk = 0;
225 | bool bx = true;
226 | char query[61];
227 | query[0] = 0;
228 |
229 | while (bx)
230 | {
231 | ssk = RandInt(1, INT_MAX);
232 | snprintf(query, sizeof(query), "UPDATE profiles SET sesskey=%d WHERE profileid='%u'", ssk, profileid);
233 |
234 | if (mdk_only_run_query(db, query))
235 | bx = false;
236 | }
237 |
238 | return ssk;
239 | }
240 |
241 | void FreeSessionKey(CDatabase* db, unsigned int profileid)
242 | {
243 | char query[61];
244 | query[0] = 0;
245 |
246 | snprintf(query, sizeof(query), "UPDATE profiles SET sesskey=NULL WHERE profileid='%u'", profileid);
247 |
248 | mdk_only_run_query(db, query);
249 | }
250 |
251 | int GetPublicMaskFromProfileID(CDatabase* db, unsigned int pid)
252 | {
253 | CResultSet *res = new CResultSet();
254 | std::string query = "";
255 | int ret = 0;
256 |
257 | query = "SELECT publicmask FROM profiles WHERE profileid=";
258 | query += std::to_string(pid);
259 |
260 | if (!ExecuteFirstQuery(db, res, query))
261 | {
262 | delete res;
263 | return ret;
264 | }
265 |
266 | ret = res->GetIntFromRow(0);
267 |
268 | delete res;
269 | return ret;
270 | }
271 |
272 | bool GetProfileInfo(CDatabase* db, unsigned int pid, GPIInfoCache *out, unsigned int *id_out)
273 | {
274 | #define resget(x) res->GetStringFromRow(x).c_str()
275 |
276 | CResultSet *res = new CResultSet();
277 | std::string query = "";
278 |
279 | query = "SELECT profiles.uniquenick, profiles.nick, profiles.firstname, profiles.lastname, profiles.latitude," //5
280 | " profiles.longitude, profiles.publicmask, profiles.userid, profiles.aim, profiles.picture," //9
281 | " profiles.occupationid, profiles.incomeid, profiles.industryid, profiles.marriedid, profiles.childcount," //14
282 | " profiles.interests1, profiles.ownership1, profiles.connectiontype, profiles.sex, profiles.zipcode," //19
283 | " profiles.countrycode, profiles.homepage, profiles.birthday, profiles.birthmonth, profiles.birthyear," //24
284 | " profiles.location, profiles.icq, users.email FROM profiles INNER JOIN users ON users.userid=profiles.userid WHERE profiles.profileid=";
285 |
286 | query += std::to_string(pid);
287 |
288 | if (!ExecuteFirstQuery(db, res, query))
289 | {
290 | delete res;
291 | return false;
292 | }
293 |
294 | strncpy(out->uniquenick, resget(0), sizeof(out->uniquenick));
295 | out->uniquenick[sizeof(out->uniquenick) - 1] = '\0';
296 | strncpy(out->nick, resget(1), sizeof(out->nick));
297 | out->nick[sizeof(out->nick) - 1] = '\0';
298 | strncpy(out->firstname, resget(2), sizeof(out->firstname));
299 | out->firstname[sizeof(out->firstname) - 1] = '\0';
300 | strncpy(out->lastname, resget(3), sizeof(out->lastname));
301 | out->lastname[sizeof(out->lastname) - 1] = '\0';
302 | out->latitude = (float)res->GetDoubleFromRow(4);
303 | out->longitude = (float)res->GetDoubleFromRow(5);
304 | out->publicmask = res->GetIntFromRow(6);
305 | *id_out = res->GetUIntFromRow(7);
306 | strncpy(out->aimname, resget(8), sizeof(out->aimname));
307 | out->aimname[sizeof(out->aimname) - 1] = '\0';
308 | out->pic = res->GetIntFromRow(9);
309 | out->occupationid = res->GetIntFromRow(10);
310 | out->incomeid = res->GetIntFromRow(11);
311 | out->industryid = res->GetIntFromRow(12);
312 | out->marriedid = res->GetIntFromRow(13);
313 | out->childcount = res->GetIntFromRow(14);
314 | out->interests1 = res->GetIntFromRow(15);
315 | out->ownership1 = res->GetIntFromRow(16);
316 | out->conntypeid = res->GetIntFromRow(17);
317 |
318 | if (res->GetStringFromRow(18).compare("MALE") == 0)
319 | out->sex = GP_MALE;
320 | else if (res->GetStringFromRow(18).compare("FEMALE") == 0)
321 | out->sex = GP_FEMALE;
322 | else
323 | out->sex = GP_PAT;
324 |
325 | strncpy(out->zipcode, resget(19), sizeof(out->zipcode));
326 | out->zipcode[sizeof(out->zipcode) - 1] = '\0';
327 | strncpy(out->countrycode, resget(20), sizeof(out->countrycode));
328 | out->countrycode[sizeof(out->countrycode) - 1] = '\0';
329 | strncpy(out->homepage, resget(21), sizeof(out->homepage));
330 | out->homepage[sizeof(out->homepage) - 1] = '\0';
331 | out->birthday = res->GetIntFromRow(22);
332 | out->birthmonth = res->GetIntFromRow(23);
333 | out->birthyear = res->GetIntFromRow(24);
334 | strncpy(out->place, resget(25), sizeof(out->place));
335 | out->place[sizeof(out->place) - 1] = '\0';
336 | out->icquin = res->GetIntFromRow(26);
337 | strncpy(out->email, resget(27), sizeof(out->email));
338 | out->email[sizeof(out->email) - 1] = '\0';
339 |
340 | delete res;
341 |
342 | return true;
343 | }
344 |
345 | bool GetProfileIDFromAuthToken(CDatabase* db, const char *authtoken, unsigned int* out)
346 | {
347 | std::string query = "";
348 | std::string _authtoken = authtoken;
349 | CResultSet *res = NULL;
350 |
351 | if (!mdk_escape_query_string(db, _authtoken))
352 | return false;
353 |
354 | res = new CResultSet();
355 |
356 | query = "SELECT profileid FROM authtoken WHERE token='";
357 | query += _authtoken;
358 | query += "'";
359 |
360 | if (!ExecuteFirstQuery(db, res, query))
361 | {
362 | delete res;
363 | return false;
364 | }
365 |
366 | *out = res->GetUIntFromRow(0);
367 |
368 | delete res;
369 | return true;
370 | }
371 |
372 | int RegisterUser(CDatabase* db, const char* email, const char* nick, const char* pass, unsigned int* userid)
373 | {
374 | std::string query = "", _email = email, _nick = nick, _pass = pass;
375 | CResultSet* res = NULL;
376 |
377 | if (!mdk_escape_query_string(db, _email))
378 | return false;
379 |
380 | if (!mdk_escape_query_string(db, _nick))
381 | return false;
382 |
383 | if (!mdk_escape_query_string(db, _pass))
384 | return false;
385 |
386 | query = "SELECT uniquenick FROM profiles WHERE uniquenick='";
387 | query += _nick;
388 | query += "'";
389 |
390 | res = new CResultSet();
391 |
392 | if (!res->ExecuteQuery(db, query.c_str()))
393 | {
394 | delete res;
395 | return GP_NEWUSER;
396 | }
397 |
398 | if (res->GetTotalRows() > 0)
399 | {
400 | delete res;
401 | return GP_NEWUSER_UNIQUENICK_INUSE;
402 | }
403 |
404 | query = "SELECT email FROM users WHERE email='";
405 | query += _email;
406 | query += "'";
407 |
408 | if (!res->ExecuteQuery(db, query.c_str()))
409 | {
410 | delete res;
411 | return GP_NEWUSER;
412 | }
413 |
414 | if (res->GetTotalRows() > 0)
415 | {
416 | delete res;
417 | return GP_NEWUSER;
418 | }
419 |
420 | query = "INSERT INTO users(email, password, deleted, emailverified) VALUES ('";
421 | query += _email;
422 | query += "', '";
423 | query += _pass;
424 | query += "', 0, 1)";
425 |
426 | if (!mdk_only_run_query(db, query))
427 | {
428 | delete res;
429 | return GP_NEWUSER;
430 | }
431 |
432 | query = "SELECT userid FROM users WHERE email='";
433 | query += _email;
434 | query += "'";
435 |
436 | if (!ExecuteFirstQuery(db, res, query))
437 | {
438 | delete res;
439 | return GP_NEWUSER;
440 | }
441 |
442 | query = "INSERT INTO profiles(userid, uniquenick, nick) VALUES (";
443 | query += std::to_string(res->GetUIntFromRow(0));
444 | query += ", '";
445 | query += _nick;
446 | query += "', '";
447 | query += _nick;
448 | query += "')";
449 |
450 | if (!mdk_only_run_query(db, query))
451 | {
452 | delete res;
453 | return GP_NEWUSER;
454 | }
455 |
456 | query = "SELECT profileid FROM profiles WHERE uniquenick='";
457 | query += _nick;
458 | query += "'";
459 |
460 | if (!ExecuteFirstQuery(db, res, query))
461 | {
462 | delete res;
463 | return GP_NEWUSER;
464 | }
465 |
466 | *userid = res->GetUIntFromRow(0);
467 |
468 | delete res;
469 | return -1;
470 | }
--------------------------------------------------------------------------------
/common/Helper_Random.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2009 Luigi Auriemma
3 |
4 | This program is free software; you can redistribute it and/or modify
5 | it under the terms of the GNU General Public License as published by
6 | the Free Software Foundation; either version 2 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU General Public License for more details.
13 |
14 | You should have received a copy of the GNU General Public License
15 | along with this program; if not, write to the Free Software
16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 |
18 | http://www.gnu.org/licenses/gpl-2.0.txt
19 | */
20 | #include "Helper.h"
21 |
22 | // Cross platform random number generator
23 | #define RANa 16807 // multiplier
24 | #define LONGRAND_MAX 2147483647L // 2**31 - 1
25 |
26 | static long randomnum = 1;
27 |
28 | static long nextlongrand(long seed)
29 | {
30 | unsigned long lo, hi;
31 | lo = RANa * (unsigned long)(seed & 0xFFFF);
32 | hi = RANa * ((unsigned long)seed >> 16);
33 | lo += (hi & 0x7FFF) << 16;
34 |
35 | if (lo > LONGRAND_MAX)
36 | {
37 | lo &= LONGRAND_MAX;
38 | ++lo;
39 | }
40 | lo += hi >> 15;
41 |
42 | if (lo > LONGRAND_MAX)
43 | {
44 | lo &= LONGRAND_MAX;
45 | ++lo;
46 | }
47 |
48 | return(long)lo;
49 | }
50 |
51 | // return next random long
52 | static long longrand(void)
53 | {
54 | randomnum = nextlongrand(randomnum);
55 | return randomnum;
56 | }
57 |
58 | // to seed it
59 | void RandSeed(unsigned long seed)
60 | {
61 | // nonzero seed
62 | randomnum = seed ? (long)(seed & LONGRAND_MAX) : 1;
63 | }
64 |
65 | int RandInt(int low, int high)
66 | {
67 | unsigned int range = (unsigned int)high - low;
68 | int num;
69 |
70 | if (range == 0)
71 | return (low); // Prevent divide by zero
72 |
73 | num = (int)(longrand() % range);
74 |
75 | return(num + low);
76 | }
77 |
--------------------------------------------------------------------------------
/common/TemplateStringServer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | Foobar is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with Foobar. If not, see .
16 | */
17 | #include "TemplateStringServer.h"
18 |
19 | #include "Helper.h"
20 |
21 | #include
22 |
23 | CTemplateStringServer::CTemplateStringServer(int defaultport, bool udp) : CThreadServer(defaultport, udp) {}
24 | CTemplateStringServer::~CTemplateStringServer() {}
25 |
26 | void CTemplateStringServer::OnTCPRead(mdk_socket stream, const char *data, ssize_t size)
27 | {
28 | bool bC = true;
29 | char *buffer2 = NULL;
30 |
31 | if (size < 8)
32 | return;
33 |
34 | buffer2 = (char*)malloc(sizeof(char)*(size+1));
35 | strncpy(buffer2, data, size);
36 | buffer2[size] = 0;
37 |
38 | /* Check if the buffer is valid */
39 | if (!is_gs_valid(buffer2))
40 | return;
41 |
42 | /* Loop to handle multiple request in the same buffer (it happends somehow) */
43 | while (bC)
44 | {
45 | char *find_str = NULL;
46 | char *the_string = NULL;
47 |
48 | size_t pos = 0;
49 |
50 | /* Check if the buffer is NULL */
51 | if (buffer2[0] == '\0')
52 | bC = false;
53 | else
54 | {
55 | /* Find the last part of a buffer */
56 | find_str = strstr(buffer2, "final\\");
57 |
58 | if (find_str == NULL)
59 | bC = false; /* Invalid request */
60 | else
61 | {
62 | char type[128];
63 |
64 | type[0] = 0;
65 |
66 | size_t rq_pos = 0;
67 |
68 | pos = find_str - buffer2;
69 |
70 | /* Allocate the string where we take the part our buffer */
71 | the_string = (char *)malloc(sizeof(char) * (pos+1));
72 |
73 | /* Copy the request into the string */
74 | strncpy(the_string, buffer2, pos);
75 | the_string[pos] = '\0';
76 |
77 | /* Get the first request "x//" */
78 | rq_pos = get_gs_req(the_string, type, sizeof(type));
79 | if (rq_pos == -1)
80 | {
81 | /* Invalid request */
82 | Close(stream);
83 | bC = false;
84 | }
85 | else
86 | {
87 | /* Send it to the master handler */
88 | if (!HandleRequest(stream, type, &the_string[rq_pos], pos - rq_pos))
89 | {
90 | /* It wanted to close the socket, ok */
91 | Close(stream);
92 | bC = false;
93 | }
94 | }
95 |
96 |
97 | free(the_string); /* Free allocated memory */
98 | }
99 |
100 | /* If we can continue, continue to control the buffer */
101 | if (bC)
102 | buffer2 = &buffer2[pos + 6];
103 | }
104 | }
105 | }
106 |
107 | // Virtual functions
108 | bool CTemplateStringServer::OnTCPNewConnection(mdk_socket, int) { return true; }
109 | bool CTemplateStringServer::HandleRequest(mdk_socket, const char *, const char *, int) { return true; }
110 |
--------------------------------------------------------------------------------
/common/TemplateStringServer.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | Foobar is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with Foobar. If not, see .
16 | */
17 | #ifndef RETROSPYCOMMON_STRINGSERVER_H
18 | #define RETROSPYCOMMON_STRINGSERVER_H
19 |
20 | #include
21 |
22 | /*
23 | This class is a Server that handle generic
24 | string packets (like GPSP requests)
25 | */
26 | class CTemplateStringServer : public CThreadServer
27 | {
28 | public:
29 | CTemplateStringServer(int defaultport, bool udp);
30 | ~CTemplateStringServer();
31 |
32 | /* See CServer::OnRead */
33 | void OnTCPRead(mdk_socket stream, const char *data, ssize_t size);
34 | void OnUDPRead(mdk_socket stream, const struct sockaddr* addr, const char*data, ssize_t size) {}
35 |
36 | /* See CServer::OnNewConnection */
37 | virtual bool OnTCPNewConnection(mdk_socket stream, int status) = 0;
38 |
39 | /*
40 | Function: HandleRequest
41 | Description: Called when a request is received
42 | Return: true if you want to keep the connection, otherwise false
43 | Parameters:
44 | stream => A pointer to the client
45 | req => The request
46 | buf => The content of the request
47 | size => The length of the content
48 | */
49 | virtual bool HandleRequest(mdk_socket stream, const char *req, const char *buf, int size);
50 | };
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/common/chc_endian.cpp:
--------------------------------------------------------------------------------
1 | /* chc_endian by Andrew "CHCNiZ" Learn
2 | * Copyright (C) 2009 Andrew Learn
3 | *
4 | * chc_endian is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * chc_endian is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with chc_endian. If not, see .
16 | */
17 | #include "chc_endian.h"
18 |
19 | //now obviously madness like this isn't used often(who would need invert_bytes for example) a lot of its just for fun and no cpu i've heard of uses such a byte order, but its still included into this header
20 | uint32_t little_to_middle(uint32_t x) { //0xABCDEF02 becomes 0xCDAB02EF this is used for converting from middle endian(ARM CPU's/PDP-11) to little endian
21 | return x<<8&0xff000000|x>>8&0xff0000|(x&0x0000ff00)>>8|(x&0x000000ff)<<8;
22 | }
23 |
24 | uint32_t reverse_endian32(uint32_t x) { //little to big or vice versa
25 | return (x<<24|(x<<8&0x00ff0000)|x>>8&0x0000ff00|x>>24&0x000000ff);
26 | }
27 |
28 | uint32_t invert_bytes(uint32_t x) { //0xABCDEF02 becomes 0xBADCFE20
29 | return ((x&0x0f000000)<<4|(x&0xf0000000)>>4|(x&0x00f00000)>>4|(x&0x000f0000)<<4|(x&0x0000f000)>>4|(x&0x00000f00)<<4|(x&0x000000f0)>>4|(x&0x0000000f)<<4);
30 | }
31 |
32 | uint32_t rev_bendian32(uint32_t x) { //0xABCDEF02 becomes 0x20FEDCAB
33 | return ((x&0x0f0000)<<4|(x&0xf00000)>>4)>>8|((x&0x0f)<<4|(x&0xf0)>>4)<<24|((x&0x0f00)<<4|(x&0xf000)>>4)<<8|((x&0x0f000000)<<4|(x&0xf0000000)>>4)>>24;
34 | }
35 |
36 | uint16_t reverse_endian16(uint16_t x) { //little to big or vice versa
37 | return (x&0xff00)>>8|(x&0x00ff)<<8;
38 | }
39 |
40 | uint16_t invert_inner16(uint16_t x) {//0xABCD becomes 0xACBD
41 | return x&0xf00f|(x&0x0f00)>>4|(x&0x00f0)<<4;
42 | }
43 |
44 | uint16_t invert_outer16(uint16_t x) { //0xABCD becomes 0xDBCA
45 | return (x&0x000f)<<12|x&0x0ff0|(x&0xf000)>>12;
46 | }
47 |
48 | uint16_t flipbyte16(uint16_t x) { //0xABCD becomes 0xBADC
49 | return (x&0x0f00)<<4|(x&0xf000)>>4|(x&0x000f)<<4|(x&0x00f0)>>4;
50 | }
51 |
52 | uint8_t flipbyte(uint8_t x) { //0xAB becomes 0xBA
53 | return x<<4&0xf0|(x>>4)&0x0f;
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/common/chc_endian.h:
--------------------------------------------------------------------------------
1 | /* chc_endian by Andrew "CHCNiZ" Learn
2 | * Copyright (C) 2009 Andrew Learn
3 | *
4 | * chc_endian is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, either version 3 of the License, or
7 | * (at your option) any later version.
8 | *
9 | * chc_endian is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with chc_endian. If not, see .
16 | */
17 | #ifndef _CHC_ENDIAN_INC
18 | #define _CHC_ENDIAN_INC
19 |
20 | // Changed to msstdint
21 | #include
22 |
23 | //now obviously madness like this isn't used often(who would need invert_bytes for example) a lot of its just for fun and no cpu i've heard of uses such a byte order, but its still included into this header
24 | uint32_t little_to_middle(uint32_t x);
25 | uint32_t reverse_endian32(uint32_t x);
26 | uint32_t invert_bytes(uint32_t x);
27 | uint32_t rev_bendian32(uint32_t x);
28 | uint16_t reverse_endian16(uint16_t x);
29 | uint16_t invert_inner16(uint16_t x);
30 | uint16_t invert_outer16(uint16_t x);
31 | uint16_t flipbyte16(uint16_t x);
32 | uint8_t flipbyte(uint8_t x);
33 |
34 | #endif
--------------------------------------------------------------------------------
/common/md5.c:
--------------------------------------------------------------------------------
1 | /*
2 | * RFC 1321 compliant MD5 implementation
3 | *
4 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 | *
6 | * Copyright (C) 2009 Paul Bakker
7 | *
8 | * This program is free software; you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation; either version 2 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along
19 | * with this program; if not, write to the Free Software Foundation, Inc.,
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 | */
22 | /*
23 | * The MD5 algorithm was designed by Ron Rivest in 1991.
24 | *
25 | * http://www.ietf.org/rfc/rfc1321.txt
26 | */
27 |
28 | //#include "polarssl/config.h"
29 | #include "md5.h"
30 | #define POLARSSL_MD5_C
31 | #if defined(POLARSSL_MD5_C)
32 |
33 | //#include "polarssl/md5.h"
34 |
35 | #include
36 | #include
37 |
38 | #ifndef _WIN32
39 | void fopen_s(FILE**fp, const char *path, const char *mode) { *fp = fopen(path, mode); }
40 | #endif
41 |
42 | /*
43 | * 32-bit integer manipulation macros (little endian)
44 | */
45 | #ifndef GET_ULONG_LE
46 | #define GET_ULONG_LE(n,b,i) \
47 | { \
48 | (n) = ( (unsigned long) (b)[(i) ] ) \
49 | | ( (unsigned long) (b)[(i) + 1] << 8 ) \
50 | | ( (unsigned long) (b)[(i) + 2] << 16 ) \
51 | | ( (unsigned long) (b)[(i) + 3] << 24 ); \
52 | }
53 | #endif
54 |
55 | #ifndef PUT_ULONG_LE
56 | #define PUT_ULONG_LE(n,b,i) \
57 | { \
58 | (b)[(i) ] = (unsigned char) ( (n) ); \
59 | (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
60 | (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
61 | (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
62 | }
63 | #endif
64 |
65 | /*
66 | * MD5 context setup
67 | */
68 | void md5_starts( md5_context *ctx )
69 | {
70 | ctx->total[0] = 0;
71 | ctx->total[1] = 0;
72 |
73 | ctx->state[0] = 0x67452301;
74 | ctx->state[1] = 0xEFCDAB89;
75 | ctx->state[2] = 0x98BADCFE;
76 | ctx->state[3] = 0x10325476;
77 | }
78 |
79 | static void md5_process( md5_context *ctx, unsigned char data[64] )
80 | {
81 | unsigned long X[16], A, B, C, D;
82 |
83 | GET_ULONG_LE( X[ 0], data, 0 );
84 | GET_ULONG_LE( X[ 1], data, 4 );
85 | GET_ULONG_LE( X[ 2], data, 8 );
86 | GET_ULONG_LE( X[ 3], data, 12 );
87 | GET_ULONG_LE( X[ 4], data, 16 );
88 | GET_ULONG_LE( X[ 5], data, 20 );
89 | GET_ULONG_LE( X[ 6], data, 24 );
90 | GET_ULONG_LE( X[ 7], data, 28 );
91 | GET_ULONG_LE( X[ 8], data, 32 );
92 | GET_ULONG_LE( X[ 9], data, 36 );
93 | GET_ULONG_LE( X[10], data, 40 );
94 | GET_ULONG_LE( X[11], data, 44 );
95 | GET_ULONG_LE( X[12], data, 48 );
96 | GET_ULONG_LE( X[13], data, 52 );
97 | GET_ULONG_LE( X[14], data, 56 );
98 | GET_ULONG_LE( X[15], data, 60 );
99 |
100 | #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
101 |
102 | #define P(a,b,c,d,k,s,t) \
103 | { \
104 | a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
105 | }
106 |
107 | A = ctx->state[0];
108 | B = ctx->state[1];
109 | C = ctx->state[2];
110 | D = ctx->state[3];
111 |
112 | #define F(x,y,z) (z ^ (x & (y ^ z)))
113 |
114 | P( A, B, C, D, 0, 7, 0xD76AA478 );
115 | P( D, A, B, C, 1, 12, 0xE8C7B756 );
116 | P( C, D, A, B, 2, 17, 0x242070DB );
117 | P( B, C, D, A, 3, 22, 0xC1BDCEEE );
118 | P( A, B, C, D, 4, 7, 0xF57C0FAF );
119 | P( D, A, B, C, 5, 12, 0x4787C62A );
120 | P( C, D, A, B, 6, 17, 0xA8304613 );
121 | P( B, C, D, A, 7, 22, 0xFD469501 );
122 | P( A, B, C, D, 8, 7, 0x698098D8 );
123 | P( D, A, B, C, 9, 12, 0x8B44F7AF );
124 | P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
125 | P( B, C, D, A, 11, 22, 0x895CD7BE );
126 | P( A, B, C, D, 12, 7, 0x6B901122 );
127 | P( D, A, B, C, 13, 12, 0xFD987193 );
128 | P( C, D, A, B, 14, 17, 0xA679438E );
129 | P( B, C, D, A, 15, 22, 0x49B40821 );
130 |
131 | #undef F
132 |
133 | #define F(x,y,z) (y ^ (z & (x ^ y)))
134 |
135 | P( A, B, C, D, 1, 5, 0xF61E2562 );
136 | P( D, A, B, C, 6, 9, 0xC040B340 );
137 | P( C, D, A, B, 11, 14, 0x265E5A51 );
138 | P( B, C, D, A, 0, 20, 0xE9B6C7AA );
139 | P( A, B, C, D, 5, 5, 0xD62F105D );
140 | P( D, A, B, C, 10, 9, 0x02441453 );
141 | P( C, D, A, B, 15, 14, 0xD8A1E681 );
142 | P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
143 | P( A, B, C, D, 9, 5, 0x21E1CDE6 );
144 | P( D, A, B, C, 14, 9, 0xC33707D6 );
145 | P( C, D, A, B, 3, 14, 0xF4D50D87 );
146 | P( B, C, D, A, 8, 20, 0x455A14ED );
147 | P( A, B, C, D, 13, 5, 0xA9E3E905 );
148 | P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
149 | P( C, D, A, B, 7, 14, 0x676F02D9 );
150 | P( B, C, D, A, 12, 20, 0x8D2A4C8A );
151 |
152 | #undef F
153 |
154 | #define F(x,y,z) (x ^ y ^ z)
155 |
156 | P( A, B, C, D, 5, 4, 0xFFFA3942 );
157 | P( D, A, B, C, 8, 11, 0x8771F681 );
158 | P( C, D, A, B, 11, 16, 0x6D9D6122 );
159 | P( B, C, D, A, 14, 23, 0xFDE5380C );
160 | P( A, B, C, D, 1, 4, 0xA4BEEA44 );
161 | P( D, A, B, C, 4, 11, 0x4BDECFA9 );
162 | P( C, D, A, B, 7, 16, 0xF6BB4B60 );
163 | P( B, C, D, A, 10, 23, 0xBEBFBC70 );
164 | P( A, B, C, D, 13, 4, 0x289B7EC6 );
165 | P( D, A, B, C, 0, 11, 0xEAA127FA );
166 | P( C, D, A, B, 3, 16, 0xD4EF3085 );
167 | P( B, C, D, A, 6, 23, 0x04881D05 );
168 | P( A, B, C, D, 9, 4, 0xD9D4D039 );
169 | P( D, A, B, C, 12, 11, 0xE6DB99E5 );
170 | P( C, D, A, B, 15, 16, 0x1FA27CF8 );
171 | P( B, C, D, A, 2, 23, 0xC4AC5665 );
172 |
173 | #undef F
174 |
175 | #define F(x,y,z) (y ^ (x | ~z))
176 |
177 | P( A, B, C, D, 0, 6, 0xF4292244 );
178 | P( D, A, B, C, 7, 10, 0x432AFF97 );
179 | P( C, D, A, B, 14, 15, 0xAB9423A7 );
180 | P( B, C, D, A, 5, 21, 0xFC93A039 );
181 | P( A, B, C, D, 12, 6, 0x655B59C3 );
182 | P( D, A, B, C, 3, 10, 0x8F0CCC92 );
183 | P( C, D, A, B, 10, 15, 0xFFEFF47D );
184 | P( B, C, D, A, 1, 21, 0x85845DD1 );
185 | P( A, B, C, D, 8, 6, 0x6FA87E4F );
186 | P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
187 | P( C, D, A, B, 6, 15, 0xA3014314 );
188 | P( B, C, D, A, 13, 21, 0x4E0811A1 );
189 | P( A, B, C, D, 4, 6, 0xF7537E82 );
190 | P( D, A, B, C, 11, 10, 0xBD3AF235 );
191 | P( C, D, A, B, 2, 15, 0x2AD7D2BB );
192 | P( B, C, D, A, 9, 21, 0xEB86D391 );
193 |
194 | #undef F
195 |
196 | ctx->state[0] += A;
197 | ctx->state[1] += B;
198 | ctx->state[2] += C;
199 | ctx->state[3] += D;
200 | }
201 |
202 | /*
203 | * MD5 process buffer
204 | */
205 | void md5_update( md5_context *ctx, unsigned char *input, int ilen )
206 | {
207 | int fill;
208 | unsigned long left;
209 |
210 | if( ilen <= 0 )
211 | return;
212 |
213 | left = ctx->total[0] & 0x3F;
214 | fill = 64 - left;
215 |
216 | ctx->total[0] += ilen;
217 | ctx->total[0] &= 0xFFFFFFFF;
218 |
219 | if( ctx->total[0] < (unsigned long) ilen )
220 | ctx->total[1]++;
221 |
222 | if( left && ilen >= fill )
223 | {
224 | memcpy( (void *) (ctx->buffer + left),
225 | (void *) input, fill );
226 | md5_process( ctx, ctx->buffer );
227 | input += fill;
228 | ilen -= fill;
229 | left = 0;
230 | }
231 |
232 | while( ilen >= 64 )
233 | {
234 | md5_process( ctx, input );
235 | input += 64;
236 | ilen -= 64;
237 | }
238 |
239 | if( ilen > 0 )
240 | {
241 | memcpy( (void *) (ctx->buffer + left),
242 | (void *) input, ilen );
243 | }
244 | }
245 |
246 | static const unsigned char md5_padding[64] =
247 | {
248 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
251 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
252 | };
253 |
254 | /*
255 | * MD5 final digest
256 | */
257 | void md5_finish( md5_context *ctx, unsigned char output[16] )
258 | {
259 | unsigned long last, padn;
260 | unsigned long high, low;
261 | unsigned char msglen[8];
262 |
263 | high = ( ctx->total[0] >> 29 )
264 | | ( ctx->total[1] << 3 );
265 | low = ( ctx->total[0] << 3 );
266 |
267 | PUT_ULONG_LE( low, msglen, 0 );
268 | PUT_ULONG_LE( high, msglen, 4 );
269 |
270 | last = ctx->total[0] & 0x3F;
271 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
272 |
273 | md5_update( ctx, (unsigned char *) md5_padding, padn );
274 | md5_update( ctx, msglen, 8 );
275 |
276 | PUT_ULONG_LE( ctx->state[0], output, 0 );
277 | PUT_ULONG_LE( ctx->state[1], output, 4 );
278 | PUT_ULONG_LE( ctx->state[2], output, 8 );
279 | PUT_ULONG_LE( ctx->state[3], output, 12 );
280 | }
281 |
282 | /*
283 | * output = MD5( input buffer )
284 | */
285 | void md5( unsigned char *input, int ilen, unsigned char output[16] )
286 | {
287 | md5_context ctx;
288 |
289 | md5_starts( &ctx );
290 | md5_update( &ctx, input, ilen );
291 | md5_finish( &ctx, output );
292 |
293 | memset( &ctx, 0, sizeof( md5_context ) );
294 | }
295 |
296 | /*
297 | * output = MD5( file contents )
298 | */
299 | int md5_file( char *path, unsigned char output[16] )
300 | {
301 | // Function changed to support fopen_s
302 | FILE *f = NULL;
303 | size_t n;
304 | md5_context ctx;
305 | unsigned char buf[1024];
306 |
307 | fopen_s(&f, path, "rb");
308 |
309 | if (f == NULL)
310 | return( 1 );
311 |
312 | md5_starts( &ctx );
313 |
314 | while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
315 | md5_update( &ctx, buf, (int) n );
316 |
317 | md5_finish( &ctx, output );
318 |
319 | memset( &ctx, 0, sizeof( md5_context ) );
320 |
321 | if( ferror( f ) != 0 )
322 | {
323 | fclose( f );
324 | return( 2 );
325 | }
326 |
327 | fclose( f );
328 | return( 0 );
329 | }
330 |
331 | /*
332 | * MD5 HMAC context setup
333 | */
334 | void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen )
335 | {
336 | int i;
337 | unsigned char sum[16];
338 |
339 | if( keylen > 64 )
340 | {
341 | md5( key, keylen, sum );
342 | keylen = 16;
343 | key = sum;
344 | }
345 |
346 | memset( ctx->ipad, 0x36, 64 );
347 | memset( ctx->opad, 0x5C, 64 );
348 |
349 | for( i = 0; i < keylen; i++ )
350 | {
351 | ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
352 | ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
353 | }
354 |
355 | md5_starts( ctx );
356 | md5_update( ctx, ctx->ipad, 64 );
357 |
358 | memset( sum, 0, sizeof( sum ) );
359 | }
360 |
361 | /*
362 | * MD5 HMAC process buffer
363 | */
364 | void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen )
365 | {
366 | md5_update( ctx, input, ilen );
367 | }
368 |
369 | /*
370 | * MD5 HMAC final digest
371 | */
372 | void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
373 | {
374 | unsigned char tmpbuf[16];
375 |
376 | md5_finish( ctx, tmpbuf );
377 | md5_starts( ctx );
378 | md5_update( ctx, ctx->opad, 64 );
379 | md5_update( ctx, tmpbuf, 16 );
380 | md5_finish( ctx, output );
381 |
382 | memset( tmpbuf, 0, sizeof( tmpbuf ) );
383 | }
384 |
385 | /*
386 | * output = HMAC-MD5( hmac key, input buffer )
387 | */
388 | void md5_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen,
389 | unsigned char output[16] )
390 | {
391 | md5_context ctx;
392 |
393 | md5_hmac_starts( &ctx, key, keylen );
394 | md5_hmac_update( &ctx, input, ilen );
395 | md5_hmac_finish( &ctx, output );
396 |
397 | memset( &ctx, 0, sizeof( md5_context ) );
398 | }
399 |
400 | #if defined(POLARSSL_SELF_TEST)
401 | /*
402 | * RFC 1321 test vectors
403 | */
404 | static unsigned char md5_test_buf[7][81] =
405 | {
406 | { "" },
407 | { "a" },
408 | { "abc" },
409 | { "message digest" },
410 | { "abcdefghijklmnopqrstuvwxyz" },
411 | { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
412 | { "12345678901234567890123456789012345678901234567890123456789012" \
413 | "345678901234567890" }
414 | };
415 |
416 | static const int md5_test_buflen[7] =
417 | {
418 | 0, 1, 3, 14, 26, 62, 80
419 | };
420 |
421 | static const unsigned char md5_test_sum[7][16] =
422 | {
423 | { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
424 | 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
425 | { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
426 | 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
427 | { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
428 | 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
429 | { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
430 | 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
431 | { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
432 | 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
433 | { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
434 | 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
435 | { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
436 | 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
437 | };
438 |
439 | /*
440 | * RFC 2202 test vectors
441 | */
442 | static unsigned char md5_hmac_test_key[7][26] =
443 | {
444 | { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
445 | { "Jefe" },
446 | { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
447 | { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
448 | "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
449 | { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
450 | { "" }, /* 0xAA 80 times */
451 | { "" }
452 | };
453 |
454 | static const int md5_hmac_test_keylen[7] =
455 | {
456 | 16, 4, 16, 25, 16, 80, 80
457 | };
458 |
459 | static unsigned char md5_hmac_test_buf[7][74] =
460 | {
461 | { "Hi There" },
462 | { "what do ya want for nothing?" },
463 | { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
464 | "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
465 | "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
466 | "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
467 | "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
468 | { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
469 | "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
470 | "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
471 | "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
472 | "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
473 | { "Test With Truncation" },
474 | { "Test Using Larger Than Block-Size Key - Hash Key First" },
475 | { "Test Using Larger Than Block-Size Key and Larger"
476 | " Than One Block-Size Data" }
477 | };
478 |
479 | static const int md5_hmac_test_buflen[7] =
480 | {
481 | 8, 28, 50, 50, 20, 54, 73
482 | };
483 |
484 | static const unsigned char md5_hmac_test_sum[7][16] =
485 | {
486 | { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
487 | 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
488 | { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
489 | 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
490 | { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
491 | 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
492 | { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
493 | 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
494 | { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
495 | 0xF9, 0xBA, 0xB9, 0x95 },
496 | { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
497 | 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
498 | { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
499 | 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
500 | };
501 |
502 | /*
503 | * Checkup routine
504 | */
505 | int md5_self_test( int verbose )
506 | {
507 | int i, buflen;
508 | unsigned char buf[1024];
509 | unsigned char md5sum[16];
510 | md5_context ctx;
511 |
512 | for( i = 0; i < 7; i++ )
513 | {
514 | if( verbose != 0 )
515 | printf( " MD5 test #%d: ", i + 1 );
516 |
517 | md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
518 |
519 | if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
520 | {
521 | if( verbose != 0 )
522 | printf( "failed\n" );
523 |
524 | return( 1 );
525 | }
526 |
527 | if( verbose != 0 )
528 | printf( "passed\n" );
529 | }
530 |
531 | if( verbose != 0 )
532 | printf( "\n" );
533 |
534 | for( i = 0; i < 7; i++ )
535 | {
536 | if( verbose != 0 )
537 | printf( " HMAC-MD5 test #%d: ", i + 1 );
538 |
539 | if( i == 5 || i == 6 )
540 | {
541 | memset( buf, '\xAA', buflen = 80 );
542 | md5_hmac_starts( &ctx, buf, buflen );
543 | }
544 | else
545 | md5_hmac_starts( &ctx, md5_hmac_test_key[i],
546 | md5_hmac_test_keylen[i] );
547 |
548 | md5_hmac_update( &ctx, md5_hmac_test_buf[i],
549 | md5_hmac_test_buflen[i] );
550 |
551 | md5_hmac_finish( &ctx, md5sum );
552 |
553 | buflen = ( i == 4 ) ? 12 : 16;
554 |
555 | if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
556 | {
557 | if( verbose != 0 )
558 | printf( "failed\n" );
559 |
560 | return( 1 );
561 | }
562 |
563 | if( verbose != 0 )
564 | printf( "passed\n" );
565 | }
566 |
567 | if( verbose != 0 )
568 | printf( "\n" );
569 |
570 | return( 0 );
571 | }
572 |
573 | #endif
574 |
575 | #endif
576 |
--------------------------------------------------------------------------------
/common/md5.h:
--------------------------------------------------------------------------------
1 | /**
2 | * \file md5.h
3 | *
4 | * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 | *
6 | * Copyright (C) 2009 Paul Bakker
7 | *
8 | * This program is free software; you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation; either version 2 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License along
19 | * with this program; if not, write to the Free Software Foundation, Inc.,
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 | */
22 | #ifndef POLARSSL_MD5_H
23 | #define POLARSSL_MD5_H
24 |
25 | /**
26 | * \brief MD5 context structure
27 | */
28 | typedef struct
29 | {
30 | unsigned long total[2]; /*!< number of bytes processed */
31 | unsigned long state[4]; /*!< intermediate digest state */
32 | unsigned char buffer[64]; /*!< data block being processed */
33 |
34 | unsigned char ipad[64]; /*!< HMAC: inner padding */
35 | unsigned char opad[64]; /*!< HMAC: outer padding */
36 | }
37 | md5_context;
38 |
39 | #ifdef __cplusplus
40 | extern "C" {
41 | #endif
42 |
43 | /**
44 | * \brief MD5 context setup
45 | *
46 | * \param ctx context to be initialized
47 | */
48 | void md5_starts( md5_context *ctx );
49 |
50 | /**
51 | * \brief MD5 process buffer
52 | *
53 | * \param ctx MD5 context
54 | * \param input buffer holding the data
55 | * \param ilen length of the input data
56 | */
57 | void md5_update( md5_context *ctx, unsigned char *input, int ilen );
58 |
59 | /**
60 | * \brief MD5 final digest
61 | *
62 | * \param ctx MD5 context
63 | * \param output MD5 checksum result
64 | */
65 | void md5_finish( md5_context *ctx, unsigned char output[16] );
66 |
67 | /**
68 | * \brief Output = MD5( input buffer )
69 | *
70 | * \param input buffer holding the data
71 | * \param ilen length of the input data
72 | * \param output MD5 checksum result
73 | */
74 | void md5( unsigned char *input, int ilen, unsigned char output[16] );
75 |
76 | /**
77 | * \brief Output = MD5( file contents )
78 | *
79 | * \param path input file name
80 | * \param output MD5 checksum result
81 | *
82 | * \return 0 if successful, 1 if fopen failed,
83 | * or 2 if fread failed
84 | */
85 | int md5_file( char *path, unsigned char output[16] );
86 |
87 | /**
88 | * \brief MD5 HMAC context setup
89 | *
90 | * \param ctx HMAC context to be initialized
91 | * \param key HMAC secret key
92 | * \param keylen length of the HMAC key
93 | */
94 | void md5_hmac_starts( md5_context *ctx, unsigned char *key, int keylen );
95 |
96 | /**
97 | * \brief MD5 HMAC process buffer
98 | *
99 | * \param ctx HMAC context
100 | * \param input buffer holding the data
101 | * \param ilen length of the input data
102 | */
103 | void md5_hmac_update( md5_context *ctx, unsigned char *input, int ilen );
104 |
105 | /**
106 | * \brief MD5 HMAC final digest
107 | *
108 | * \param ctx HMAC context
109 | * \param output MD5 HMAC checksum result
110 | */
111 | void md5_hmac_finish( md5_context *ctx, unsigned char output[16] );
112 |
113 | /**
114 | * \brief Output = HMAC-MD5( hmac key, input buffer )
115 | *
116 | * \param key HMAC secret key
117 | * \param keylen length of the HMAC key
118 | * \param input buffer holding the data
119 | * \param ilen length of the input data
120 | * \param output HMAC-MD5 result
121 | */
122 | void md5_hmac( unsigned char *key, int keylen,
123 | unsigned char *input, int ilen,
124 | unsigned char output[16] );
125 |
126 | /**
127 | * \brief Checkup routine
128 | *
129 | * \return 0 if successful, or 1 if the test failed
130 | */
131 | int md5_self_test( int verbose );
132 |
133 | #ifdef __cplusplus
134 | }
135 | #endif
136 |
137 | #endif /* md5.h */
138 |
--------------------------------------------------------------------------------
/natneg/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(SOURCES
2 | ${CMAKE_CURRENT_LIST_DIR}/NNServer.cpp
3 | ${CMAKE_CURRENT_LIST_DIR}/NNServer.h
4 | ${CMAKE_CURRENT_LIST_DIR}/ClientManager.h
5 | ${CMAKE_CURRENT_LIST_DIR}/NNTypes.h
6 | ${CMAKE_CURRENT_LIST_DIR}/ClientManager.cpp
7 | ${CMAKE_CURRENT_LIST_DIR}/Client.h
8 | ${CMAKE_CURRENT_LIST_DIR}/Client.cpp
9 | )
10 |
11 | include_directories("${CMAKE_CURRENT_LIST_DIR}/../common")
12 |
13 | add_library(NatNeg SHARED ${SOURCES})
14 | target_link_libraries(NatNeg RetroSpyCommon)
15 |
--------------------------------------------------------------------------------
/natneg/Client.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #include "Client.h"
18 |
19 | #include "ClientManager.h"
20 |
21 | #include
22 |
23 | #include "NNServer.h"
24 |
25 | #include
26 |
27 | #ifdef _WIN32
28 | #define close closesocket
29 | #endif
30 |
31 | static unsigned char NNMagicData[] = {NN_MAGIC_0, NN_MAGIC_1, NN_MAGIC_2, NN_MAGIC_3, NN_MAGIC_4, NN_MAGIC_5};
32 |
33 | CClient::~CClient()
34 | {
35 | Disconnect();
36 | }
37 |
38 | CClient::CClient(mdk_socket stream, const struct sockaddr_in* addr, CDatabase* db)
39 | {
40 | m_stream = stream;
41 | m_dbConnect = db;
42 | memcpy(&m_addr, addr, sizeof(struct sockaddr_in));
43 | memcpy(&m_punching, addr, sizeof(struct sockaddr_in));
44 |
45 | #ifdef _WIN32
46 | inet_ntop(AF_INET, (const VOID*)&(addr->sin_addr), m_ip, INET_ADDRSTRLEN);
47 | #else
48 | inet_ntop(AF_INET, &(addr->sin_addr), m_ip, INET_ADDRSTRLEN);
49 | #endif
50 | m_port = addr->sin_port;
51 |
52 | m_lastpacket = 0;
53 | m_ack = false;
54 | m_lastpacket = time(NULL);
55 | m_version = 0;
56 | m_clientindex = 0;
57 | m_init = false;
58 | m_connectTime = time(NULL);
59 | m_connected = false;
60 | }
61 |
62 | void CClient::Disconnect()
63 | {
64 | m_connected = false;
65 | }
66 |
67 | bool CClient::Handle(const char *buf, ssize_t len)
68 | {
69 | NatNegPacket *packet = (NatNegPacket*)buf;
70 | if (memcmp(packet->magic, NNMagicData, NATNEG_MAGIC_LEN) != 0)
71 | return false;
72 |
73 | m_lastpacket = time(NULL);
74 |
75 | switch(packet->packettype)
76 | {
77 | case NN_INIT:
78 | return HandleInitPacket(packet);
79 | case NN_ADDRESS_CHECK:
80 | return HandleAddressCheck(packet);
81 | case NN_NATIFY_REQUEST:
82 | return HandleNatifyRequest(packet);
83 | case NN_CONNECT_ACK:
84 | m_ack = true;
85 | break;
86 | case NN_REPORT:
87 | return HandleReport(packet);
88 | default:
89 | LOG_WARN("NatNeg", "Unknown packet type: %d", packet->packettype);
90 | return false;
91 | }
92 |
93 | return true;
94 | }
95 |
96 | bool CClient::HandleInitPacket(NatNegPacket* packet)
97 | {
98 | m_version = packet->version;
99 |
100 | if ((m_version > 1) && (packet->Packet.Init.porttype == 1))
101 | {
102 | CClient* c = CClientManager::FindClientByCookieIndex(packet->cookie, m_clientindex);
103 | if (c != NULL && c != this)
104 | {
105 | m_punching.sin_port = c->GetPunchingAddr().sin_port;
106 | CClientManager::Delete(c);
107 | }
108 | }
109 |
110 | m_cookie = packet->cookie;
111 | m_clientindex = packet->Packet.Init.clientindex;
112 | packet->packettype = NN_INITACK;
113 | Write(packet, INITPACKET_SIZE);
114 |
115 | if (packet->Packet.Init.porttype > 1)
116 | return false;
117 |
118 | m_init = true;
119 |
120 | if ((m_version < 2) || (packet->Packet.Init.porttype == 1))
121 | SendConnect(packet);
122 |
123 | return true;
124 | }
125 |
126 | void CClient::Write(void* data, int len)
127 | {
128 | CTemplateSocket::WriteUDP(m_stream, data, len, (const struct sockaddr*)&m_addr);
129 | }
130 |
131 | void CClient::SendConnect(NatNegPacket* packet, bool sendToOther)
132 | {
133 | if (m_ack || m_init == false)
134 | return;
135 |
136 | CClient* c = CClientManager::FindClientByCookieIndex(packet->cookie, m_clientindex);
137 | if (c != NULL && c != this)
138 | {
139 | NatNegPacket sendpacket = {0};
140 | sendpacket.version = m_version;
141 | sendpacket.Packet.Connect.gotyourdata = 'B';
142 | sendpacket.packettype = NN_CONNECT;
143 | sendpacket.cookie = m_cookie;
144 | memcpy(sendpacket.magic, NNMagicData, NATNEG_MAGIC_LEN);
145 | sendpacket.Packet.Connect.finished = FINISHED_NOERROR;
146 | if (!c->IsInit() || c->HaveAck())
147 | return;
148 |
149 | c->AllowConnection(true);
150 | m_connected = true;
151 |
152 | sendpacket.Packet.Connect.remoteIP = c->GetPunchingAddr().sin_addr.s_addr;
153 | sendpacket.Packet.Connect.remotePort = c->GetPunchingAddr().sin_port;
154 |
155 | Write(&sendpacket, CONNECTPACKET_SIZE);
156 |
157 | m_connectTime = time(NULL);
158 |
159 | if(!sendToOther)
160 | return;
161 |
162 | c->SetConnectTime(time(NULL));
163 |
164 | sendpacket.Packet.Connect.remoteIP = m_punching.sin_addr.s_addr;
165 | sendpacket.Packet.Connect.remotePort = m_punching.sin_port;
166 |
167 | Write(&sendpacket, CONNECTPACKET_SIZE);
168 | }
169 | }
170 |
171 | bool CClient::HandleAddressCheck(NatNegPacket* packet)
172 | {
173 | packet->packettype = NN_ADDRESS_REPLY;
174 | packet->Packet.Init.localip = m_addr.sin_addr.s_addr;
175 | packet->Packet.Init.localport = m_addr.sin_port;
176 | Write(packet, INITPACKET_SIZE);
177 | return true;
178 | }
179 |
180 | bool CClient::HandleNatifyRequest(NatNegPacket* packet)
181 | {
182 | int ret = 0;
183 |
184 | #ifdef _WIN32
185 | SOCKET ertsocket = INVALID_SOCKET;
186 | #else
187 | int ertsocket = 0;
188 | #endif
189 |
190 | struct sockaddr_in si, si_src;
191 |
192 | if (packet->Packet.Init.porttype == 1)
193 | Write(packet, INITPACKET_SIZE);
194 |
195 | ertsocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
196 | if (ertsocket == -1)
197 | return false;
198 |
199 | si.sin_family = AF_INET;
200 | si.sin_port = m_addr.sin_port;
201 | si.sin_addr.s_addr = m_addr.sin_addr.s_addr;
202 | si_src.sin_family = AF_INET;
203 |
204 | si_src.sin_port = htons(MATCHUP_PORT);
205 | if (packet->Packet.Init.porttype == NN_PT_NN2 || packet->Packet.Init.porttype == NN_PT_NN3)
206 | {
207 | inet_pton(AF_INET, CNNServer::GetProbeIP(), &si_src.sin_addr.s_addr);
208 | }
209 | else
210 | inet_pton(AF_INET, CNNServer::GetMatchIP(), &si_src.sin_addr.s_addr);
211 |
212 | if (packet->Packet.Init.porttype == NN_PT_NN3)
213 | ret = connect(ertsocket, (struct sockaddr*)&si_src, sizeof(si_src));
214 | else
215 | ret = bind(ertsocket, (struct sockaddr*)&si_src, sizeof(si_src));
216 |
217 | if (ret != 0)
218 | return false;
219 |
220 | sendto(ertsocket, (char*)packet, INITPACKET_SIZE, 0, (struct sockaddr*)&si, sizeof(si));
221 | close(ertsocket);
222 |
223 | return true;
224 | }
225 |
226 | bool CClient::HandleReport(NatNegPacket* packet)
227 | {
228 | packet->packettype = NN_REPORT_ACK;
229 | Write(packet, REPORTPACKET_SIZE);
230 | return true;
231 | }
--------------------------------------------------------------------------------
/natneg/Client.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #ifndef NN_CLIENT_H
18 | #define NN_CLIENT_H
19 |
20 | #include
21 | #include
22 |
23 | #include "NNTypes.h"
24 |
25 | #ifdef _WIN32
26 | #include
27 | #else
28 | #include
29 | #endif
30 |
31 | class CClient
32 | {
33 | public:
34 | CClient(mdk_socket stream, const struct sockaddr_in* addr, CDatabase* db);
35 | ~CClient();
36 |
37 | bool Handle(const char *buf, ssize_t len);
38 |
39 | inline unsigned short GetPort() { return m_port; }
40 | inline const char* GetIP() { return m_ip; }
41 |
42 | inline mdk_socket GetSocket() { return m_stream; }
43 |
44 | inline struct sockaddr_in* GetAddr() { return &m_addr; }
45 |
46 | void Disconnect();
47 |
48 | // Operator overload
49 | bool operator==(CClient& c);
50 | bool operator!=(CClient& c);
51 |
52 | inline void SetConnectTime(time_t time) { m_connectTime = time; }
53 | inline void AllowConnection(bool c) { m_connected = c; }
54 |
55 | inline struct sockaddr_in GetPunchingAddr() { return m_punching; }
56 |
57 | inline bool IsInit() { return m_init; }
58 | inline bool HaveAck() { return m_ack; }
59 |
60 | inline int GetCookie() { return m_cookie; }
61 | inline unsigned char GetClientIndex() { return m_clientindex; }
62 |
63 | private:
64 | struct sockaddr_in m_addr;
65 | struct sockaddr_in m_punching;
66 | time_t m_lastpacket, m_connectTime;
67 | mdk_socket m_stream;
68 | bool m_ack;
69 | int m_cookie;
70 | unsigned char m_clientindex;
71 | unsigned char m_version;
72 | bool m_init;
73 | unsigned int m_instance;
74 | bool m_connected;
75 | unsigned short m_port;
76 | char m_ip[INET_ADDRSTRLEN];
77 |
78 | protected:
79 | bool HandleInitPacket(NatNegPacket* packet);
80 | bool HandleReport(NatNegPacket* packet);
81 | bool HandleAddressCheck(NatNegPacket* packet);
82 | bool HandleNatifyRequest(NatNegPacket* packet);
83 | void SendConnect(NatNegPacket* packet, bool sendToOther = true);
84 |
85 | private:
86 | void Write(void* data, int len);
87 |
88 | CDatabase* m_dbConnect;
89 | };
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/natneg/ClientManager.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #include "ClientManager.h"
18 |
19 | #include
20 |
21 | void CClientManager::Free()
22 | {
23 | ClientMap::iterator it = m_clients.begin();
24 |
25 | while (it != m_clients.end())
26 | {
27 | // Free CClient memory
28 | if (it->second)
29 | delete it->second;
30 |
31 | it++;
32 | }
33 |
34 | m_clients.clear();
35 | }
36 |
37 | void CClientManager::Delete(ClientMap::iterator it)
38 | {
39 | CTemplateServer* server = NULL;
40 |
41 | if (it == m_clients.end())
42 | return;
43 |
44 | if (!it->second)
45 | return;
46 |
47 | delete (it->second);
48 |
49 | m_clients.erase(it);
50 | }
51 |
52 | bool CClientManager::CreateAndHandle(CDatabase* db, mdk_socket stream, const struct sockaddr_in* addr_in, const char *data, ssize_t len)
53 | {
54 | // Create che client
55 | CClient* c = new CClient(stream, addr_in, db);
56 | SClientStruct ss;
57 |
58 | inet_ntop(AF_INET, &(addr_in->sin_addr), ss.ip, INET_ADDRSTRLEN);
59 |
60 | ss.port = addr_in->sin_port;
61 |
62 | m_clients[ss] = c;
63 |
64 | if (!c->Handle(data, len))
65 | {
66 | Delete(c); // Delete the client if it returned false
67 | return false;
68 | }
69 |
70 | return true;
71 | }
72 |
73 | bool CClientManager::Handle(CDatabase* con, mdk_socket stream, const struct sockaddr* addr, const char *data, ssize_t len)
74 | {
75 | ClientMap::iterator it;
76 | unsigned int i = 0;
77 | SClientStruct ss;
78 | struct sockaddr_in* addr_in = (struct sockaddr_in*)addr;
79 |
80 | inet_ntop(AF_INET, &(addr_in->sin_addr), ss.ip, INET_ADDRSTRLEN);
81 | ss.port = addr_in->sin_port;
82 |
83 | it = m_clients.find(ss);
84 |
85 | if (it == m_clients.end())
86 | return CreateAndHandle(con, stream, addr_in, data, len);
87 |
88 | // Handle our client
89 | if (!it->second->Handle(data, len))
90 | {
91 | Delete(it); // Delete the client if it returned false
92 | return false;
93 | }
94 |
95 | return true;
96 | }
97 |
98 | void CClientManager::Delete(CClient* c)
99 | {
100 | ClientMap::iterator it = m_clients.begin();
101 |
102 | while (it != m_clients.end())
103 | {
104 | CClient *cc = it->second;
105 |
106 | if (cc == c)
107 | {
108 | Delete(it);
109 | return;
110 | }
111 |
112 | it++;
113 | }
114 | }
115 |
116 | CClient* CClientManager::FindClientByCookieIndex(int cookie, unsigned char index)
117 | {
118 | ClientMap::iterator it = m_clients.begin();
119 |
120 | while (it != m_clients.end())
121 | {
122 | CClient *cc = it->second;
123 |
124 | if (cc->GetCookie() == cookie && cc->GetClientIndex() == index)
125 | return cc;
126 |
127 | it++;
128 | }
129 |
130 | return NULL;
131 | }
132 |
133 |
134 | ClientMap CClientManager::m_clients;
135 |
--------------------------------------------------------------------------------
/natneg/ClientManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | This file is part of RetroSpy Server.
3 |
4 | RetroSpy Server is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | RetroSpy Server is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with RetroSpy Server. If not, see .
16 | */
17 | #ifndef NN_CLIENTMANAGER_H
18 | #define NN_CLIENTMANAGER_H
19 |
20 | #include "Client.h"
21 |
22 | #include
23 |
24 | #include