Tools to make secret sharing easier.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

228 lines
6.1 KiB

/*
* gfsec - Secret sharing tools
* Copyright (C) 2016 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "mtp-support.h"
#ifndef HAVE_LIBMTP
#include <errno.h>
unsigned char *
gfsec_get_file_from_mtp(const char *authority,
const char *path,
size_t *len)
{
(void) authority;
(void) path;
(void) len;
errno = ENOSYS;
return NULL;
}
#else
#include <string.h>
#include <splitstr.h>
#define MTP_ROOT_FOLDER_ID 0xFFFFFFFF
/**
* Finds a connected MTP device with the specified serial number.
*
* @param[in] wanted_serial The serial number of the device to find.
*
* @return An object representing the found device (to be freed with
* LIBMTP_Release_Device), or NULL if no device was found.
*/
static LIBMTP_mtpdevice_t *
find_mtp_device(const char *wanted_serial)
{
LIBMTP_raw_device_t *raw_devices;
LIBMTP_mtpdevice_t *device;
int i, n;
if ( LIBMTP_Detect_Raw_Devices(&raw_devices, &n) != 0 )
return NULL;
for ( i = 0, device = NULL; i < n && device == NULL; i++ ) {
char *serial;
device = LIBMTP_Open_Raw_Device_Uncached(&(raw_devices[i]));
if ( (serial = LIBMTP_Get_Serialnumber(device)) == NULL ||
strcmp(serial, wanted_serial) != 0 ) {
LIBMTP_Release_Device(device);
device = NULL;
if ( serial )
free(serial);
}
}
free(raw_devices);
return device;
}
/**
* Finds a file on a given MTP device.
*
* @param[in] device The MTP device.
* @param[in] storage Storage identifier (0 to search in all storages).
* @param[in] path The path of the file to find.
* @param[out] size If not NULL and the file is found, this will be set
* to the size of the file.
*
* @return The MTP identifier for the file if found, or -1 if not found.
*/
static long
find_mtp_file(LIBMTP_mtpdevice_t *device,
unsigned storage,
const char *path,
size_t *size)
{
char **components;
size_t n;
unsigned i, file_id;
long rc = -1;
if ( ! (components = splitstr(path, '/', &n)) )
return -1;
for ( i = 0, file_id = MTP_ROOT_FOLDER_ID; i < n; i++ ) {
LIBMTP_file_t *files, *file;
int found = 0;
files = LIBMTP_Get_Files_And_Folders(device, storage, file_id);
file = files;
while ( file && ! found ) {
LIBMTP_file_t *tmp;
if ( strcmp(file->filename, components[i]) == 0 ) {
if ( file->filetype == LIBMTP_FILETYPE_FOLDER && i < n - 1 ) {
file_id = file->item_id;
found = 1;
}
else if ( file->filetype != LIBMTP_FILETYPE_FOLDER && i == n - 1 ) {
rc = file->item_id;
found = 1;
if ( size )
*size = file->filesize;
}
}
tmp = file;
file = file->next;
LIBMTP_destroy_file_t(tmp);
}
if ( ! found )
i = n; /* Exit loop. */
}
free(components);
return rc;
}
struct getfile_cb_data {
unsigned char *buffer;
unsigned written;
size_t expected;
};
/**
* Callback for the LIBMTP_Get_File_To_Handler function.
*
* @param params MTP parameters (unused).
* @param priv Pointer to a getfile_cb_data structure.
* @param sendlen Number of bytes available.
* @param data Actual bytes available.
* @param[out] putlen Number of bytes used.
*
* @return LIBMTP_HANLDER_RETURN_OK if successful, or
* LIBMTP_HANDLER_RETURN_ERROR if we get more bytes than we expected.
*/
static unsigned short
getfile_cb(void *params,
void *priv,
unsigned sendlen,
unsigned char *data,
unsigned *putlen)
{
struct getfile_cb_data *cb_data = priv;
(void) params;
if ( cb_data->written + sendlen > cb_data->expected )
return LIBMTP_HANDLER_RETURN_ERROR;
memcpy(cb_data->buffer + cb_data->written, data, sendlen);
cb_data->written += sendlen;
*putlen = sendlen;
return LIBMTP_HANDLER_RETURN_OK;
}
/**
* Gets the contents of a file on a MTP device.
*
* @param[in] authority Serial number of the MTP device.
* @param[in] path Path to the file on the MTP device.
* @param[out] len Number of bytes read from the device.
*
* @return A pointer to a newly allocated buffer containing
* the file data, or NULL if an error occured.
*/
unsigned char *
gfsec_get_file_from_mtp(const char *authority,
const char *path,
size_t *len)
{
LIBMTP_mtpdevice_t *device;
struct getfile_cb_data cb_data;
unsigned char *blob = NULL;
if ( (device = find_mtp_device(authority)) ) {
long file_id;
if ( (file_id = find_mtp_file(device, 0, path, len)) != -1 ) {
if ( (blob = malloc(*len)) ) {
cb_data.buffer = blob;
cb_data.written = 0;
cb_data.expected = *len;
if ( LIBMTP_Get_File_To_Handler(device, file_id,
getfile_cb, &cb_data, NULL, NULL) != 0 ) {
free(blob);
blob = NULL;
}
}
}
LIBMTP_Release_Device(device);
}
return blob;
}
#endif /* HAVE_LIBMTP */