mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `mqtt` - the pm3 client can now send and receive MQTT messages or json files. (@iceman1001)
|
||||
- Changed `hf iclass wrbl` - replay behavior to use privilege escalation if the macs field is not passed empty(@antiklesys)
|
||||
- Changed `hf iclass restore` - it now supports privilege escalation to restore card content using replay (@antiklesys)
|
||||
- Fixed `hf 15 dump` - now reads sysinfo response correct (@iceman1001)
|
||||
|
||||
@@ -402,6 +402,7 @@ set (TARGET_SOURCES
|
||||
${PM3_ROOT}/client/src/cmdlfvisa2000.c
|
||||
${PM3_ROOT}/client/src/cmdlfzx8211.c
|
||||
${PM3_ROOT}/client/src/cmdmain.c
|
||||
${PM3_ROOT}/client/src/cmdmqtt.c
|
||||
${PM3_ROOT}/client/src/cmdnfc.c
|
||||
${PM3_ROOT}/client/src/cmdparser.c
|
||||
${PM3_ROOT}/client/src/cmdpiv.c
|
||||
@@ -772,6 +773,7 @@ target_link_libraries(proxmark3 PRIVATE
|
||||
pm3rrg_rdv4_reveng
|
||||
pm3rrg_rdv4_hardnested
|
||||
pm3rrg_rdv4_id48
|
||||
pm3rrg_rdv4_mqtt
|
||||
${ADDITIONAL_LNK})
|
||||
|
||||
if (NOT SKIPPTHREAD EQUAL 1)
|
||||
|
||||
@@ -131,6 +131,12 @@ WHEREAMILIBINC = -I$(WHEREAMILIBPATH)
|
||||
WHEREAMILIB = $(WHEREAMILIBPATH)/libwhereami.a
|
||||
WHEREAMILIBLD =
|
||||
|
||||
## MQTT
|
||||
MQTTLIBPATH = ./deps/mqtt
|
||||
MQTTLIBINC = -I$(MQTTLIBPATH)
|
||||
MQTTLIB = $(MQTTLIBPATH)/mqtt.a
|
||||
MQTTLIBLD =
|
||||
|
||||
##########################
|
||||
# common local libraries #
|
||||
##########################
|
||||
@@ -239,6 +245,12 @@ STATICLIBS += $(WHEREAMILIB)
|
||||
LDLIBS += $(WHEREAMILIBLD)
|
||||
PM3INCLUDES += $(WHEREAMILIBINC)
|
||||
|
||||
## MQTT
|
||||
# not distributed as system library
|
||||
STATICLIBS += $(MQTTLIB)
|
||||
LDLIBS += $(MQTTLIBLD)
|
||||
PM3INCLUDES += $(MQTTLIBINC)
|
||||
|
||||
####################
|
||||
# system libraries #
|
||||
####################
|
||||
@@ -682,6 +694,7 @@ SRCS = mifare/aiddesfire.c \
|
||||
cmdlfvisa2000.c \
|
||||
cmdlfzx8211.c \
|
||||
cmdmain.c \
|
||||
cmdmqtt.c \
|
||||
cmdnfc.c \
|
||||
cmdparser.c \
|
||||
cmdpiv.c \
|
||||
@@ -877,6 +890,7 @@ endif
|
||||
$(Q)$(MAKE) --no-print-directory -C $(REVENGLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(TINYCBORLIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) clean
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) clean
|
||||
@# Just in case someone compiled within these dirs:
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MBEDTLSLIBPATH) clean
|
||||
|
||||
@@ -974,6 +988,10 @@ ifneq ($(WHEREAMI_FOUND),1)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(WHEREAMILIBPATH) all
|
||||
endif
|
||||
|
||||
$(MQTTLIB): .FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C $(MQTTLIBPATH) all
|
||||
|
||||
########
|
||||
# SWIG #
|
||||
########
|
||||
|
||||
@@ -31,3 +31,6 @@ endif()
|
||||
if (NOT TARGET pm3rrg_rdv4_whereami)
|
||||
include(whereami.cmake)
|
||||
endif()
|
||||
if (NOT TARGET pm3rrg_rdv4_mqtt)
|
||||
include(mqtt.cmake)
|
||||
endif()
|
||||
+21
-22
@@ -440,33 +440,32 @@ int json_dumpfd(const json_t *json, int output, size_t flags) {
|
||||
}
|
||||
|
||||
int json_dump_file(const json_t *json, const char *path, size_t flags) {
|
||||
int result;
|
||||
|
||||
FILE *output = fopen(path, "w");
|
||||
if (!output)
|
||||
FILE *f = fopen(path, "w");
|
||||
if (f == NULL) {
|
||||
return -1;
|
||||
|
||||
result = json_dumpf(json, output, flags);
|
||||
|
||||
if (fclose(output) != 0)
|
||||
return -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags) {
|
||||
int res;
|
||||
hashtable_t parents_set;
|
||||
|
||||
if (!(flags & JSON_ENCODE_ANY)) {
|
||||
if (!json_is_array(json) && !json_is_object(json))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hashtable_init(&parents_set))
|
||||
int res = json_dumpf(json, f, flags);
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return -1;
|
||||
res = do_dump(json, flags, 0, &parents_set, callback, data);
|
||||
hashtable_close(&parents_set);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags) {
|
||||
if (!(flags & JSON_ENCODE_ANY)) {
|
||||
if (!json_is_array(json) && !json_is_object(json)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
hashtable_t parents_set;
|
||||
if (hashtable_init(&parents_set)) {
|
||||
return -1;
|
||||
}
|
||||
int res = do_dump(json, flags, 0, &parents_set, callback, data);
|
||||
hashtable_close(&parents_set);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
|
||||
../../common/mbedtls/x509.c
|
||||
../../common/mbedtls/x509_crl.c
|
||||
../../common/mbedtls/x509_crt.c
|
||||
../../common/mbedtls/net_sockets.c
|
||||
../../common/mbedtls/net_sockets.c
|
||||
)
|
||||
|
||||
target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
add_library(pm3rrg_rdv4_mqtt STATIC
|
||||
mqtt/mqtt.c
|
||||
mqtt/mqtt_pal.c
|
||||
)
|
||||
|
||||
target_compile_definitions(pm3rrg_rdv4_mqtt PRIVATE WAI_PM3_TUNED)
|
||||
target_include_directories(pm3rrg_rdv4_mqtt INTERFACE mqtt)
|
||||
target_compile_options(pm3rrg_rdv4_mqtt PRIVATE -Wall -Werror -O3)
|
||||
set_property(TARGET pm3rrg_rdv4_mqtt PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,14 @@
|
||||
MYSRCPATHS =
|
||||
MYINCLUDES =
|
||||
MYCFLAGS = -Wno-bad-function-cast -Wno-switch-enum
|
||||
MYDEFS = -DWAI_PM3_TUNED
|
||||
MYSRCS = \
|
||||
mqtt.c \
|
||||
mqtt_pal.c \
|
||||
|
||||
LIB_A = mqtt.a
|
||||
|
||||
# Transition: remove old directories and objects
|
||||
MYCLEANOLDPATH = ../../mqtt
|
||||
|
||||
include ../../../Makefile.host
|
||||
@@ -0,0 +1,152 @@
|
||||
#if !defined(__MBEDTLS_SOCKET_TEMPLATE_H__)
|
||||
#define __MBEDTLS_SOCKET_TEMPLATE_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mbedtls/error.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/net_sockets.h>
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
#if !defined(MBEDTLS_NET_POLL_READ)
|
||||
/* compat for older mbedtls */
|
||||
#define MBEDTLS_NET_POLL_READ 1
|
||||
#define MBEDTLS_NET_POLL_WRITE 1
|
||||
|
||||
int mbedtls_net_poll(mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout) {
|
||||
/* XXX this is not ideal but good enough for an example */
|
||||
msleep(300);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct mbedtls_context {
|
||||
mbedtls_net_context net_ctx;
|
||||
mbedtls_ssl_context ssl_ctx;
|
||||
mbedtls_ssl_config ssl_conf;
|
||||
mbedtls_x509_crt ca_crt;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
};
|
||||
|
||||
void failed(const char *fn, int rv);
|
||||
void cert_verify_failed(uint32_t rv);
|
||||
void open_nb_socket(struct mbedtls_context *ctx,
|
||||
const char *hostname,
|
||||
const char *port,
|
||||
const char *ca_file);
|
||||
|
||||
|
||||
void failed(const char *fn, int rv) {
|
||||
char buf[100];
|
||||
mbedtls_strerror(rv, buf, sizeof(buf));
|
||||
printf("%s failed with %x (%s)\n", fn, -rv, buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void cert_verify_failed(uint32_t rv) {
|
||||
char buf[512];
|
||||
mbedtls_x509_crt_verify_info(buf, sizeof(buf), "\t", rv);
|
||||
printf("Certificate verification failed (%0" PRIx32 ")\n%s\n", rv, buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
A template for opening a non-blocking mbed TLS connection.
|
||||
*/
|
||||
void open_nb_socket(struct mbedtls_context *ctx,
|
||||
const char *hostname,
|
||||
const char *port,
|
||||
const char *ca_file) {
|
||||
|
||||
const unsigned char *additional = (const unsigned char *)"Pm3 Client";
|
||||
size_t additional_len = 6;
|
||||
int rv;
|
||||
|
||||
mbedtls_net_context *net_ctx = &ctx->net_ctx;
|
||||
mbedtls_ssl_context *ssl_ctx = &ctx->ssl_ctx;
|
||||
mbedtls_ssl_config *ssl_conf = &ctx->ssl_conf;
|
||||
mbedtls_x509_crt *ca_crt = &ctx->ca_crt;
|
||||
mbedtls_entropy_context *entropy = &ctx->entropy;
|
||||
mbedtls_ctr_drbg_context *ctr_drbg = &ctx->ctr_drbg;
|
||||
|
||||
mbedtls_entropy_init(entropy);
|
||||
mbedtls_ctr_drbg_init(ctr_drbg);
|
||||
rv = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func, entropy,
|
||||
additional, additional_len);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ctr_drbg_seed", rv);
|
||||
}
|
||||
|
||||
mbedtls_x509_crt_init(ca_crt);
|
||||
rv = mbedtls_x509_crt_parse_file(ca_crt, ca_file);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_x509_crt_parse_file", rv);
|
||||
}
|
||||
|
||||
mbedtls_ssl_config_init(ssl_conf);
|
||||
rv = mbedtls_ssl_config_defaults(ssl_conf, MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_config_defaults", rv);
|
||||
}
|
||||
mbedtls_ssl_conf_ca_chain(ssl_conf, ca_crt, NULL);
|
||||
mbedtls_ssl_conf_authmode(ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
mbedtls_ssl_conf_rng(ssl_conf, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
|
||||
mbedtls_net_init(net_ctx);
|
||||
rv = mbedtls_net_connect(net_ctx, hostname, port, MBEDTLS_NET_PROTO_TCP);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_net_connect", rv);
|
||||
}
|
||||
rv = mbedtls_net_set_nonblock(net_ctx);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_net_set_nonblock", rv);
|
||||
}
|
||||
|
||||
mbedtls_ssl_init(ssl_ctx);
|
||||
rv = mbedtls_ssl_setup(ssl_ctx, ssl_conf);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_setup", rv);
|
||||
}
|
||||
rv = mbedtls_ssl_set_hostname(ssl_ctx, hostname);
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_set_hostname", rv);
|
||||
}
|
||||
mbedtls_ssl_set_bio(ssl_ctx, net_ctx,
|
||||
mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
|
||||
for (;;) {
|
||||
rv = mbedtls_ssl_handshake(ssl_ctx);
|
||||
uint32_t want = 0;
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
want |= MBEDTLS_NET_POLL_READ;
|
||||
} else if (rv == MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
want |= MBEDTLS_NET_POLL_WRITE;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
rv = mbedtls_net_poll(net_ctx, want, (uint32_t) -1);
|
||||
if (rv < 0) {
|
||||
failed("mbedtls_net_poll", rv);
|
||||
}
|
||||
}
|
||||
if (rv != 0) {
|
||||
failed("mbedtls_ssl_handshake", rv);
|
||||
}
|
||||
uint32_t result = mbedtls_ssl_get_verify_result(ssl_ctx);
|
||||
if (result != 0) {
|
||||
if (result == (uint32_t) -1) {
|
||||
failed("mbedtls_ssl_get_verify_result", (int)result);
|
||||
} else {
|
||||
cert_verify_failed(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mqtt.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Implements @ref mqtt_pal_sendall and @ref mqtt_pal_recvall and
|
||||
* any platform-specific helpers you'd like.
|
||||
* @cond Doxygen_Suppress
|
||||
*/
|
||||
|
||||
#if defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
|
||||
/*
|
||||
* In case of MQTT_USE_CUSTOM_SOCKET_HANDLE, a pal implemantation is
|
||||
* provided by the user.
|
||||
*/
|
||||
|
||||
/* Note: Some toolchains complain on an object without symbols */
|
||||
|
||||
int _mqtt_pal_dummy;
|
||||
|
||||
#else /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
#include <mbedtls/ssl.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
int rv = mbedtls_ssl_write(fd, (const unsigned char *)buf + sent, len - sent);
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_write later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Note: rv can be 0 here eg. when mbedtls just flushed
|
||||
* the previous incomplete record.
|
||||
*
|
||||
* Note: we never send an empty TLS record.
|
||||
*/
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
int rv;
|
||||
do {
|
||||
rv = mbedtls_ssl_read(fd, (unsigned char *)buf, bufsz);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* Note: mbedtls_ssl_read returns 0 when the underlying
|
||||
* transport was closed without CloseNotify.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (rv == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
rv == MBEDTLS_ERR_SSL_WANT_WRITE
|
||||
#if defined(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS
|
||||
#endif
|
||||
#if defined(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)
|
||||
|| rv == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS
|
||||
#endif
|
||||
) {
|
||||
/* should call mbedtls_ssl_read later again */
|
||||
break;
|
||||
}
|
||||
/* Note: MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is handled here. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (const char *)buf - (const char *)start;
|
||||
}
|
||||
|
||||
#elif defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
enum MQTTErrors error = 0;
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
ssize_t rv = send(fd, (const char *)buf + sent, len - sent, flags);
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
/* should call send later again */
|
||||
break;
|
||||
}
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv == 0) {
|
||||
/* is this possible? maybe OS bug. */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
sent += (size_t) rv;
|
||||
}
|
||||
if (sent == 0) {
|
||||
return error;
|
||||
}
|
||||
return (ssize_t)sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const void *const start = buf;
|
||||
enum MQTTErrors error = 0;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv == 0) {
|
||||
/*
|
||||
* recv returns 0 when the socket is (half) closed by the peer.
|
||||
*
|
||||
* Raise an error to trigger a reconnect.
|
||||
*/
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
if (rv < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
/* should call recv later again */
|
||||
break;
|
||||
}
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
error = MQTT_ERROR_SOCKET_ERROR;
|
||||
break;
|
||||
}
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= (unsigned long)rv;
|
||||
} while (bufsz > 0);
|
||||
if (buf == start) {
|
||||
return error;
|
||||
}
|
||||
return (char *)buf - (const char *)start;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags) {
|
||||
size_t sent = 0;
|
||||
while (sent < len) {
|
||||
ssize_t tmp = send(fd, (char *)buf + sent, len - sent, flags);
|
||||
if (tmp < 1) {
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
sent += (size_t) tmp;
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags) {
|
||||
const char *const start = buf;
|
||||
ssize_t rv;
|
||||
do {
|
||||
rv = recv(fd, buf, bufsz, flags);
|
||||
if (rv > 0) {
|
||||
/* successfully read bytes from the socket */
|
||||
buf = (char *)buf + rv;
|
||||
bufsz -= rv;
|
||||
} else if (rv < 0) {
|
||||
int err = WSAGetLastError();
|
||||
if (err != WSAEWOULDBLOCK) {
|
||||
/* an error occurred that wasn't "nothing to read". */
|
||||
return MQTT_ERROR_SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
} while (rv > 0 && bufsz > 0);
|
||||
|
||||
return (ssize_t)((char *)buf - start);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error No PAL!
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* defined(MQTT_USE_CUSTOM_SOCKET_HANDLE) */
|
||||
|
||||
/** @endcond */
|
||||
@@ -0,0 +1,173 @@
|
||||
#if !defined(__MQTT_PAL_H__)
|
||||
#define __MQTT_PAL_H__
|
||||
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright(c) 2018 Liam Bindle
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Includes/supports the types/calls required by the MQTT-C client.
|
||||
*
|
||||
* @note This is the \em only file included in mqtt.h, and mqtt.c. It is therefore
|
||||
* responsible for including/supporting all the required types and calls.
|
||||
*
|
||||
* @defgroup pal Platform abstraction layer
|
||||
* @brief Documentation of the types and calls required to port MQTT-C to a new platform.
|
||||
*
|
||||
* mqtt_pal.h is the \em only header file included in mqtt.c. Therefore, to port MQTT-C to a
|
||||
* new platform the following types, functions, constants, and macros must be defined in
|
||||
* mqtt_pal.h:
|
||||
* - Types:
|
||||
* - \c size_t, \c ssize_t
|
||||
* - \c uint8_t, \c uint16_t, \c uint32_t
|
||||
* - \c va_list
|
||||
* - \c mqtt_pal_time_t : return type of \c MQTT_PAL_TIME()
|
||||
* - \c mqtt_pal_mutex_t : type of the argument that is passed to \c MQTT_PAL_MUTEX_LOCK and
|
||||
* \c MQTT_PAL_MUTEX_RELEASE
|
||||
* - Functions:
|
||||
* - \c memcpy, \c strlen
|
||||
* - \c va_start, \c va_arg, \c va_end
|
||||
* - Constants:
|
||||
* - \c INT_MIN
|
||||
*
|
||||
* Additionally, three macro's are required:
|
||||
* - \c MQTT_PAL_HTONS(s) : host-to-network endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_NTOHS(s) : network-to-host endian conversion for uint16_t.
|
||||
* - \c MQTT_PAL_TIME() : returns [type: \c mqtt_pal_time_t] current time in seconds.
|
||||
* - \c MQTT_PAL_MUTEX_LOCK(mtx_pointer) : macro that locks the mutex pointed to by \c mtx_pointer.
|
||||
* - \c MQTT_PAL_MUTEX_RELEASE(mtx_pointer) : macro that unlocks the mutex pointed to by
|
||||
* \c mtx_pointer.
|
||||
*
|
||||
* Lastly, \ref mqtt_pal_sendall and \ref mqtt_pal_recvall, must be implemented in mqtt_pal.c
|
||||
* for sending and receiving data using the platforms socket calls.
|
||||
*/
|
||||
|
||||
|
||||
/* UNIX-like platform support */
|
||||
#if defined(__unix__) || defined(__APPLE__) || defined(__NuttX__)
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef pthread_mutex_t mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) pthread_mutex_init(mtx_ptr, NULL)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) pthread_mutex_lock(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) pthread_mutex_unlock(mtx_ptr)
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
#if defined(MQTT_USE_MBEDTLS)
|
||||
struct mbedtls_ssl_context;
|
||||
typedef struct mbedtls_ssl_context *mqtt_pal_socket_handle;
|
||||
#else
|
||||
typedef int mqtt_pal_socket_handle;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER) || defined(WIN32)
|
||||
#include <limits.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef SSIZE_T ssize_t;
|
||||
#define MQTT_PAL_HTONS(s) htons(s)
|
||||
#define MQTT_PAL_NTOHS(s) ntohs(s)
|
||||
|
||||
#define MQTT_PAL_TIME() time(NULL)
|
||||
|
||||
typedef time_t mqtt_pal_time_t;
|
||||
typedef CRITICAL_SECTION mqtt_pal_mutex_t;
|
||||
|
||||
#define MQTT_PAL_MUTEX_INIT(mtx_ptr) InitializeCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_LOCK(mtx_ptr) EnterCriticalSection(mtx_ptr)
|
||||
#define MQTT_PAL_MUTEX_UNLOCK(mtx_ptr) LeaveCriticalSection(mtx_ptr)
|
||||
|
||||
|
||||
#if !defined(MQTT_USE_CUSTOM_SOCKET_HANDLE)
|
||||
typedef SOCKET mqtt_pal_socket_handle;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sends all the bytes in a buffer.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the first byte in the buffer to send.
|
||||
* @param[in] len The number of bytes to send (starting at \p buf).
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes sent if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void *buf, size_t len, int flags);
|
||||
|
||||
/**
|
||||
* @brief Non-blocking receive all the byte available.
|
||||
* @ingroup pal
|
||||
*
|
||||
* @param[in] fd The file-descriptor (or handle) of the socket.
|
||||
* @param[in] buf A pointer to the receive buffer.
|
||||
* @param[in] bufsz The max number of bytes that can be put into \p buf.
|
||||
* @param[in] flags Flags which are passed to the underlying socket.
|
||||
*
|
||||
* @returns The number of bytes received if successful, an \ref MQTTErrors otherwise.
|
||||
*
|
||||
* Note about the error handling:
|
||||
* - On an error, if some bytes have been processed already,
|
||||
* this function should return the number of bytes successfully
|
||||
* processed. (partial success)
|
||||
* - Otherwise, if the error is an equivalent of EAGAIN, return 0.
|
||||
* - Otherwise, return MQTT_ERROR_SOCKET_ERROR.
|
||||
*/
|
||||
ssize_t mqtt_pal_recvall(mqtt_pal_socket_handle fd, void *buf, size_t bufsz, int flags);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
#if !defined(__POSIX_SOCKET_TEMPLATE_H__)
|
||||
#define __POSIX_SOCKET_TEMPLATE_H__
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// A template for opening a non-blocking POSIX socket.
|
||||
|
||||
void close_nb_socket(int sockfd);
|
||||
int open_nb_socket(const char *addr, const char *port);
|
||||
|
||||
int open_nb_socket(const char *addr, const char *port) {
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
|
||||
hints.ai_socktype = SOCK_STREAM; /* Must be TCP */
|
||||
|
||||
struct addrinfo *p, *servinfo;
|
||||
|
||||
/* get address information */
|
||||
int rv = getaddrinfo(addr, port, &hints, &servinfo);
|
||||
if (rv != 0) {
|
||||
fprintf(stderr, "Failed to open socket (getaddrinfo): %s\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the first possible socket */
|
||||
int sockfd = -1;
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
if (sockfd == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* connect to server */
|
||||
rv = connect(sockfd, p->ai_addr, p->ai_addrlen);
|
||||
if (rv == -1) {
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// free servinfo
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
// make non-blocking
|
||||
if (sockfd != -1) {
|
||||
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void close_nb_socket(int sockfd) {
|
||||
if (sockfd != -1) {
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
# Information
|
||||
Source: https://github.com/LiamBindle/MQTT-C
|
||||
License: MIT
|
||||
Authors:
|
||||
|
||||
MQTT-C was initially developed as a CMPT 434 (Winter Term, 2018) final project at the University of Saskatchewan by:
|
||||
|
||||
- Liam Bindle
|
||||
- Demilade Adeoye
|
||||
|
||||
|
||||
# about
|
||||
MQTT-C is an MQTT v3.1.1 client written in C. MQTT is a lightweight publisher-subscriber-based messaging protocol that is commonly used in IoT and networking applications where high-latency and low data-rate links are expected. The purpose of MQTT-C is to provide a portable MQTT client, written in C, for embedded systems and PC's alike. MQTT-C does this by providing a transparent Platform Abstraction Layer (PAL) which makes porting to new platforms easy. MQTT-C is completely thread-safe but can also run perfectly fine on single-threaded systems making MQTT-C well-suited for embedded systems and microcontrollers. Finally, MQTT-C is small; there are only two source files totalling less than 2000 lines.
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#if !defined(__WIN32_SOCKET_TEMPLATE_H__)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
void close_nb_socket(int sockfd);
|
||||
int open_nb_socket(const char *addr, const char *port);
|
||||
|
||||
int open_nb_socket(const char *addr, const char *port) {
|
||||
|
||||
WSADATA wsaData;
|
||||
int res = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (res != 0) {
|
||||
fprintf(stderr, "error: WSAStartup failed with error: %i", res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
|
||||
hints.ai_socktype = SOCK_STREAM; // Must be TCP
|
||||
hints.ai_protocol = IPPROTO_TCP; //
|
||||
|
||||
struct addrinfo *p, *servinfo;
|
||||
// get address information
|
||||
int rv = getaddrinfo(addr, port, &hints, &servinfo);
|
||||
if (rv != 0) {
|
||||
fprintf(stderr, "error: getaddrinfo: %s", gai_strerror(rv));
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the first possible socket */
|
||||
SOCKET hSocket = INVALID_SOCKET;
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
hSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||
|
||||
if (hSocket == INVALID_SOCKET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect to server
|
||||
if (connect(hSocket, p->ai_addr, (int)p->ai_addrlen) != INVALID_SOCKET) {
|
||||
break;
|
||||
}
|
||||
|
||||
closesocket(hSocket);
|
||||
hSocket = INVALID_SOCKET;
|
||||
|
||||
}
|
||||
|
||||
// free servinfo
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
if (p == NULL) { // No address succeeded
|
||||
fprintf(stderr, "error: Could not connect");
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make non-blocking
|
||||
if (hSocket != INVALID_SOCKET) {
|
||||
uint32_t mode = 1; // FIONBIO returns size on 32b
|
||||
ioctlsocket(hSocket, FIONBIO, (u_long *)&mode);
|
||||
}
|
||||
|
||||
int flag = 1;
|
||||
res = setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag));
|
||||
if (res != 0) {
|
||||
closesocket(hSocket);
|
||||
WSACleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hSocket;
|
||||
}
|
||||
|
||||
void close_nb_socket(int sockfd) {
|
||||
if (sockfd != -1) {
|
||||
close(sockfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1135,7 +1135,7 @@ int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) {
|
||||
res = PM3_EMALLOC;
|
||||
}
|
||||
}
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
DropField();
|
||||
return res;
|
||||
|
||||
@@ -781,17 +781,20 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces) {
|
||||
}
|
||||
int legic_get_type(legic_card_select_t *card) {
|
||||
|
||||
if (card == NULL)
|
||||
if (card == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_LEGIC_INFO, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false)
|
||||
if (WaitForResponseTimeout(CMD_HF_LEGIC_INFO, &resp, 1500) == false) {
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS)
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
memcpy(card, resp.data.asBytes, sizeof(legic_card_select_t));
|
||||
return PM3_SUCCESS;
|
||||
@@ -1527,7 +1530,7 @@ int readLegicUid(bool loop, bool verbose) {
|
||||
PrintAndLogEx(SUCCESS, " MSN: " _GREEN_("%s"), sprint_hex(card.uid + 1, sizeof(card.uid) - 1));
|
||||
legic_print_type(card.cardsize, 0);
|
||||
|
||||
} while (loop && kbd_enter_pressed() == false);
|
||||
} while (loop && (kbd_enter_pressed() == false));
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
+3
-3
@@ -462,7 +462,7 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
} while (cm && kbd_enter_pressed() == false);
|
||||
} while (cm && (kbd_enter_pressed() == false));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ int CmdLFRead(const char *Cmd) {
|
||||
int ret = PM3_SUCCESS;
|
||||
do {
|
||||
ret = lf_read_internal(realtime, verbose, samples);
|
||||
} while (cm && kbd_enter_pressed() == false);
|
||||
} while (cm && (kbd_enter_pressed() == false));
|
||||
|
||||
if (ret == PM3_SUCCESS) {
|
||||
PrintAndLogEx(SUCCESS, "Got " _YELLOW_("%zu") " samples", g_GraphTraceLen);
|
||||
@@ -985,7 +985,7 @@ int CmdLFSniff(const char *Cmd) {
|
||||
int ret = PM3_SUCCESS;
|
||||
do {
|
||||
ret = lf_sniff(realtime, verbose, samples);
|
||||
} while (cm && kbd_enter_pressed() == false);
|
||||
} while (cm && (kbd_enter_pressed() == false));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user