【问题标题】:Passing a C character string to linux command line将 C 字符串传递给 linux 命令行
【发布时间】:2011-12-05 08:25:15
【问题描述】:

我的函数中有一个字符串,定义为 ..

 char *key="anyvalue";

现在我使用 linux 命令作为 ...

 $openssl dgst -md5 -hmac "anyvalue" file.txt

现在的问题是我需要通过 C 函数执行以下任务..

这里是代码...

  void func (char *key) {

     char *key_new=key;

     system("openssl -dgst md5 -hmac <got stuck here> file.txt");

  }

如何将键值传递给标记的部分??

我在 php.ini 中非常简单地做到了这一点。 ...

   $key="somevalue"

   exec("openssl -dgst md5 -hmac $key file.txt");

C 中有类似的东西吗???

如果没有那么请告诉我任何其他可能的方式???

限制:

密钥必须通过函数传递。

我不能把它当作 C 命令行参数。

编辑:

我试过这个......但首先我想提一下,它是一个大项目中的一个小文件,并且警告被视为错误......所以我也需要照顾它们

这就是我所做的 -

    char *sstring=NULL;
    sprintf(sstring, "openssl dgst -md5 -hmac \"%s\"
    -out data3.md5 data3.txt",(char *)key);
    system(sstring);

如果我不初始化,那么这里会出现警告..

    gcc -o hmacmd5.so -I.. -fPIC -fsigned-char -pipe -Wall 
    -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wnested-externs
    -Winline -Werror -g -Wcast-align -DSENDIP_LIBS=\"/usr/local/lib/sendip\"
    -shared hmacmd5.c ../libsendipaux.a ../libsendipaux.a

    cc1: warnings being treated as errors
    hmacmd5.c: In function ‘xoricv’:
    hmacmd5.c:271:9: error: ‘sstring’ is used uninitialized in this function
    make: *** [hmacmd5.so] Error 1

【问题讨论】:

  • 如果在程序输入中提供了key 的值,您可能会面临安全漏洞。考虑一下:如果 keyabcdef$(rm -f /etc/passwd)ghijkl 怎么办?

标签: c pointers exec command-line-arguments


【解决方案1】:

如果你想在 C 字符串中写字符 ",你可以写成 \"

所以,你写

system("openssl dgst -md5 -hmac \"key\" file.txt");

如果你的key不是常量,你应该使用snprintf

类似这样的:

char buffer[/*enough size*/];
snprintf(buffer, /*the size*/, "openssl dgst -md5 -hmac \"%s\" file.txt", key);

之后

system(buffer);

【讨论】:

  • 我认为您错过了问题的重点。他是如何将key 的值放入字符串中的,更不用说引用了?
  • string is variable ....每次我调用函数时都会传递一个新的键值,我认为你建议的是一个固定的键值“key”
  • @UditGupta 我编辑了这篇文章。但是,您仍然需要记住在字符串中使用 \"
  • 但是我将如何执行系统命令呢????我需要提供整个字符串作为system 命令的输入,如果我使用char *str 之类的东西代替整个字符串,那么我如何在其中添加这个键??
【解决方案2】:

我想你在找sprintf:

int sprintf(char *STR, const char *FORMAT, ...);

在您的情况下,您可以按如下方式使用它:

sprintf(some_allocated_output_string, "openssl -dgst md5 -hmac %s", key);
system(some_allocated_output_string);

编辑:

看到你尝试的代码后,我可以看到我没有给你一个完整的答案。

这里有两个选择(假设下面的STRING_SIZE#defined 的大小,比如300 之类的):

1) 使用预先分配的缓冲区:

char sstring[STRING_SIZE];
sprintf(sstring, "openssl -dgst md5 -hmac \"%s\" -out data3.md5 data3.txt",(char *)key);
system(sstring);

2) 使用 malloc/free:

#include <stdlib.h>
//blah blah blah
char *sstring=NULL;
//blah blah blah
sstring = malloc(STRING_SIZE);
sprintf(sstring, "openssl -dgst md5 -hmac \"%s\" -out data3.md5 data3.txt",(char *)key);
system(sstring);
free(sstring);

我建议第一种方法。除此之外,如果您的编译器支持,我强烈建议您注意使用@pmg 对snprintf 的建议。这看起来像这样:

char sstring[STRING_SIZE];
int result = 0;
result = snprintf(sstring, STRING_SIZE, "openssl -dgst md5 -hmac \"%s\" -out data3.md5 data3.txt",(char *)key);
// Perform a check on result here, in case you ran out of space.
// If result > STRING_SIZE, you need to try a larger buffer.
system(sstring);

【讨论】:

  • +1;更好的是,如果 OP 有 C99 编译器,则为 snprintf
  • 强烈同意。越安全越好,尤其是在缓冲区方面。 sprintf 刚刚接触到...旧习惯和所有这些;^)
  • @UditGupta 你能把你试过的代码贴出来,我看看能不能把你引向正确的方向?
【解决方案3】:

另一种选择:

void func(char * key)
{
    char cmd[255] = "openssl dgst -md5 -hmac ";
    assert(sizeof cmd > strlen(cmd) + strlen(key));
    strcpy(cmd, key);
    system(cmd);
}

【讨论】:

    【解决方案4】:

    怎么样:

     void func (char *key) {
    
         char *cmd = "openssl -dgst md5 -hmac ";
         char *fullmsg = _malloc( strlen(key) + strlen(cmd) );
         if (fullmsg != NULL) {
           sprintf_s( fullmsg, sizeof(fullmsg), "%s%s", cmd, key );
           system( fullmsg );
           free( fullmsg );
         } // else out of memory
    
      }
    

    【讨论】:

    • 啊,这可能只在微软的 C 编译器中可用。然后使用 sprintf() 代替,只要确保你没有超出缓冲区。
    【解决方案5】:

    您应该学习使用 openssl API 而不是调用命令行。

    否则,您需要使用system,而不是 fork。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    相关资源
    最近更新 更多