1 /*
2 * string.c - ssh string functions
3 *
4 * This file is part of the SSH Library
5 *
6 * Copyright (c) 2003-2008 by Aris Adamantiadis
7 *
8 * The SSH Library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or (at your
11 * option) any later version.
12 *
13 * The SSH Library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the SSH Library; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 * MA 02111-1307, USA.
22 */
23
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #ifndef _WIN32
29 #include <arpa/inet.h>
30 #endif
31
32 #include "libssh/priv.h"
33 #include "libssh/string.h"
34
35 /**
36 * @defgroup libssh_string The SSH string functions
37 * @ingroup libssh
38 *
39 * @brief String manipulations used in libssh.
40 *
41 * @{
42 */
43
44 /**
45 * @brief Create a new SSH String object.
46 *
47 * @param[in] size The size of the string.
48 *
49 * @return The newly allocated string, NULL on error.
50 */
ssh_string_new(size_t size)51 struct ssh_string_struct *ssh_string_new(size_t size) {
52 struct ssh_string_struct *str = NULL;
53
54 str = malloc(sizeof(struct ssh_string_struct) + size);
55 if (str == NULL) {
56 return NULL;
57 }
58
59 str->size = htonl(size);
60 str->data[0] = 0;
61
62 return str;
63 }
64
65 /**
66 * @brief Fill a string with given data. The string should be big enough.
67 *
68 * @param s An allocated string to fill with data.
69 *
70 * @param data The data to fill the string with.
71 *
72 * @param len Size of data.
73 *
74 * @return 0 on success, < 0 on error.
75 */
ssh_string_fill(struct ssh_string_struct * s,const void * data,size_t len)76 int ssh_string_fill(struct ssh_string_struct *s, const void *data, size_t len) {
77 if ((s == NULL) || (data == NULL) ||
78 (len == 0) || (len > ssh_string_len(s))) {
79 return -1;
80 }
81
82 memcpy(s->data, data, len);
83
84 return 0;
85 }
86
87 /**
88 * @brief Create a ssh string using a C string
89 *
90 * @param[in] what The source 0-terminated C string.
91 *
92 * @return The newly allocated string, NULL on error with errno
93 * set.
94 *
95 * @note The nul byte is not copied nor counted in the ouput string.
96 */
ssh_string_from_char(const char * what)97 struct ssh_string_struct *ssh_string_from_char(const char *what) {
98 struct ssh_string_struct *ptr;
99 size_t len;
100
101 if(what == NULL) {
102 errno = EINVAL;
103 return NULL;
104 }
105
106 len = strlen(what);
107
108 ptr = ssh_string_new(len);
109 if (ptr == NULL) {
110 return NULL;
111 }
112
113 memcpy(ptr->data, what, len);
114
115 return ptr;
116 }
117
118 /**
119 * @brief Return the size of a SSH string.
120 *
121 * @param[in] s The the input SSH string.
122 *
123 * @return The size of the content of the string, 0 on error.
124 */
ssh_string_len(struct ssh_string_struct * s)125 size_t ssh_string_len(struct ssh_string_struct *s) {
126 if (s == NULL) {
127 return ntohl(0);
128 }
129
130 return ntohl(s->size);
131 }
132
133 /**
134 * @brief Get the the string as a C nul-terminated string.
135 *
136 * This is only available as long as the SSH string exists.
137 *
138 * @param[in] s The SSH string to get the C string from.
139 *
140 * @return The char pointer, NULL on error.
141 */
ssh_string_get_char(struct ssh_string_struct * s)142 const char *ssh_string_get_char(struct ssh_string_struct *s)
143 {
144 if (s == NULL) {
145 return NULL;
146 }
147 s->data[ssh_string_len(s)] = '\0';
148
149 return (const char *) s->data;
150 }
151
152 /**
153 * @brief Convert a SSH string to a C nul-terminated string.
154 *
155 * @param[in] s The SSH input string.
156 *
157 * @return An allocated string pointer, NULL on error with errno
158 * set.
159 *
160 * @note If the input SSH string contains zeroes, some parts of the output
161 * string may not be readable with regular libc functions.
162 */
ssh_string_to_char(struct ssh_string_struct * s)163 char *ssh_string_to_char(struct ssh_string_struct *s) {
164 size_t len;
165 char *new;
166 if (s == NULL || s->data == NULL)
167 return NULL;
168 len = ssh_string_len(s) + 1;
169 new = malloc(len);
170
171 if (new == NULL) {
172 return NULL;
173 }
174 memcpy(new, s->data, len - 1);
175 new[len - 1] = '\0';
176 return new;
177 }
178
179 /**
180 * @brief Deallocate a char string object.
181 *
182 * @param[in] s The string to delete.
183 */
ssh_string_free_char(char * s)184 void ssh_string_free_char(char *s) {
185 SAFE_FREE(s);
186 }
187
188 /**
189 * @brief Copy a string, return a newly allocated string. The caller has to
190 * free the string.
191 *
192 * @param[in] s String to copy.
193 *
194 * @return Newly allocated copy of the string, NULL on error.
195 */
ssh_string_copy(struct ssh_string_struct * s)196 struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) {
197 struct ssh_string_struct *new;
198
199 if (s == NULL || s->data == NULL) {
200 return NULL;
201 }
202
203 new = ssh_string_new(ssh_string_len(s));
204 if (new == NULL) {
205 return NULL;
206 }
207
208 memcpy(new->data, s->data, ssh_string_len(s));
209
210 return new;
211 }
212
213 /**
214 * @brief Destroy the data in a string so it couldn't appear in a core dump.
215 *
216 * @param[in] s The string to burn.
217 */
ssh_string_burn(struct ssh_string_struct * s)218 void ssh_string_burn(struct ssh_string_struct *s) {
219 if (s == NULL) {
220 return;
221 }
222 memset(s->data, 'X', ssh_string_len(s));
223 }
224
225 /**
226 * @brief Get the payload of the string.
227 *
228 * @param s The string to get the data from.
229 *
230 * @return Return the data of the string or NULL on error.
231 */
ssh_string_data(struct ssh_string_struct * s)232 void *ssh_string_data(struct ssh_string_struct *s) {
233 if (s == NULL) {
234 return NULL;
235 }
236
237 return s->data;
238 }
239
240 /**
241 * @brief Deallocate a SSH string object.
242 *
243 * \param[in] s The SSH string to delete.
244 */
ssh_string_free(struct ssh_string_struct * s)245 void ssh_string_free(struct ssh_string_struct *s) {
246 SAFE_FREE(s);
247 }
248
249 /** @} */
250
251 /* vim: set ts=4 sw=4 et cindent: */
252