LCOV - code coverage report
Current view: top level - util - sss_ssh.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 22 98 22.4 %
Date: 2016-06-29 Functions: 1 3 33.3 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jan Cholasta <jcholast@redhat.com>
       4             : 
       5             :     Copyright (C) 2012 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <arpa/inet.h>
      22             : 
      23             : #include "db/sysdb.h"
      24             : #include "util/util.h"
      25             : #include "util/crypto/sss_crypto.h"
      26             : #include "util/sss_ssh.h"
      27             : 
      28             : errno_t
      29           0 : sss_ssh_make_ent(TALLOC_CTX *mem_ctx,
      30             :                  struct ldb_message *msg,
      31             :                  struct sss_ssh_ent **result)
      32             : {
      33             :     TALLOC_CTX *tmp_ctx;
      34           0 :     struct sss_ssh_ent *res = NULL;
      35             :     errno_t ret;
      36             :     const char *name;
      37             :     struct ldb_message_element *el;
      38             :     unsigned int i;
      39             : 
      40           0 :     tmp_ctx = talloc_new(NULL);
      41           0 :     if (!tmp_ctx) {
      42           0 :         return ENOMEM;
      43             :     }
      44             : 
      45           0 :     name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
      46           0 :     if (!name) {
      47           0 :         ret = EINVAL;
      48           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Host is missing name attribute\n");
      49           0 :         goto done;
      50             :     }
      51             : 
      52           0 :     res = talloc_zero(tmp_ctx, struct sss_ssh_ent);
      53           0 :     if (!res) {
      54           0 :         ret = ENOMEM;
      55           0 :         goto done;
      56             :     }
      57             : 
      58           0 :     res->name = talloc_strdup(res, name);
      59           0 :     if (!res->name) {
      60           0 :         ret = ENOMEM;
      61           0 :         goto done;
      62             :     }
      63             : 
      64           0 :     el = ldb_msg_find_element(msg, SYSDB_SSH_PUBKEY);
      65           0 :     if (el) {
      66           0 :         res->num_pubkeys = el->num_values;
      67             : 
      68           0 :         res->pubkeys = talloc_array(res, struct sss_ssh_pubkey,
      69             :                                     res->num_pubkeys);
      70           0 :         if (!res->pubkeys) {
      71           0 :             ret = ENOMEM;
      72           0 :             goto done;
      73             :         }
      74             : 
      75           0 :         for (i = 0; i < el->num_values; i++) {
      76           0 :             res->pubkeys[i].data = sss_base64_decode(res->pubkeys,
      77           0 :                     (char *)el->values[i].data, &res->pubkeys[i].data_len);
      78           0 :             if (!res->pubkeys[i].data) {
      79           0 :                 ret = ENOMEM;
      80           0 :                 goto done;
      81             :             }
      82             :         }
      83             :     }
      84             : 
      85           0 :     el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS);
      86           0 :     if (el) {
      87           0 :         res->num_aliases = el->num_values;
      88             : 
      89           0 :         res->aliases = talloc_array(res, char *, res->num_aliases);
      90           0 :         if (!res->aliases) {
      91           0 :             ret = ENOMEM;
      92           0 :             goto done;
      93             :         }
      94             : 
      95           0 :         for (i = 0; i < el->num_values; i++) {
      96           0 :             res->aliases[i] = talloc_strdup(res->aliases,
      97           0 :                                             (char *)el->values[i].data);
      98           0 :             if (!res->aliases[i]) {
      99           0 :                 ret = ENOMEM;
     100           0 :                 goto done;
     101             :             }
     102             :         }
     103             :     }
     104             : 
     105           0 :     *result = talloc_steal(mem_ctx, res);
     106           0 :     ret = EOK;
     107             : 
     108             : done:
     109           0 :     talloc_free(tmp_ctx);
     110             : 
     111           0 :     return ret;
     112             : }
     113             : 
     114             : static errno_t
     115           0 : sss_ssh_get_pubkey_algorithm(TALLOC_CTX *mem_ctx,
     116             :                              struct sss_ssh_pubkey *pubkey,
     117             :                              char **result)
     118             : {
     119           0 :     size_t c = 0;
     120             :     uint32_t algo_len;
     121             :     char *algo;
     122             : 
     123           0 :     if (pubkey->data_len < 5) {
     124           0 :         return EINVAL;
     125             :     }
     126             : 
     127           0 :     SAFEALIGN_COPY_UINT32(&algo_len, pubkey->data, &c);
     128           0 :     algo_len = ntohl(algo_len);
     129           0 :     if (algo_len < 1 || algo_len > 64 || algo_len > pubkey->data_len - 4) {
     130             :         /* the maximum length of 64 is defined in RFC 4250 */
     131           0 :         return EINVAL;
     132             :     }
     133             : 
     134           0 :     algo = talloc_zero_array(mem_ctx, char, algo_len+1);
     135           0 :     if (!algo) {
     136           0 :         return ENOMEM;
     137             :     }
     138             : 
     139           0 :     memcpy(algo, pubkey->data+c, algo_len);
     140             : 
     141           0 :     *result = algo;
     142           0 :     return EOK;
     143             : }
     144             : 
     145             : errno_t
     146           6 : sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx,
     147             :                       struct sss_ssh_pubkey *pubkey,
     148             :                       char **result)
     149             : {
     150             :     TALLOC_CTX *tmp_ctx;
     151             :     errno_t ret;
     152             :     char *blob;
     153             :     char *algo;
     154           6 :     char *out = NULL;
     155             :     size_t i, len;
     156             : 
     157           6 :     tmp_ctx = talloc_new(NULL);
     158           6 :     if (!tmp_ctx) {
     159           0 :         return ENOMEM;
     160             :     }
     161             : 
     162           6 :     if (pubkey->data_len > 4 && memcmp(pubkey->data, "\0\0\0", 3) == 0) {
     163             :         /* All valid public key blobs start with 3 null bytes (see RFC 4253
     164             :          * section 6.6, RFC 4251 section 5 and RFC 4250 section 4.6)
     165             :          */
     166           0 :         blob = sss_base64_encode(tmp_ctx, pubkey->data, pubkey->data_len);
     167           0 :         if (!blob) {
     168           0 :             ret = ENOMEM;
     169           0 :             goto done;
     170             :         }
     171             : 
     172           0 :         ret = sss_ssh_get_pubkey_algorithm(tmp_ctx, pubkey, &algo);
     173           0 :         if (ret != EOK) {
     174           0 :             goto done;
     175             :         }
     176             : 
     177           0 :         out = talloc_asprintf(mem_ctx, "%s %s", algo, blob);
     178           0 :         if (!out) {
     179           0 :             ret = ENOMEM;
     180           0 :             goto done;
     181             :         }
     182             :     } else {
     183             :         /* Not a valid public key blob, so this must be a textual public key */
     184        2037 :         for (i = 0; i < pubkey->data_len; i++) {
     185        4069 :             if (pubkey->data[i] == '\0' ||
     186        4069 :                 (pubkey->data[i] == '\n' && i != pubkey->data_len - 1) ||
     187        2033 :                 pubkey->data[i] == '\r') {
     188           4 :                 ret = EINVAL;
     189           4 :                 goto done;
     190             :             }
     191             :         }
     192             : 
     193           2 :         len = pubkey->data_len;
     194           2 :         if (pubkey->data[len - 1] == '\n') {
     195           1 :             len--;
     196             :         }
     197             : 
     198           2 :         out = talloc_array(mem_ctx, char, len + 1);
     199           2 :         if (out == NULL) {
     200           0 :             ret = ENOMEM;
     201           0 :             goto done;
     202             :         }
     203             : 
     204           2 :         memcpy(out, pubkey->data, len);
     205           2 :         out[len] = '\0';
     206             :     }
     207             : 
     208           2 :     *result = out;
     209           2 :     ret = EOK;
     210             : 
     211             : done:
     212           6 :     talloc_free(tmp_ctx);
     213             : 
     214           6 :     return ret;
     215             : }

Generated by: LCOV version 1.10